StudyFeatures  -- multiple entries possible for students pursuing several degrees at once, usually created upon LDAP login
    user          UserId
    degree        StudyDegreeId   -- Abschluss, i.e. Master, Bachelor, etc.
    field         StudyTermsId    -- Fach, i.e. Informatics, Philosophy, etc.
    superField    StudyTermsId Maybe
    type          StudyFieldType  -- Major or minor, i.e. Haupt-/Nebenfach
    semester      Int
    firstObserved UTCTime Maybe
    lastObserved  UTCTime default=now() -- last update from LDAP
    valid         Bool default=true
    relevanceCached UUID Maybe
    UniqueStudyFeatures user degree field type semester
    deriving Eq Show Generic
    -- UniqueUserSubject ubuser degree field -- There exists a counterexample

RelevantStudyFeatures
    term          TermId
    studyFeatures StudyFeaturesId
    UniqueRelevantStudyFeatures term studyFeatures
    deriving Generic

StudyDegree   -- Studienabschluss
    key           Int            -- LMU-internal key
    shorthand     Text Maybe     -- admin determined shorthand
    name          Text Maybe     -- description given by LDAP
    Primary key                  -- column key is used as actual DB row key
                                 -- newtype Key StudyDegree = StudyDegreeKey' { unStudyDegreeKey :: Int }
    deriving Eq Show Generic
StudyTerms    -- Studiengang
    key           Int            -- standardised key
    shorthand     Text Maybe     -- admin determined shorthand
    name          Text Maybe     -- description given by LDAP
    defaultDegree StudyDegreeId Maybe
    defaultType   StudyFieldType Maybe
    Primary key                  -- column key is used as actual DB row key
                                 -- newtype Key StudyTerms = StudyTermsKey' { unStudyTermsKey :: Int }
    deriving Eq Ord Show Generic
StudySubTerms
    child         StudyTermsId
    parent        StudyTermsId
    UniqueStudySubTerms child parent
    deriving Generic
StudyTermNameCandidate    -- No one at LMU is willing and able to tell us the meaning of the keys for StudyDegrees and StudyTerms.
    -- Each LDAP login provides an unordered set of keys and an unordered set of plain text description with an unknown 1-1 correspondence.
    -- This table helps us to infer which key belongs to which plain text by recording possible combinations at login.
    -- If a login provides n keys and n plan texts, then n^2 rows with the same incidence are created, storing all combinations
    incidence     TermCandidateIncidence -- random id, generated once per login to associate matching pairs
    key           Int      -- a possible key for the studyTermName or studySubTermName
    name          Text     -- studyTermName as plain text from LDAP
    deriving Show Eq Ord Generic
StudySubTermParentCandidate
    incidence     TermCandidateIncidence
    key           Int
    parent        Int
    deriving Show Eq Ord Generic
StudyTermStandaloneCandidate
    incidence     TermCandidateIncidence
    key           Int
    deriving Show Eq Ord Generic

