Build a configurable exam scheduling platform.

This document is the long-running implementation brief for turning the local scheduling logic into a modern exams operations platform hosted at exams.twisteredu.co.uk. It defines the product, inputs, rules, outputs, architecture, UI, phases, and acceptance checks needed to build the tool without losing the logic that already works.

Target outcome

  • 1Scenario-based schedulingRun and compare three-session, four-block, and custom patterns.
  • 2Configurable rulesDates, capacities, sessions, restrictions, and scoring weights are editable.
  • 3Visual reviewTimetable boards, capacity bars, clash queues, and student views.
  • 4Publish-ready exportsExcel, PDF, CSV, mail merge, and later protected student links.

Core Workflow

The app should guide users through one clear workflow while still allowing advanced configuration when needed.

1
Create projectName the exam window, choose dates, select year groups, and set project defaults.
2
Import dataUpload pupil exam requirements, assessment definitions, access arrangements, teacher timetables, rooms, and exam board schedules.
3
Configure rulesDefine sessions, capacities, restrictions, and scoring weights.
4
Run scenariosGenerate three-session, four-block, and custom schedules.
5
Review and exportCompare schedules, fix exceptions, and publish planning outputs.

Exam Modes

The core input is not a resit. The core input is that a pupil needs to take an exam, assessment, unit, component, or paper. Resit entry management is one workflow inside the wider platform.

Internal Exams

Build the schedule from school criteria: dates, sessions, rooms, access arrangements, invigilation, year restrictions, and clash rules.

Mocks Evidence assessments Internal resits Baseline exams

External Exams

Import or enter the exam board timetable, match it to pupil entries, detect clashes and heavy days, then publish personalised schedules.

Exam board schedule Pupil entries Clash detection 6+ hour day warnings

Post-Results

Import results, unit/module marks, UMS, boundaries, grades, services requested, returned scripts, and resit entry decisions.

Results hub Grade boundaries Review of marking Resit entries

Inputs and Variables

The web app must be adaptable. Every input below should be either imported, manually editable, or configurable at project level.

Area Fields Required Purpose
StudentsCandidate ID, name, year group, email, parent emailsCandidate ID, name, year groupIdentity, student timetables, mail merge, year restrictions.
Pupil exam requirementsCandidate ID, subject, assessment/component/paper, exam type, confirmed flag, sourceCandidate ID, subject, assessment/component/paperOne row means one pupil needs one exam sitting.
AssessmentsYear group, subject, assessment name, duration, qualification, component codeYear group, subject, assessment name, durationDefines the schedulable exam groups.
Access arrangementsCandidate number(s), extra time, separate room type, rest breaks, laptop, reader, scribe, notesCandidate number(s), arrangement typeControls finish times, room allocation, supervision, and invigilation instructions.
TeachersTeacher name, subject, unavailable dates, department, role, support allowanceOptionalSupports teacher spread, invigilation eligibility, and pupil-support protection.
Teacher timetableTeacher, day, period, class, subject, year group, room, available flagRequired for invigilation schedulingDetermines whether a teacher is free or whether a lesson can be repurposed for invigilation.
InvigilatorsName, internal/external, availability, max periods, room restrictions, training statusRequired for invigilation schedulingAllocates invigilators using configurable ratios and override rules.
RoomsRoom name, capacity, available dates, access suitability, locationOptional for phase 1Allows location allocation and room pressure reports.
DaysDate, label, allowed year groups, capacity target, hard capacityYesDefines the exam window and day-specific rules.
SessionsName, start, end, hard end, capacity, overflow flag, clash flagYesDefines timetable blocks and fallback patterns.
ConstraintsScope, type, hard/soft, weight, descriptionYesMakes the optimiser configurable rather than hard-coded.
ScenariosName, session set, ruleset, weights, seed, iterationsYesAllows comparison between planning options.
Exam board timetableBoard, qualification, subject, component, date, start, durationFor external examsExternal schedules are entered, not optimised, then matched to pupil entries.
Pupil subject entriesCandidate ID, qualification, board, subject, unit/component, HOD confirmationFor external examsAllows HODs to confirm or update external exam entries.
ResultsCandidate ID, board, subject, unit, raw mark, UMS, grade, overall gradeFor results hubStores external results, including module/unit results and overall awards.
Grade boundariesBoard, series, subject, unit, grade, raw mark boundary, UMS boundaryFor results hubSupports analysis of marks, grades, near misses, and resit decisions.
Exam servicesCandidate ID, paper, service type, status, cost, deadline, uploaded scriptFor post-results servicesTracks reviews of marking, clerical checks, access to scripts, and returned papers.
PoliciesPolicy name, category, file, version, effective date, access levelFor policy centreStores secure exam policies and links them to guidance and workflows.
Mail merge templatesTemplate name, type, audience, variables, attachment rulesFor communicationGenerates timetable PDFs, results letters, resit letters, and exam-service notices.

Constraint System

Rules should be stored as configurable records. The app must make it clear which rules are hard blockers and which are weighted preferences.

Hard Rules

Cannot be broken unless the schedule is declared infeasible.

Year 11 no Thursday Duration fits block Valid date window Room hard capacity Required access room

Soft Preferences

Can be broken with a visible penalty and exception report.

Avoid clashes Avoid back-to-back Keep Sunday near 80 Teacher spread Invigilator fairness

Scenario Weights

Weights let the user decide which compromises are least acceptable.

Critical High Medium Low Override allowed
Implementation principle Every compromise must be explainable. If the optimiser chooses an awkward placement, the UI should show which rule pressure caused it and where it appears in the exception reports.

Access Arrangements

Access arrangements must be first-class scheduling inputs, not notes. They affect rooming, timings, supervision, instructions, and invigilation.

Arrangement Types

Support multiple arrangements per pupil and per exam where needed.

25% extra time Separate room individual Separate room small group Rest breaks Laptop Reader Scribe Prompter

Rooming Impact

Extra rooms can be assigned to external invigilators by default, with configurable exceptions.

Individual room Small group room Laptop suitable Rest break supervision

Instruction Impact

Invigilators should see exactly what applies in their room, including what-if guidance.

Room card Student list Special instructions Incident guidance

Invigilation Scheduling

Invigilation should be scheduled after the exam timetable and room allocation exist. The system must support internal teachers, external invigilators, ratios, override options, and teacher timetable imports.

Configurable Ratios

Individual roomCan be 1:1 where required.
Small group roomConfigurable ratio, often external invigilator led.
Large spaceDefault configurable rule: 1:30 plus 1.
OverrideManual override with reason and audit log.

Teacher Eligibility Rules

  • Teacher must be free at that time, unless a configured lesson-release rule applies.
  • Teacher should not normally be teaching those pupils unless the lesson is being repurposed.
  • If the exam in their subject is more than one week away, lessons for classes sitting an exam may be used for invigilation.
  • System should protect a configurable number of free periods per week for pupil support.
  • External invigilators should normally cover access-arrangement extra rooms.
Invigilator guide portal Anyone assigned to invigilate should be able to log in, see their room, candidate list, access arrangements, start/end times, checklist, policy references, and what-if guidance.

Results Hub and Exam Services

The platform should continue after exams. Results, grade boundaries, services, scripts, and resit entries should live in one controlled workflow rather than email chains.

Results Hub

Import external results, module/unit results, raw marks, UMS, grade boundaries, and overall grades.

Raw mark UMS Unit grade Overall grade Boundaries

Resit Entry Management

Use module results to identify possible resits, collect decisions, and prepare exam board entry data.

Near boundary HOD review Candidate confirmation Board export

Exam Services

Track reviews of marking, clerical checks, access to scripts, return of papers, costs, deadlines, and uploaded scripts.

Review of marking Return of paper Script upload HOD viewing

Communications and Policy Centre

Mail merge, PDF generation, secure policy storage, and role-based guidance should be part of the platform from the beginning.

Rich Mail Merge

Generate personalised PDFs and emails for different exam workflows.

Exam timetables Results letters Resit letters Exam service updates Access arrangement notices Invigilation schedules

Policy Centre

Store exam policies securely, version them, and link them to invigilator guides, exam services, access arrangements, and results workflows.

Secure storage Version control Role-based access Referenced guidance

Users, Roles, and Permissions

The platform needs role-based access from the start. Exam managers, leadership, HODs, HOYs, teachers, students, and parents should see different information and have different actions available.

Role Typical Access Allowed Actions Restrictions
Exam ManagerFull operational access across projects, schedules, entries, rooms, invigilation, results, services, policies, and communications.Create projects, import data, configure rules, run schedules, publish outputs, manage services, upload results, manage users.Actions should be audited because this role can change official exam data.
LeadershipRead-only or approval-level access to dashboards, high-level schedules, risks, capacity, results summaries, and policy compliance.Review status, approve publication, view reports, monitor exceptions.Should not edit operational schedule data by default.
HODDepartment-level access to subject entries, results, scripts, services, and subject-specific schedules.Confirm entries, review returned papers, request services, comment on resit decisions, view subject candidate lists.Cannot view unrelated departments unless granted wider access.
HOYYear-group access to pupil timetables, clashes, access risks, heavy days, attendance concerns, and communication status.Review year group impact, support student follow-up, view relevant student schedules.No default access to department-only scripts or whole-school configuration.
TeacherOwn classes, assigned invigilation, relevant scripts/papers, relevant candidate lists, and guidance.View invigilation instructions, view assigned rooms, view returned scripts when permitted, comment on services where assigned.Should not see unrelated pupil results or full platform settings.
StudentOwn timetable, room, access arrangements that apply to them, results letters, exam-service status where appropriate.Download timetable, view personalised notices, acknowledge communications if enabled.Can only see their own data.
ParentLinked child timetable, letters, results communications, service request status where permitted.View/download published documents, acknowledge communications, submit consent/confirmation if enabled.Can only see linked children and published information.
External InvigilatorAssigned sessions, room cards, candidate lists, access instructions, invigilation guide, policies needed for the assignment.View assigned duties, mark checklist complete, report incidents if enabled.No access to wider student records, results, or internal planning beyond assigned duties.
System AdminTechnical administration, integrations, backups, domain settings, and user provisioning.Manage authentication, roles, deployment settings, backups, and logs.Should not be used for everyday exam operations.
Permission design principle Use role-based defaults with scoped access. A HOD should be scoped to subjects/departments, a HOY to year groups, a teacher to classes or invigilation duties, and parents/students to their own records only.

Architecture

The first production version should reuse the existing Python scheduling logic while introducing a web UI, persisted projects, background runs, and reproducible exports.

Recommended Stack

FrontendNext.js, React, TypeScript
Backend APIFastAPI, Python
OptimiserCurrent Python scheduler, later OR-Tools if needed
DatabasePostgreSQL
JobsRedis plus RQ or Celery
DeploymentDocker Compose on VPS
ProxyCaddy or Nginx with HTTPS

Repo Structure

apps/webNext.js app and UI components
apps/apiFastAPI app, routes, auth, exports
packages/schedulerPorted scheduling engine and tests
packages/sharedShared schemas and generated API client
infraDocker, Caddy/Nginx, deployment scripts
docsProduct specs, import templates, admin guide

What FastAPI Means

FastAPI is a Python web framework for building the backend API. In this architecture, the browser UI calls FastAPI endpoints to upload files, save settings, start scheduler jobs, fetch timetable data, and download exports. It fits well because the optimiser and Excel/PDF generation are already Python-friendly.

Python backend API routes Validation Background jobs

SQLite or PostgreSQL

SQLite is fine for a local single-user tool or an early prototype. PostgreSQL is the better production choice for a VPS web app with multiple users, background jobs, uploaded files, audit history, concurrent scenario runs, results data, and policy storage.

SQLite: prototype PostgreSQL: production Backups Concurrent users

Data Model

The model must separate exam definitions, pupil exam requirements, scheduled exam blocks, individual pupil sittings, room allocation, and invigilation. Resits are not the core object; they are a type of pupil exam requirement.

Table Key Fields Notes
usersid, name, email, auth_provider, status, last_loginAll people who can log in: staff, students, parents, invigilators, and admins.
rolesid, name, description, system_roleExam Manager, Leadership, HOD, HOY, Teacher, Student, Parent, External Invigilator, System Admin.
permissionsid, key, description, module, actionGranular capabilities such as schedule.run, results.view, services.request, policies.manage.
role_permissionsrole_id, permission_idDefault permission set for each role.
user_rolesuser_id, role_id, scope_type, scope_idAssigns roles with scope, such as HOD for Economics or HOY for Year 11.
student_guardiansstudent_id, user_id, relationship, priorityLinks parents/guardians to students.
teacher_classesstaff_id, class_id, subject, year_groupLinks teachers to the pupils/classes they teach.
projectsid, name, school, academic_year, timezone, modeTop-level container for an internal exam window, external exam series, results cycle, or services workflow.
exam_seriesproject_id, board, qualification, series, internal_externalGroups exams by internal window or external board series.
studentsproject_id, candidate_id, name, year_group, emailsCandidate ID should be unique within a project.
exam_componentsseries_id, year_group, subject, component_name, code, durationInternal assessment, external paper, unit, module, or component definition.
pupil_exam_requirementsstudent_id, component_id, source, confirmed, entry_statusOne row per pupil exam that must be sat, whether internal, external, resit, or evidence assessment.
access_arrangementsstudent_id, arrangement_type, value, applies_to, notesSupports extra time, rest breaks, separate rooms, laptop, reader, scribe, prompter, and future arrangements.
exam_daysproject_id, date, label, capacity_target, restrictionsSupports different windows and day-specific capacity.
exam_sessionsday_id, name, start, end, hard_end, capacitySession patterns are configurable.
roomsproject_id, name, capacity, room_type, access_suitableLarge spaces, small group rooms, individual rooms, laptop rooms, and overflow rooms.
room_allocationsrun_id, session_id, room_id, component_id, student_groupMaps exams and access-arrangement groups to locations.
constraintsscope, rule_type, hard, weight, config_jsonDefines rules without code changes.
scenariosproject_id, name, session_set, weights, statusThree-session, four-block, or custom.
scenario_runsscenario_id, seed, iterations, score, metrics_jsonStores reproducible optimisation results.
scheduled_exam_blocksrun_id, component_id, session_idThe main exam timetable.
student_sittingsrun_id, student_id, component_id, session_id, room_id, sitting_typeIndividual pupil timetable, including deferred clash sittings.
staffproject_id, name, email, subject, role, internal_externalTeachers, exams staff, HODs, and external invigilators.
teacher_timetablestaff_id, day, period, class_name, subject, year_group, roomImported timetable used to determine teacher availability and lesson-release rules.
invigilation_rulesproject_id, room_type, ratio, plus_one, override_allowedConfigurable ratios such as 1:1 or 1:30 plus 1.
invigilation_assignmentsrun_id, staff_id, room_allocation_id, role, override_reasonWho invigilates each room and why they were eligible.
exceptionsrun_id, type, severity, student_id, component_id, detailClashes, back-to-back, over-capacity, missing data, access risks, invigilation gaps.
exam_board_schedulesseries_id, board, subject, component, date, start, durationExternal exam schedules entered from boards.
exam_entriesstudent_id, series_id, subject, component, status, hod_confirmedExternal entry management and HOD confirmation.
resultsstudent_id, component_id, raw_mark, ums, grade, overall_gradeUnit/module and overall results.
grade_boundariesseries_id, component_id, grade, raw_boundary, ums_boundaryBoundary storage for results analysis.
exam_servicesstudent_id, component_id, service_type, status, cost, deadlineReview of marking, clerical checks, access to scripts, return of papers.
uploaded_scriptsexam_service_id, file_path, uploaded_by, uploaded_atReturned papers/scripts viewable securely by teachers and HODs.
policiesname, category, file_path, version, access_levelSecure exam policy centre with versioned documents.
mail_merge_templatesname, type, audience, body, variables_jsonPDF/email templates for timetables, results, resits, services, and invigilation.
exportsrun_id, type, file_path, created_atExcel, CSV, PDF, mail merge data.
audit_eventsuser_id, action, entity_type, entity_id, before_json, after_json, created_atRecords sensitive changes to schedules, entries, results, services, policies, and permissions.

UI Screens

The UI should feel like a clean operational planning tool. Dense, visual, readable, and built for repeated review rather than a marketing site.

Dashboard

Recent projects, active scenarios, data warnings, last run status, and quick actions.

Exam Scheduling Dashboard3 active scenarios
3-session
4-block
Warnings
Exports

Data Import

Upload files, map columns, preview detected data, and fix import issues before scheduling.

Column Mapping5 required columns found

Session Builder

Create editable day/session patterns, including capacity, hard end times, and overflow rules.

Session Pattern: Three SessionsSunday target 80
07:30
10:00
12:30
Overflow

Visual Timetable

Whole-school, year-group, student, teacher, and room views with capacity bars and warnings.

Whole-School TimetableCapacity view
Sun 07:30
Mon 07:30
Tue 10:00
Wed 12:30

Access Arrangements

Manage extra time, separate rooms, rest breaks, laptop use, readers, scribes, and room-specific instructions.

Access Arrangement PlannerRoom impact
Extra time
Individual room
Laptop
Rest breaks

Invigilation

Schedule internal teachers and external invigilators using ratios, teacher timetables, release rules, and overrides.

Invigilation Assignment1:30 + 1
Main hall
Small room
1:1 room
Free staff

Scenario Comparison

Compare three-session, four-block, and custom scenarios side by side with movement reports.

3 Sessions vs 4 Blocks4 metrics improved
Clashes
Back-to-back
Sunday
Thursday

Exception Review

Review same-session clashes, deferred sittings, short gaps, over-capacity sessions, and data issues.

Exception QueueNeeds review

Results Hub

Import results, units, UMS, boundaries, and overall grades, then identify resit and service opportunities.

Results HubBoundaries loaded
Unit marks
UMS
Near misses
Resits

Exam Services

Track reviews of marking, access to scripts, returned papers, uploaded scripts, costs, status, and deadlines.

Exam Services TrackerScripts uploaded

Policy Centre

Store secure exam policies, versioned guidance, invigilator instructions, and role-based references.

Policy CentreSecure

Exports

Generate Excel workbooks, CSV files, student PDFs, teacher schedules, room schedules, and mail merge data.

Export CentreReady
Excel
PDF
CSV
Email

Outputs

Outputs should be generated per scenario run and remain attached to the run so decisions can be audited later.

Planning Outputs

Whole-school timetable, year-group grids, room grids, teacher grids, session load report, capacity report.

Student Outputs

Student timetable table, student timetable grid, PDF timetable, future protected link and calendar export.

Exception Outputs

Clashes, deferred sittings, back-to-back, short gaps, extra-time finish risks, missing data, over-capacity sessions.

Invigilation Outputs

Invigilator timetable, room cards, attendance lists, access arrangement instructions, ratio checks, and override report.

Results Outputs

Results PDFs, unit/module summaries, grade boundary analysis, resit recommendation lists, and HOD review exports.

Services Outputs

Review of marking tracker, return of paper tracker, uploaded script links, service letters, and deadline reports.

Implementation Plan

This phased plan is designed for a long-running Codex task. Each phase has a clear done condition and should leave the app usable.

Phase 0

Repo and Foundations

  • Create GitHub repo and initialise monorepo structure.
  • Add Next.js app, FastAPI app, scheduler package, Docker Compose, and README.
  • Add lint, format, type check, and basic CI.
  • Create initial design system: colours, typography, spacing, buttons, tables, panels.
Phase 1

Import and Core Exam Scheduling

  • Build file upload and column mapping for pupil exam requirements, exam components, and access arrangements.
  • Persist imported project data to PostgreSQL.
  • Port current scheduler into backend service.
  • Generate three-session, four-block, and comparison workbooks.
Phase 2

Visual Timetable, Rooming, and Scenario Review

  • Build whole-school timetable board with capacity bars and filters.
  • Add year-group, student, teacher, room, and access-arrangement views.
  • Add scenario comparison dashboard and assessment movement report.
  • Add exception queue for clashes, back-to-back, and data issues.
Phase 3

Configurable Rules, Access, and Manual Review

  • Build session builder and day capacity editor.
  • Build constraint studio with hard/soft rules and weights.
  • Build access arrangement manager for extra time, separate rooms, rest breaks, laptop use, readers, scribes, and room instructions.
  • Add manual schedule adjustment workflow with revalidation.
  • Add audit log explaining why a schedule changed.
Phase 4

Invigilation Scheduling

  • Import teacher timetables by CSV and model teacher availability.
  • Build invigilation ratio rules with overrides: 1:1, small group, large space 1:30 plus 1, and custom variants.
  • Assign internal teachers and external invigilators according to configurable eligibility rules.
  • Build invigilator guide portal with room cards, access instructions, what-if guidance, and policy references.
Phase 5

External Exams, Results, and Services

  • Add external exam board schedule import and pupil entry matching.
  • Add HOD confirmation workflow for external subject/unit/component entries.
  • Add Results Hub with module/unit results, UMS, grade boundaries, and overall grades.
  • Add exam services tracker for review of marking, access to scripts, return of paper, uploaded scripts, costs, and deadlines.
Phase 6

Mail Merge, Policy Centre, and Deployment

  • Add rich mail merge templates and PDF generation for timetables, results, resits, letters, services, and invigilation schedules.
  • Add secure policy centre with versioned policies and role-based references.
  • Add authentication and project permissions.
  • Deploy to VPS at exams.twisteredu.co.uk with HTTPS, backups, monitoring, logs, and rollback instructions.

Deployment Plan

The deployment should be boring and recoverable. The app will be hosted on a VPS under the Twister Education domain.

VPS Services

  • web: Next.js app
  • api: FastAPI backend
  • worker: scheduler and export jobs
  • postgres: persistent database
  • redis: background job queue
  • proxy: HTTPS reverse proxy

Operational Requirements

  • Daily PostgreSQL backup.
  • Persistent upload and export storage.
  • Environment variables documented in .env.example.
  • HTTPS certificate automation.
  • Deploy script and rollback notes.
  • Admin user creation command.

Acceptance Criteria

These checks define what a usable first release must do before it can replace the local Python tool for real scheduling work.

Area Acceptance Check Evidence
ImportCan import pupil exam requirements, exam components, access arrangements, rooms, teacher timetables, and external exam board schedules.Successful import plus data issue report.
SchedulingCan generate three-session and four-block internal exam schedules from the same project.Scenario runs stored with metrics.
ComparisonCan compare both schedules side by side and list changed assessment placements.Comparison page and export.
Visual timetableCan review whole-school, year-group, and student views in the browser.Browser verified at desktop and mobile widths.
Access arrangementsCan model extra time, separate rooms, rest breaks, laptop use, and room-specific instructions.Access view, rooming report, and invigilator instructions.
InvigilationCan allocate internal teachers and external invigilators using configurable ratios, availability, and override rules.Invigilation timetable, ratio report, and override audit.
External examsCan import exam board schedules, match them to pupil entries, and flag clashes and days over six hours.External timetable view and exception report.
Results hubCan store results, module/unit marks, UMS, grade boundaries, and overall grades.Results import, results tables, and boundary analysis.
Exam servicesCan track review of marking, return of paper, access to scripts, uploaded scripts, status, deadlines, and costs.Services tracker and secure script viewer.
PoliciesCan store secure, versioned exam policies and reference them from invigilation and services workflows.Policy centre with role-based access.
Mail mergeCan generate PDFs and mail merge outputs for timetables, results, resits, services, and invigilation schedules.Generated PDF/CSV outputs with template variables.
PermissionsCan enforce different access for exam managers, leadership, HODs, HOYs, teachers, students, parents, external invigilators, and admins.Role tests and scoped visibility checks.
AuditCan record who changed schedules, entries, results, services, policies, and permissions.Audit event table and UI history view.
ExceptionsCan identify clashes, deferred sittings, back-to-back rows, access risks, invigilation gaps, and over-capacity sessions.Exception queue matches exported reports.
ExportsCan export the current workbook outputs plus room, invigilation, services, and results outputs.Generated files open without errors.
DeploymentCan deploy from GitHub to the VPS with documented commands.Live app at exams.twisteredu.co.uk.

Long-Running Agent Brief

Use this brief when starting the implementation task. It keeps the build aligned with the product goal and prevents drifting into a one-off prototype.

Implementation Instructions

  • Start by creating a GitHub repo and monorepo structure for the app.
  • Model the core object as pupil exam requirements, not resits. Resits are one workflow inside the platform.
  • Keep the first milestone focused: upload exam requirement data, run three-session and four-block internal exam scenarios, compare visually, export workbooks.
  • Port the existing Python scheduler rather than rewriting the optimiser from scratch.
  • Make dates, sessions, capacities, access arrangement rules, invigilation ratios, year-group restrictions, and scoring weights configurable.
  • Build a clean operational UI: sidebar navigation, timetable board, dense tables, filters, status badges, capacity bars.
  • Add teacher timetable import before attempting invigilation scheduling.
  • Build access arrangements as first-class data affecting timing, rooms, instructions, and invigilation.
  • Implement role-based access early: exam managers, leadership, HODs, HOYs, teachers, students, parents, external invigilators, and admins.
  • Do not send emails in phase 1. Generate mail merge data and later add PDF/email publishing.
  • Add results, grade boundaries, exam services, script upload, policies, and HOD entry confirmation after the scheduling foundation works.
  • Verify with the demo workbook and a real anonymised workbook before deployment.
  • Do not mark complete until the app is deployed or has clear deployment instructions ready for the VPS.