Add timetable scheduler Phases 1 + 2 to school-service

Phase 1 — Stammdaten (7 tables):
  tt_class, tt_period, tt_room, tt_subject, tt_teacher,
  tt_curriculum, tt_assignment with CRUD endpoints.

Phase 2 — Constraints (15 typed tables):
  Teacher (6): unavailable_day, unavailable_window, max_hours_day,
    max_hours_week, excluded_subject, excluded_room
  Subject (5): min_day_gap, max_consecutive, contiguous_when_repeated,
    preferred_period, double_lesson
  Class (2): max_hours_day, no_gaps
  Room (2): requires_type, unavailable

Each constraint row carries is_hard / weight / active / note /
created_by_user_id; ownership enforced via WHERE EXISTS against the
parent tt_teacher/tt_class/tt_subject/tt_room row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-21 22:12:23 +02:00
parent a1488b2fec
commit e958f88a2d
19 changed files with 3276 additions and 0 deletions
+95
View File
@@ -123,6 +123,101 @@ func main() {
api.PUT("/certificates/detail/:id/finalize", handler.FinalizeCertificate)
api.GET("/certificates/detail/:id/pdf", handler.GetCertificatePDF)
api.DELETE("/certificates/detail/:id", handler.DeleteCertificate)
// Timetable Scheduler — Stammdaten
api.GET("/timetable/classes", handler.ListTimetableClasses)
api.POST("/timetable/classes", handler.CreateTimetableClass)
api.DELETE("/timetable/classes/:id", handler.DeleteTimetableClass)
api.GET("/timetable/periods", handler.ListTimetablePeriods)
api.POST("/timetable/periods", handler.CreateTimetablePeriod)
api.DELETE("/timetable/periods/:id", handler.DeleteTimetablePeriod)
api.GET("/timetable/rooms", handler.ListTimetableRooms)
api.POST("/timetable/rooms", handler.CreateTimetableRoom)
api.DELETE("/timetable/rooms/:id", handler.DeleteTimetableRoom)
api.GET("/timetable/subjects", handler.ListTimetableSubjects)
api.POST("/timetable/subjects", handler.CreateTimetableSubject)
api.DELETE("/timetable/subjects/:id", handler.DeleteTimetableSubject)
api.GET("/timetable/teachers", handler.ListTimetableTeachers)
api.POST("/timetable/teachers", handler.CreateTimetableTeacher)
api.DELETE("/timetable/teachers/:id", handler.DeleteTimetableTeacher)
// Timetable Scheduler — Relations
api.GET("/timetable/curriculum", handler.ListTimetableCurriculum)
api.POST("/timetable/curriculum", handler.CreateTimetableCurriculum)
api.DELETE("/timetable/curriculum/:id", handler.DeleteTimetableCurriculum)
api.GET("/timetable/assignments", handler.ListTimetableAssignments)
api.POST("/timetable/assignments", handler.CreateTimetableAssignment)
api.DELETE("/timetable/assignments/:id", handler.DeleteTimetableAssignment)
// Timetable Scheduler — Constraints (15 typed tables)
// Teacher
api.GET("/timetable/constraints/teacher/unavailable-day", handler.ListTeacherUnavailableDays)
api.POST("/timetable/constraints/teacher/unavailable-day", handler.CreateTeacherUnavailableDay)
api.DELETE("/timetable/constraints/teacher/unavailable-day/:id", handler.DeleteTeacherUnavailableDay)
api.GET("/timetable/constraints/teacher/unavailable-window", handler.ListTeacherUnavailableWindows)
api.POST("/timetable/constraints/teacher/unavailable-window", handler.CreateTeacherUnavailableWindow)
api.DELETE("/timetable/constraints/teacher/unavailable-window/:id", handler.DeleteTeacherUnavailableWindow)
api.GET("/timetable/constraints/teacher/max-hours-day", handler.ListTeacherMaxHoursDay)
api.POST("/timetable/constraints/teacher/max-hours-day", handler.CreateTeacherMaxHoursDay)
api.DELETE("/timetable/constraints/teacher/max-hours-day/:id", handler.DeleteTeacherMaxHoursDay)
api.GET("/timetable/constraints/teacher/max-hours-week", handler.ListTeacherMaxHoursWeek)
api.POST("/timetable/constraints/teacher/max-hours-week", handler.CreateTeacherMaxHoursWeek)
api.DELETE("/timetable/constraints/teacher/max-hours-week/:id", handler.DeleteTeacherMaxHoursWeek)
api.GET("/timetable/constraints/teacher/excluded-subject", handler.ListTeacherExcludedSubjects)
api.POST("/timetable/constraints/teacher/excluded-subject", handler.CreateTeacherExcludedSubject)
api.DELETE("/timetable/constraints/teacher/excluded-subject/:id", handler.DeleteTeacherExcludedSubject)
api.GET("/timetable/constraints/teacher/excluded-room", handler.ListTeacherExcludedRooms)
api.POST("/timetable/constraints/teacher/excluded-room", handler.CreateTeacherExcludedRoom)
api.DELETE("/timetable/constraints/teacher/excluded-room/:id", handler.DeleteTeacherExcludedRoom)
// Subject
api.GET("/timetable/constraints/subject/min-day-gap", handler.ListSubjectMinDayGaps)
api.POST("/timetable/constraints/subject/min-day-gap", handler.CreateSubjectMinDayGap)
api.DELETE("/timetable/constraints/subject/min-day-gap/:id", handler.DeleteSubjectMinDayGap)
api.GET("/timetable/constraints/subject/max-consecutive", handler.ListSubjectMaxConsecutives)
api.POST("/timetable/constraints/subject/max-consecutive", handler.CreateSubjectMaxConsecutive)
api.DELETE("/timetable/constraints/subject/max-consecutive/:id", handler.DeleteSubjectMaxConsecutive)
api.GET("/timetable/constraints/subject/contiguous-when-repeated", handler.ListSubjectContiguousWhenRepeated)
api.POST("/timetable/constraints/subject/contiguous-when-repeated", handler.CreateSubjectContiguousWhenRepeated)
api.DELETE("/timetable/constraints/subject/contiguous-when-repeated/:id", handler.DeleteSubjectContiguousWhenRepeated)
api.GET("/timetable/constraints/subject/preferred-period", handler.ListSubjectPreferredPeriods)
api.POST("/timetable/constraints/subject/preferred-period", handler.CreateSubjectPreferredPeriod)
api.DELETE("/timetable/constraints/subject/preferred-period/:id", handler.DeleteSubjectPreferredPeriod)
api.GET("/timetable/constraints/subject/double-lesson", handler.ListSubjectDoubleLessons)
api.POST("/timetable/constraints/subject/double-lesson", handler.CreateSubjectDoubleLesson)
api.DELETE("/timetable/constraints/subject/double-lesson/:id", handler.DeleteSubjectDoubleLesson)
// Class
api.GET("/timetable/constraints/class/max-hours-day", handler.ListClassMaxHoursDay)
api.POST("/timetable/constraints/class/max-hours-day", handler.CreateClassMaxHoursDay)
api.DELETE("/timetable/constraints/class/max-hours-day/:id", handler.DeleteClassMaxHoursDay)
api.GET("/timetable/constraints/class/no-gaps", handler.ListClassNoGaps)
api.POST("/timetable/constraints/class/no-gaps", handler.CreateClassNoGaps)
api.DELETE("/timetable/constraints/class/no-gaps/:id", handler.DeleteClassNoGaps)
// Room
api.GET("/timetable/constraints/room/requires-type", handler.ListRoomRequiresTypes)
api.POST("/timetable/constraints/room/requires-type", handler.CreateRoomRequiresType)
api.DELETE("/timetable/constraints/room/requires-type/:id", handler.DeleteRoomRequiresType)
api.GET("/timetable/constraints/room/unavailable", handler.ListRoomUnavailable)
api.POST("/timetable/constraints/room/unavailable", handler.CreateRoomUnavailable)
api.DELETE("/timetable/constraints/room/unavailable/:id", handler.DeleteRoomUnavailable)
}
// Start server