diff --git a/campus/model/timetable.dbml b/campus/model/timetable.dbml deleted file mode 100644 index 28241db7..00000000 --- a/campus/model/timetable.dbml +++ /dev/null @@ -1,103 +0,0 @@ -// For all, id is a CampusID with no relation to raw XML ID. - -// An allocation refers to a new set of classes, people and class timings -// imported with a new timetable. -// It refers to one of these: -// https://github.com/nyjc-computing/nyxchange-timetable-v2/blob/data-schema/tt_file/tt_xml_docs.md -// This year's timetable and last year's timetable are two seperate allocations. -// The data for an allocation is stored in some .xml file, named `filename` - -/* Sections that stay constant or only have additions. */ -/* They will be relevant every for every allocation. */ - -// Describes a day in a repeating timetable. -// Assumption: This will stay constant across all timetables. -Table WeekDay { - id varchar [primary key] - label varchar // (cosmetic purposes: 'Mon A', 'Tue A', ... 'Mon B', 'Tue B', ..., 'Sat', 'Sun') - index integer [unique] // index 0 is earliest (eg. Mon A), followed by Tues A, etc. -} - -// Timeslot which repeats across all `WeekDay`s -// Assumption: This will stay constant across all timetables. -Table TimeSlot { - id varchar [primary key] - label varchar // (primarily cosmetic: '0730', '0800', ...) - start_time varchar [unique] // ISO8601 - end_time varchar [unique] // ISO8601 - index integer [unique] // index 0 is slot (eg. 0730), followed by 0800, etc. -} - -// Describes a single venue -// We have a set of venues that remain across years, except additions. -// Cannot refer to a group (eg. "All science labs") -Table Venue { - id varchar [primary key] - label varchar // (mutable, e.g. '03-39', 'i-Space 1', ..., follow XML when possible) -} - -// Imagine each venue has its own timetable. -// This is one timeslot on such a timetable, representing an intersection of -// Venue and TimeSlot -// We use it for clean and convenient timetable coordinates, as -// we usually reason about an intersection of venue and time anyway -// Must be automatically generated for each Venue for all WeekDay, TimeSlot. -Table VenueTimeSlot { - id varchar [primary key] - weekday_id varchar - timeslot_id varchar - venue_id varchar - indexes { - (weekday_id, timeslot_id, venue_id) [unique] - } -} -Ref: VenueTimeSlot.weekday_id > WeekDay.id -Ref: VenueTimeSlot.timeslot_id > TimeSlot.id -Ref: VenueTimeSlot.venue_id > Venue.id - -/* Sections that are only relevant to a specific allocation. */ -/* New entries are created for each allocation. */ -/* Which allocation the entry is relevant to is . */ - -// This represents a specific lesson taught to a class. -// Eg. Chem, taught to 2510. (eg. stored as '2510-CM') -// These are stored as an inconsistently formatted string, imported -// directly from the XML. -Table LessonGroup { - id varchar [primary key] - filename varchar // Allocation xml filename which this group is relevant to - label varchar -} - -// Represents a single member of a LessonGroup. -// For example, 2510-Math will have: -// - Rosaline Tan -// - All the students -// Where each individual is one LessonGroupMember. -// 2510-Chem will have its own set of entries, even if the participant is duplicated. -Table LessonGroupMember { - id varchar [primary key] - filename varchar - lessongroup_id varchar - // XML id (aka TTCode or teacher_id). We have a unique mapping of these IDs - // to nyjc email etc., for each allocation. - ade_participant varchar - indexes { - (lessongroup_id, ade_participant, filename) [unique] - } -} -Ref: LessonGroup.id < LessonGroupMember.lessongroup_id - -// A timetable represents a lesson for a LessonGroup -// at some VenueTimeSlot -Table Timetable { - id varchar [primary key] - filename varchar - lessongroup_id varchar - venuetimeslot_id varchar - indexes { - (venuetimeslot_id, lessongroup_id, filename) [unique] - } -} -Ref: Timetable.lessongroup_id > LessonGroup.id -Ref: Timetable.venuetimeslot_id > VenueTimeSlot.id \ No newline at end of file diff --git a/campus/model/timetable.py b/campus/model/timetable.py index 0f37cff4..5fd8331e 100644 --- a/campus/model/timetable.py +++ b/campus/model/timetable.py @@ -9,17 +9,21 @@ - Students and teachers involved in said lessons - Venues -!! The schema is documented in DETAIL by the `timetable.dbml` file. -!! Commenting both files would mean duplicate documentation. -!! Please visualise it [here](https://dbml-editor.alswl.com/)!!!! -!! The tool is also able to export the schema as SQL to create the respective tables. +For all models, id is a CampusID with no relation to raw XML ID. + +An allocation refers to a new set of classes, people and class timings + imported with a new timetable. +It refers to one of these: + https://github.com/nyjc-computing/nyxchange-timetable-v2/blob/data-schema/tt_file/tt_xml_docs.md +This year's timetable and last year's timetable are two seperate allocations. +The data for an allocation is stored in some .xml file, named `filename` + +TODO: Update doc link after migration """ -from typing import ClassVar from dataclasses import dataclass, field from campus.common import schema -from campus.common.schema.openapi import String, Integer, Boolean, DateTime from campus.common.utils import uid from .base import Model @@ -30,40 +34,59 @@ "constraints": [constraints.UNIQUE], }) +## Sections that stay constant or only have additions. ## +## They will be relevant every for every allocation. ## @dataclass(eq=False, kw_only=True) class WeekDay(Model): """ Describes a day in a repeating timetable. + Assumption: This will stay constant across all allocations. + + Fields: + label (String): (cosmetic purposes: 'Mon A', 'Tue A', ... 'Mon B', 'Tue B', ..., 'Sat', 'Sun') + index (Integer): index 0 is earliest (eg. Mon A), followed by Tues A, etc. """ id: schema.CampusID = unique_field - label: String - index: Integer + label: schema.String + index: schema.Integer @dataclass(eq=False, kw_only=True) class TimeSlot(Model): """ Timeslot which repeats across all `WeekDay`s + Assumption: This will stay constant across all allocations. + + Fields: + label (String): (primarily cosmetic: '0730', '0800', ...) + start_time (DateTime): ISO8601 + end_time (DateTime): ISO8601 + index (Integer): index 0 is earliest slot (eg. 0730), followed by 0800 at idx 1, etc. """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - label: String - start_time: DateTime = unique_field - end_time: DateTime = unique_field - index: Integer = unique_field + label: schema.String + start_time: schema.DateTime = unique_field # ISO8601 + end_time: schema.DateTime = unique_field # ISO8601 + index: schema.Integer = unique_field @dataclass(eq=False, kw_only=True) class Venue(Model): """ - Describes a single venue + Describes a single venue. + We have a set of venues that remain across years, except additions. + Cannot refer to a group (eg. "All science labs"). + + Fields: + label (String): (e.g. '03-39', 'i-Space 1', ..., follow XML when possible) """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - label: String + label: schema.String @dataclass(eq=False, kw_only=True) @@ -72,27 +95,44 @@ class VenueTimeSlot(Model): Imagine each venue has its own timetable. This is one timeslot on such a timetable, representing an intersection of Venue and TimeSlot + We use it for clean and convenient "timetable coordinates", as + we usually reason about an intersection of venue and time anyway + Must be automatically generated for each Venue for all WeekDay, TimeSlot. + + Fields: + weekday_id (CampusID): FK referencing a WeekDay.id + timeslot_id (CampusID): FK referencing a TimeSlot.id + venue_id (CampusID): FK referencing a Venue.id """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - weekday_id: schema.CampusID # FK -> weekday_id + weekday_id: schema.CampusID timeslot_id: schema.CampusID venue_id: schema.CampusID __constraints__ = constraints.Unique("weekday_id", "timeslot_id", "venue_id") +## Sections that are only relevant to a specific allocation. ## +## New entries are created for each allocation. ## +## Which allocation the entry is relevant to is . ## @dataclass(eq=False, kw_only=True) class LessonGroup(Model): """ - This represents a specific lesson taught to a class. + This represents a specific subject taught to a class. Eg. Chem, taught to 2510. (eg. stored as '2510-CM') + These are labelled as an inconsistently formatted string, imported + directly from the XML. It seems we cannot seperate class and subject. + + Fields: + filename (String): Allocation xml filename which this entry is relevant to + label (String): Label brought over from xml, like 2527-COM """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - filename: String - label: String + filename: schema.String + label: schema.String @dataclass(eq=False, kw_only=True) @@ -104,26 +144,37 @@ class LessonGroupMember(Model): - All the students Where each individual is one LessonGroupMember. 2510-Chem will have its own set of entries, even if the participant is duplicated. + + Fields: + filename (String): Allocation xml filename which this entry is relevant to + lessongroup_id (CampusID): FK referencing a LessonGroup.id + ade_participant (String): XML id (aka TTCode or teacher_id). We have a unique mapping of these IDs + to nyjc email etc., for each allocation. """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - filename: String - lessongroup_id: String - ade_participant: String + filename: schema.String + lessongroup_id: schema.CampusID + ade_participant: schema.String __constraints__ = constraints.Unique("lessongroup_id", "ade_participant", "filename") @dataclass(eq=False, kw_only=True) class Timetable(Model): """ - A timetable represents a lesson for a LessonGroup - at some VenueTimeSlot + A timetable represents a single lesson for a LessonGroup + at some VenueTimeSlot. + + Fields: + filename (String): Allocation xml filename which this entry is relevant to + lessongroup_id (CampusID): FK referencing a LessonGroup.id + venuetimeslot_id (CampusID): FK referencing a VenueTimeSlot.id """ id: schema.CampusID = field(default_factory=( lambda: uid.generate_category_uid("timetable", length=8) )) - filename: String - lessongroup_id: String - venuetimeslot_id: String + filename: schema.String + lessongroup_id: schema.CampusID + venuetimeslot_id: schema.CampusID __constraints__ = constraints.Unique("lessongroup_id", "venuetimeslot_id", "filename")