diff --git a/models/lms.model b/models/lms.model index d0e496bbc..d332be251 100644 --- a/models/lms.model +++ b/models/lms.model @@ -3,52 +3,99 @@ Qualification shorthand (CI Text) name (CI Text) description StoredMarkup Maybe -- user-defined large Html, ought to contain full description - validDuration Word Maybe -- qualification is valid for this number of months + validDuration Word Maybe -- qualification is valid for this number of months or indefinitely auditDuration Word Maybe -- number of month to keep audit log - refreshWithin CalendarDiffDays Maybe -- refresher is scheduled within this number of month before expiry - elearningOnly Bool -- successful E-learing automatically increases validity - -- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page - -- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead + refreshWithin CalendarDiffDays Maybe -- automatically schedule e-refresher within this number of month/days before expiry + -- elearningOnly Bool -- successful E-learing automatically increases validity. NO! + -- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page NO! + -- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead NO! UniqueSchoolShort school shorthand -- must be unique per school and shorthand UniqueSchoolName school name -- must be unique per school and name deriving Generic +-- TODOs: +-- - Enstehen Kosten, wenn Teilnehmer für KnowHow eingereiht werden, aber nicht am Kurs teilnehmen? +-- Falls ja, so sollte bei automatischem refresher vorher der Kunde durch FRADrive befragt werden?! +-- - Aufteilung Qualification "R" in zwei Teile: "R e-learning" und "R exam" okay? +-- - Bedeutung LMS Übermittlung interner Mitarbeiter? +-- - LmsUser shall submit DELTA only: Beware, GET Request will always return the same; until POST Request was processed! +-- - Success/Failure: is an explicit LMS-delete still necessary? +-- - User: pin reset = 1 to existing pin problematic? Resubmission of existing users with pin causes which problems? +-- - ident unique for all qualifications F/R or duplicated? (F/R refreshers might be simultaneous) + +QualificationPrecondition + qualification QualificationId -- AND: not unique, ie. qualification can have multiple required preconditions + required [QualificationId] -- OR : alternatives, any one will suffice + continuous Bool -- expiring precondition removes qualification + deriving Generic + +-- TODO: connect Qualification with Exams! + QualificationEdit user User time UTCTime qualification QualificationId OnDeleteCascade OnUpdateCascade deriving Generic --- TODO: connect Qualification with Exams! - QualificationUser user User - qualification QualificationId + qualification QualificationId OnDeleteCascade OnUpdateCascade validUntil UTCTime lastRefresh UTCTime -- lastRefresh > validUntil possible, if Qualification^elearningOnly == False firstHeld UTCTime -- first time the qualification was earned, should never change UniqueQualificationUser qualification user deriving Generic + -- LMS Interface Tables, need regular processing by background jobs, per QualificationId: + -- + -- 1. Daily Job: Add to LmsUser daily all qualification holders with + -- 0 <= QualificationUserValidUntil - now < QualificationRefreshWithin (time to schedule refresher) + -- /\ now - max(LmsUserStarted) > QualificationRefreshWithin (not already enlisted; Problem: QualificationELearningOnly!) + -- generate fresh ident and pin. (Bools?) + -- + -- 2. REST GET User.csv: + -- - where LmsUserReceived == Nothing \/ (LmsUserResetPin /\ LmsUserEnded == Nothing) + -- - delete-flag: isJust LmsUserSuccess + -- Note: REST means that LmsUserResetPin and LmsUserDelete remain unchanged by this GET request! + -- + -- 3. REST POST Userlist.csv: + -- -- save as is to LmsUserlist + -- -- change LmsUserEnded from Nothing to Just now, if not included in received list + -- + -- 4. REST POST Ergebnisse.csv: just save as is to LmsResult + -- + -- 5. Daily Job LmsUserlist: -- Note: containment needs at-once processing + -- - For all LmsUser: + -- + if contained, set LmsUserReceived to Just now() + -- + otherwise, set LmsUserEnded to Just now() + -- - if LmsUserlistFailed: + -- + set LmsUserSuccess to Just False + -- + set LmsUserDelete to True + -- - move row to LmsAudit + -- + -- 6. Daily Job LmsResult: + -- - set LmsUserReceived to Just now() + -- - set LmsUserSuccess to Just True + -- - move row to LmsAudit --- LMS Interface Tables, need regular processing by background jobs LmsUser - qualification QualificationId + qualification QualificationId OnDeleteCascade OnUpdateCascade user UserId ident LmsIdent pin Text - resetPin Bool -- should the pin be reset? - delete Bool -- should the ident be deleted? TODO: do we need this? - started UTCTime Maybe - submitted UTCTime Maybe -- ident was sent to LMS (should happen only once) - ended UTCTime Maybe -- ident was deleted in LMS + resetPin Bool default=false -- should pin be reset? + success Bool Maybe -- open, success or failure; isJust indicates user will be deleted from LMS + -- success LmsNotification --this would also encode Day information?! + started UTCTime default=now() + received UTCTime Maybe -- last acknowledgement by LMS + ended UTCTime Maybe -- ident was deleted from LMS UniqueLmsUser qualification ident deriving Generic -- LmsUserlist stores LMS upload ofr later processing only LmsUserlist - qualification QualificationId + qualification QualificationId OnDeleteCascade OnUpdateCascade ident LmsIdent failed Bool timestamp UTCTime default=now() @@ -56,7 +103,7 @@ LmsUserlist -- LmsUserlist stores LMS upload ofr later processing only LmsResult - qualification QualificationId + qualification QualificationId OnDeleteCascade OnUpdateCascade ident LmsIdent success Day timestamp UTCTime default=now() @@ -66,7 +113,7 @@ LmsResult LmsAudit qualification QualificationId ident LmsIdent - notificationType LmsNotification - received UTCTime + notificationType LmsNotification + received UTCTime -- timestamp from LmsUserlist/LmsResult processed UTCTime default=now() deriving Generic diff --git a/src/Model/Types/Lms.hs b/src/Model/Types/Lms.hs index ddb9fa894..48122de79 100644 --- a/src/Model/Types/Lms.hs +++ b/src/Model/Types/Lms.hs @@ -18,7 +18,8 @@ newtype LmsIdent = LmsIdent { getLmsIdent :: Text } makeLenses_ ''LmsIdent -data LmsNotification = LmsAlive | LmsBlocked | LmsSuccesss Day +-- TODO: is this a good idea? Maybe just an ordinary Enum and a separate Day Column in the DB would be better, especially since LmsBlocked should really also encode a Day +data LmsNotification = LmsOpen | LmsBlocked | LmsSuccess Day deriving (Eq, Ord, Read, Show, Generic, Typeable, NFData) deriveJSON defaultOptions