"""DB-driven constraint rules as Timefold problem facts. Each tt_constraint_* table from school-service maps to one dataclass here. Rows loaded at solve time are passed in via Timetable.* fact collections (see domain.py for wiring) and queried by the constraint provider. Only the rule types actually wired into constraints.py are defined for now. Adding a new one is two steps: define the dataclass, add it to Timetable's problem-fact properties, then implement a constraint that joins it. """ from dataclasses import dataclass @dataclass(frozen=True) class TeacherUnavailableDayRule: teacher_id: str day_of_week: int is_hard: bool weight: int @dataclass(frozen=True) class TeacherUnavailableWindowRule: teacher_id: str day_of_week: int start_time: str # HH:MM end_time: str # HH:MM is_hard: bool weight: int @dataclass(frozen=True) class TeacherExcludedRoomRule: teacher_id: str room_id: str is_hard: bool weight: int @dataclass(frozen=True) class RoomUnavailableRule: room_id: str day_of_week: int period_index: int is_hard: bool weight: int @dataclass(frozen=True) class SubjectPreferredPeriodRule: subject_id: str period_from: int period_to: int is_hard: bool weight: int @dataclass(frozen=True) class RoomRequiresTypeRule: subject_id: str room_type: str is_hard: bool weight: int