Skip to main content

School timetable

Planninq keeps a school's timetable: every lesson with its time, group, teacher, room and subject. A rostering system such as Zermelo, Untis, Xedule or TimeEdit delivers the lessons through integriq. Learniq shows them to teachers, pupils and parents.

Planninq has no timetable page of its own. It stores the lessons and answers two kinds of question: "deliver these lessons" and "which lessons does this group or teacher have this week".

What a lesson holds​

FieldMeaning
externalRefThe id the rostering system gives the lesson.
sourceSystemThe system that delivered it, for example roster-zermelo, or manual.
subject, titleThe subject as the school names it, and the name shown.
startsAt, endsAtWhen the lesson runs.
groupReference, cohortIdThe school's group code, and the learniq cohort it belongs to when known.
teacherReference, teacherUserIdThe school's teacher code, and the teacher's Nextcloud account when known.
roomReference, roomLabelThe school's room code and the room name.
statusdraft, scheduled or cancelled.
importedAtWhen planninq last received the lesson. Planninq fills this in.

Delivering the same timetable again​

A rostering system sends the whole timetable again every night. Planninq recognises a lesson by its source and its externalRef:

  • a lesson it has not seen is added;
  • a lesson that moved room or time is updated;
  • a lesson that did not change is left alone and counted as unchanged.

A lesson with a missing subject or time, or one that ends before it starts, is refused with a reason. The rest of the delivery still lands.

Who can read the timetable​

A lesson is not open to everyone who can sign in. It can be read by:

  • members of the Nextcloud group planninq-timetable, meant for planners and staff who need the whole school timetable. Create the group and add those people to it;
  • the teacher the lesson names, through teacherUserId;
  • admins.

Checking a draft timetable with the teachers​

A school often checks a new timetable with its teachers before pupils see it. Deliver those lessons with the status draft. A draft lesson can be read only by the teacher it names and by admins; the planninq-timetable group sees it once it is published. A read returns drafts only when it asks for them with includeDrafts=true.

When the teachers agree, an admin publishes the drafts of one source for a period:

POST /apps/planninq/api/timetable/sessions/publish with {"sourceSystem": "roster-zermelo", "from": "2026-10-05T00:00:00+02:00", "to": "2026-10-11T23:59:59+02:00"}

Every draft of that source in that period becomes scheduled. Delivering a draft lesson again as scheduled publishes that one lesson. A lesson that is already published cannot turn back into a draft: the delivery refuses it with already-published.

Pupils and parents see their own lessons in learniq. Learniq works out which groups they belong to and asks planninq for those groups only.

For integrators​

Apps talk to planninq through two events (ADR-041). Look the class up by name and treat a missing class as "planninq is not installed".

  • OCA\Planninq\Event\TimetableUpsertRequestedEvent: deliver a batch. Read the counts from getResult().
  • OCA\Planninq\Event\TimetableSessionsQueryEvent: read lessons by cohortId, groupReference, teacherUserId or teacherReference, optionally between from and to. Read them from getSessions(). Planninq answers this event without checking the signed-in user, so your app must only ask for a group or teacher that its user is allowed to see.

Two endpoints do the same over HTTP:

MethodPathWho
GET/apps/planninq/api/timetable/sessions?cohortId=…&from=…&to=…Any signed-in user, who gets only the lessons they may read
POST/apps/planninq/api/timetable/sessions/upsert with {"sourceSystem": "…", "sessions": […]}Admins
POST/apps/planninq/api/timetable/sessions/publish with {"sourceSystem": "…", "from": "…", "to": "…"}Admins

The full contract, with every field and rejection code, is in openspec/changes/archive/2026-09-29-school-timetable-target/contract.md.