Timetable API (sessions, slots, generation)
This document describes the timetable and session-generation endpoints implemented in ILS-dev/backend/routes/timetable.js. It is a read-only extraction of current server behaviour used by the admin/teacher calendar flows.
Overview
- Purpose: manage class timetables (timetable rows, slots) and generate concrete
timetable_sessionsfrom slots across a date range. The generator is holiday-aware and idempotent. - Key concepts:
class_timetable(timetable meta),timetable_slots(repeating slot definitions by day-of-week), andtimetable_sessions(concrete scheduled dates).
Core behaviours
- Session generation (
generateSessions) is idempotent: it skips already-generated dates and only inserts new session rows. - Holidays/breaks are read from
academic_calendar_eventsand producecancelledstatuses; exam periods produceflaggedsessions. - When a slot is edited (
PATCH /api/timetable/slots/:slotId), the implementation marks existingtimetable_sessionsfor that slot as deleted (soft-delete) so a subsequentPOST /api/timetable/:id/generatewill rebuild sessions with the new slot times. - Editing a session (
PATCH /api/timetable/sessions/:sessionId) marks it as an exception (is_exception = true).
Session statuses
scheduled— normal sessioncancelled— session blocked by holiday/breakflagged— session occurs during an exam period (monitoring/attention)
Endpoints
- GET /api/timetable?classId=
-
List timetables; optional
classIdfilters to a class. Returns meta includingsession_count. -
GET /api/timetable/:id
-
Returns the timetable row plus
slotsand currentsessions(non-deleted). -
POST /api/timetable
-
Create a timetable. Body required:
{ class_id, valid_from, valid_until }. Optionalslotsarray may be provided to insert initial slots. -
PATCH /api/timetable/:id
-
Update timetable metadata:
valid_from,valid_until,period_id,notes,status. -
DELETE /api/timetable/:id
- Soft-delete the timetable (sets
deleted_at).
Slots
- POST /api/timetable/:id/slots
-
Create a slot for a timetable. Body:
{ day_of_week, start_time, end_time, valid_from?, valid_until? }. -
PATCH /api/timetable/slots/:slotId
-
Update a slot. Body accepts the same fields as POST. The handler also soft-deletes existing
timetable_sessionsfor the slot so regenerate will rebuild sessions with new times. -
DELETE /api/timetable/:id/slots/:slotId
- Soft-delete a slot (sets
deleted_at).
Session generation
- POST /api/timetable/:id/generate
- Runs the idempotent generator which:
- Reads timetable
valid_from/valid_untiland slots for the timetable. - Reads
academic_calendar_eventsto build a set of blocked dates (holidays/breaks) and flagged dates (exam periods). - Computes all calendar dates matching each slot's day-of-week within the slot's validity window.
- Skips existing
timetable_sessionsto avoid duplicates. - Inserts new
timetable_sessionswithstatusset toscheduled,cancelled, orflaggedand returns{ generated: <count> }.
- Reads timetable
- The endpoint also marks the timetable
status = 'active'on success.
Session edits
- PATCH /api/timetable/sessions/:sessionId
- Edit a single session (reschedule, cancel, add notes). The handler sets
is_exception = truefor edits and returns the updated session.
Examples
Generate sessions for timetable 42:
curl -X POST "http://localhost:4000/api/timetable/42/generate" \
-H "Authorization: Bearer <ADMIN_JWT>"
Edit a slot (this wipes generated sessions for the slot so regenerate rebuilds them):
curl -X PATCH "http://localhost:4000/api/timetable/slots/17" \
-H "Authorization: Bearer <ADMIN_JWT>" \
-H "Content-Type: application/json" \
-d '{"day_of_week":0,"start_time":"08:30","end_time":"10:00"}'
Mark a session as cancelled with a note:
curl -X PATCH "http://localhost:4000/api/timetable/sessions/999" \
-H "Authorization: Bearer <ADMIN_JWT>" \
-H "Content-Type: application/json" \
-d '{"status":"cancelled","cancellation_reason":"teacher_absent","notes":"Substitute arranged"}'
Implementation notes & cautions
- The generator uses a 500-iteration guard per slot to avoid infinite loops when computing dates.
- Date handling uses local-date arithmetic with noon (
T12:00:00) to reduce DST edge-case issues. - Holiday/block detection relies on
academic_calendar_events— exam periods are treated asflaggedrather than cancelled. - Slot
PATCHcurrently soft-deletes session rows for that slot to ensure a clean regenerate; this is a deliberate design choice and is documented in the Slot Edit Proposal page.
Source (read-only): ILS-dev/backend/routes/timetable.js
Last updated: 2026-07-08