Allocation -- attributes with prefix staff- affect lecturers only, but are invisble to students
    term                TermId
    school              SchoolId        -- school that manages this central allocation, not necessarily school of courses
    shorthand           AllocationShorthand -- practical shorthand
    name                AllocationName
    legacyShorthands    [AllocationShorthand] default='[]' -- just for association to previous allocations
    description         StoredMarkup Maybe      -- description for prospective students
    staffDescription    StoredMarkup Maybe      -- description seen by prospective lecturers only
    staffRegisterFrom   UTCTime Maybe   -- lectureres may register courses
    staffRegisterTo     UTCTime Maybe   -- course registration stops
    -- staffDeregisterUntil not needed: staff may make arbitrary changes until staffRegisterTo, always frozen afterwards
    staffAllocationFrom UTCTime Maybe   -- lecturers may rate applicants from this day onwwards or prohibited
    staffAllocationTo   UTCTime Maybe   --
    -- Student register for this allocation
    -- canRegisterNow = maybe False (<= currentTime) registerFrom && maybe True (>= currentTime) registerTo
    registerFrom        UTCTime Maybe   -- student applications allowed from a given day onwwards or prohibited
    registerTo          UTCTime Maybe   -- student applications may be prohibited from a given date onwards
    -- deregisterUntil not needed: students may withdraw applicants until registerTo, but never after. Also see overrideDeregister
    -- overrides
    registerByStaffFrom UTCTime Maybe   -- lecturers may directly enrol/disenrol students after a given date or prohibited
    registerByStaffTo   UTCTime Maybe
    registerByCourse    UTCTime Maybe   -- course registration dates are ignored until this day has passed or always prohibited
    overrideDeregister  UTCTime Maybe   -- deregister prohibited after this time or always allowed (defaulting to course settings)
    -- overrideVisible not needed, since courses are always visible
    matchingSeed        ByteString default='\x'::bytea
    TermSchoolAllocationShort  term school shorthand    -- shorthand must be unique within school and semester
    TermSchoolAllocationName   term school name         -- name must be unique within school and semester
    deriving Show Eq Ord Generic

AllocationMatching
    allocation          AllocationId
    fingerprint         AllocationFingerprint
    time                UTCTime
    log                 FileContentReference
    deriving Generic

AllocationCourse
    allocation          AllocationId
    course              CourseId
    minCapacity         Int          -- if the course would get assigned fewer than this many applicants, restart the assignment process without the course
    acceptSubstitutes   UTCTime Maybe
    overrideSumCapacity Int Maybe    -- mark course as outlier (ridiculously large capacity) and use this capacity instead for computing overall capacity of allocation
    UniqueAllocationCourse course
    deriving Generic

AllocationUser
    allocation          AllocationId
    user                UserId
    totalCourses        Word64           -- number of total allocated courses for this user must be <= than this number
    priority            AllocationPriority Maybe
    UniqueAllocationUser allocation user
    deriving Eq Ord Show Generic

AllocationDeregister -- self-inflicted user-deregistrations from an allocated course
    user                UserId
    course              CourseId Maybe OnDeleteSetNull OnUpdateCascade
    time                UTCTime
    reason              Text Maybe -- if this deregistration was done by proxy (e.g. the lecturer pressed the button)
    deriving Eq Ord Show Generic

AllocationNotificationSetting
    user                UserId
    allocation          AllocationId
    isOptOut            Bool
    UniqueAllocationNotificationSetting user allocation
    deriving Generic