chore(lms): add skeleton for csv decoding of lms result

This commit is contained in:
Steffen Jost 2022-02-18 14:33:00 +01:00
parent 87a94a5517
commit e821b416f0
3 changed files with 33 additions and 7 deletions

View File

@ -6,6 +6,7 @@ Qualification
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 -- automatically schedule e-refresher within this number of month/days before expiry
elearningStart Bool -- automatically schedule e-refresher
-- 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!
@ -16,12 +17,17 @@ Qualification
-- 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?
-- A: Der Inhaber per Email informieren!
-- A: Es kann gleich eine LMS Pin generiert und verschickt werden!
-- - Aufteilung Qualification "R" in zwei Teile: "R e-learning" und "R praxis" okay?
-- Fragen an Know-How:
-- - 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)
-- - Anzahl Fehlversuche: wird pro Durchfallen ein Failed gemeldet oder nur einmal?
QualificationPrecondition
qualification QualificationId -- AND: not unique, ie. qualification can have multiple required preconditions
@ -43,6 +49,8 @@ QualificationUser
validUntil UTCTime
lastRefresh UTCTime -- lastRefresh > validUntil possible, if Qualification^elearningOnly == False
firstHeld UTCTime -- first time the qualification was earned, should never change
-- temporärer Entzug vorsehen
-- Begründungsfeld vorsehen
UniqueQualificationUser qualification user
deriving Generic
@ -86,14 +94,14 @@ LmsUser
pin Text
resetPin Bool default=false -- should pin be reset?
success Bool Maybe -- open, success or failure; isJust indicates user will be deleted from LMS
-- success LmsStatus --this would also encode Day information?!
-- success LmsStatus -- 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 stores LMS upload for later processing only
LmsUserlist
qualification QualificationId OnDeleteCascade OnUpdateCascade
ident LmsIdent
@ -101,7 +109,7 @@ LmsUserlist
timestamp UTCTime default=now()
deriving Generic
-- LmsUserlist stores LMS upload ofr later processing only
-- LmsResult stores LMS upload for later processing only
LmsResult
qualification QualificationId OnDeleteCascade OnUpdateCascade
ident LmsIdent
@ -113,7 +121,7 @@ LmsResult
LmsAudit
qualification QualificationId
ident LmsIdent
notificationType LmsStatus
notificationType LmsStatus -- LmsOpen | LmsBlocked | LmsSuccess Day
received UTCTime -- timestamp from LmsUserlist/LmsResult
processed UTCTime default=now()
deriving Generic

View File

@ -142,7 +142,25 @@ mkResultTable qid = do
dbtIdent :: Text
dbtIdent = "lms-userlist"
dbtCsvEncode = noCsvEncode
dbtCsvDecode = Nothing -- TODO !!! continue here !!! CSV Import is the purpose of this page! Just save to DB, create Job to deal with it later!
dbtCsvDecode = Nothing {-
dbtCsvDecode = Just DBTCsvDecode -- Just save to DB; Job will process data later
{ dbtCsvRowKey = const $ return Nothing -- always generate a fres key, or should we use ident?
, dbtCsvComputeActions = \case
DBCsvDiffMissing{}
-> return () -- no deletion
DBCsvDiffExisting{}
-> return () -- no deletion
DBCsvDiffNew{dbCsvNewKey, dbCsvNew}
-> _insert
, dbtCsvClassifyAction = const () -- there is only one action: insert into table
, dbtCsvCoarsenActionClass = const () -- there is only one action: insert into table
, dbtCsvValidateActions = return () -- no validation, since this is an automatic upload, i.e. no user to review error
, dbtCsvExecuteActions = _savetodb
, dbtCsvRenderKey = _renderKey -- what is the purpose?
, dbtCsvRenderActionClass = _renderActioCalss -- what is the purpose?
, dbtCsvRenderException = _renderException
}
-}
dbtExtraReps = []
resultDBTableValidator = def

View File

@ -1017,7 +1017,7 @@ mapMM_ f mxs = Fold.mapM_ f =<< mxs
forMM_ :: (Foldable t, Monad m) => m (t a) -> (a -> m ()) -> m ()
forMM_ = flip mapMM_
-- is this a good idea? can we generalise this pattern?
-- | Monadic bind that also returns the intermediate value. This common pattern avoids the duplicated local identifiers required in the equivalent do-notation.
bind2 :: Monad m => m a -> (a -> m b) -> m (a, b)
bind2 ma ma2b = do
a <- ma