Frontend — School Admin Dashboard Build Plan
Full-Stack Delivery Plan for the School Administration Console — v2.0
401 models
327 enums
285 .tsx files
31 routes
~282 new pages needed
257 Swagger tags
1. Executive Summary
Management has requested a fully functional school administration dashboard — one that a school administrator can use to completely run a school, backed by real data, and working across all ISCED levels (primary through doctoral).
The backend is ready. 30+ engines delivering 1,772 REST endpoints across 401 Prisma models handle every aspect of school operations: admissions, student lifecycle, programmes, courses, grading, attendance, assignments, fees, wallets, staff, scheduling, timetabling, library, health, behavior, early warning, hostel, transport, canteen, documents, notifications, messaging, scholarships, oversight, and more. All endpoints are Swagger-documented across 257 tags. All 3,607 tests pass across 142 test files.
The frontend is not. Today, only the UADE landing dashboard (1 of 30+ engines) is connected to real API data. The remaining engines have zero frontend representation. The app has 31 page routes — mostly scaffold/demo pages. None are wired to the school management API.
The gap is pure frontend engineering. No new backend endpoints are needed. The work is:
- Build a tenant-scoped shell (
/dashboard/school/[tenantId]/...) with RBAC-filtered navigation
- Build ~25 frontend feature modules, each consuming 1–3 backend engines
- Make every module ISCED-aware (conditional labels, fields, features based on
iscedLevels[])
- Ensure real data flows end-to-end: CRUD operations, pagination, search, filters, bulk actions
- Build a separate Organisation Dashboard context for multi-school management (OrgPE)
2. Problem Case
2.1 What Was Asked
"Build the school admin dashboard with real data and full functionalities to completely run a school and across different ISCED levels."
2.2 What "Completely Run a School" Means
A school administrator needs to perform 25+ distinct functional domains. Every domain, its backend engine, and endpoint count:
| Domain | What They Do | Engine | Endpoints |
| Admit students | Open windows, review apps, score merit, extend offers, enroll | ADME | 62 |
| Manage students | Identity, guardians, docs, groups, class placement, transfers, clearance, ID cards, pastoral, re-enrollment | StuLCE | 66 |
| Set up programmes | Lifecycles, levels, progression rules, specializations, graduation | PME | 46 |
| Manage courses | Catalogue, offerings, syllabi, curriculum maps, outcomes, materials, content | CME | 77 |
| Master syllabus | Browse national syllabi, adopt/fork, custom builder, review pipeline | MaSyE | 50 |
| Grade students | Assessment creation, score entry, grade computation, GPA/CGPA, report gen, sequences, templates, graduation | GME | 103 |
| Online exams | Question bank, exam papers, online exam delivery, proctoring, auto-grading | QBE + GME/OEE | 45 |
| Track attendance | Mark attendance (6 event types), configure devices, set alerts, bridge grades | ATME | 28 |
| Manage assignments | Create assignments, track submissions, grade, contestation, bulk scoring | ASME | 21 |
| Collect fees | Structures, billing, payments, installments, waivers, discounts, debt, revenue share, tax | ACCTE/FME | 98 |
| Student wallets | Closed-loop cashless campus: wallets, parent funding, merchant POS, catalogue, fee bridge | ACCTE/WME | 53 |
| Subscriptions | Feature gates, subscription tiers, tenant subscriptions, overrides, enforcement | ACCTE/SBE | 37 |
| Manage staff | Onboard, contracts, qualifications, CPD, appraisals, transfers, exit, reporting | StaME | 60 |
| Schedule & timetable | Academic calendars, class timetables, exam timetables, staff leave, facilities, events | SCIE | 160 |
| Run the library | Catalogue, circulation, holds, fines, textbooks, digital resources, reading lists, inventory | LME | 95 |
| Manage health | Records, allergies, dietary, immunizations, clinic visits, sickbay, medications, pharmacy, growth | SHME | 72 |
| Track behavior | Events, at-risk detection, counseling, escalation hearings, contracts, rewards, EWS | SBME | 88 |
| Run hostels | Room allocation, exeat permits, inspections, visitors, fees, staff, operations | HME | 57 |
| Run canteen | Meal plans, sessions, check-in, tables, menu schedule, dietary alerts | RCM | 32 |
| Manage transport | Routes, stops, vehicles, drivers, enrollment, trip tracking, attendance, incidents | TME | 62 |
| Generate documents | Report cards, transcripts, certificates, custom templates, verification QR | DTGE | 38 |
| Send notifications | Multi-channel (email, SMS, WhatsApp, push, in-app), templates, inbox, preferences | NSE | 30 |
| Messaging | Two-way chat (direct + group), topics, auto-post, moderation, broadcast | MSGE | 33 |
| Handle scholarships | Programmes, applications, committee review, awards, disbursement, donors, marketplace | SCME | 91 |
| Oversee schools | Jurisdictions, compliance, inspections, analytics, alerts, transfers, audit | OvME | 82 |
| Provision schools | Academic structure setup, calendar, course proposals, facilities, grading config | SAPE | 109 |
| Multi-school orgs | Organisation management, KYC, command center, school access, transfers | OrgPE | 25 |
2.3 What "Across Different ISCED Levels" Means
| Concept | Nursery (ISCED 0) | Primary (1–2) | Secondary (3) | University (5–8) |
| Class unit | "Nursery 1" / "KG 2" | "Class 3" / "Form 2" | "Form 5" / "Terminale" | "Year 1" / "Semester 2" |
| Progression | Age-based promotion | Auto-promote by age/score | Exam-gated (GCE, BEPC) | Credit-accumulation |
| Grading | Developmental milestones / narrative | Marks /10 or /20 | Marks + GCE grades | GPA 0.0–4.0, CGPA |
| Course selection | Activity-based (no formal courses) | Fixed curriculum | Fixed + optional tracks | Electives, minors, credits |
| Fees | Flat annual/termly | Flat annual/termly | Flat + exam fees | Per-credit differential |
| Timetable | Activity schedule (simple blocks) | Simple (1:1) | Subject rotation | Multi-section + labs |
| Hostel | N/A (day school only) | Rare | Common (boarding) | Universal (residential) |
| Library | Story corner / read-aloud | Basic lending | Lending + textbook scheme | Full circulation + digital + reserves |
| Assessment | Observation-based / portfolio | Continuous only | CA + end-of-term + national | CA + midterm + finals + thesis |
| Transport | Essential (very young children) | Essential (young children) | Common | Rare (campus-based) |
| Canteen | Snack/lunch (supervised) | Day school lunch | Boarding 3 meals/day | Campus dining, wallet |
| Guardian mgmt | Critical (primary contact) | Prominent | Visible | Minimal |
| Health | Critical (immunization gate, growth) | Important | Standard | Self-managed |
3.1 Backend Engine Matrix 30+ engines
| # | Engine | Code | GET | POST | PUT | PATCH | DEL | Total |
| 1 | Scheduling & Calendar | SCIE | 60 | 76 | 15 | 0 | 9 | 160 |
| 2 | Fee Management | ACCTE | 56 | 76 | 13 | 0 | 6 | 151 |
| 3 | Auto-Provisioning | SAPE | 48 | 30 | 21 | 0 | 10 | 109 |
| 4 | Grading | GME | 36 | 52 | 11 | 0 | 4 | 103 |
| 5 | Library | LME | 40 | 35 | 19 | 0 | 1 | 95 |
| 6 | Scholarships | SCME | 37 | 48 | 6 | 0 | 0 | 91 |
| 7 | Student Behavior | SBME | 31 | 44 | 13 | 0 | 0 | 88 |
| 8 | Oversight | OvME | 45 | 23 | 6 | 7 | 1 | 82 |
| 9 | Courses | CME | 27 | 35 | 11 | 0 | 4 | 77 |
| 10 | Student Health | SHME | 29 | 30 | 9 | 2 | 2 | 72 |
| 11 | Student Lifecycle | StuLCE | 23 | 28 | 10 | 0 | 5 | 66 |
| 12 | Admissions | ADME | 19 | 37 | 6 | 0 | 0 | 62 |
| 13 | Transport | TME | 28 | 15 | 8 | 4 | 7 | 62 |
| 14 | Staff | StaME | 22 | 24 | 14 | 0 | 0 | 60 |
| 15 | Hostel | HME | 25 | 13 | 14 | 0 | 5 | 57 |
| 16 | Master Syllabus | MaSyE | 17 | 20 | 6 | 2 | 5 | 50 |
| 17 | Programmes | PME | 16 | 21 | 3 | 0 | 6 | 46 |
| 18 | Documents | DTGE | 12 | 20 | 5 | 0 | 1 | 38 |
| 19 | Subscriptions | SBE | 21 | 6 | 3 | 7 | 0 | 37 |
| 20 | Platform | Platform | 19 | 8 | 6 | 0 | 2 | 35 |
| 21 | Messaging | MSGE | 11 | 14 | 5 | 0 | 3 | 33 |
| 22 | Canteen | RCM | 13 | 8 | 1 | 8 | 2 | 32 |
| 23 | Notifications | NSE | 13 | 11 | 2 | 0 | 4 | 30 |
| 24 | Attendance | ATME | 12 | 12 | 3 | 0 | 1 | 28 |
| 25 | Org Portal | OrgPE | 9 | 13 | 3 | 0 | 0 | 25 |
| 26 | Assignments | ASME | 6 | 12 | 2 | 0 | 1 | 21 |
| 27 | Question Bank | QBE | 8 | 9 | 2 | 0 | 1 | 20 |
| 28 | RBAC | RBAC | 9 | 3 | 2 | 0 | 1 | 15 |
| 29 | UADE | UADE | 8 | 0 | 0 | 0 | 0 | 8 |
| 30 | Auth | AUTH | 3 | 1 | 0 | 0 | 1 | 5 |
| TOTALS | 713 | 724 | 223 | 30 | 82 | 1,772 |
3.2 Prisma Schema & Tests
401 models
327 enums
50+ education systems
75 feature gates
142 spec files
3,607 test cases
All green ✓
4. ISCED Level Strategy
The backend does not have separate codepaths for primary vs. university. Tenant.iscedLevels: Int[] declares which levels the school operates at. The frontend reads this and conditionally renders. See the ISCED Rendering Map (Section 18) for the complete per-component decision matrix.
| Level | Name | Age | Examples |
| 0 | Early childhood | 0–5 | Nursery, kindergarten |
| 1 | Primary | 6–11 | Primary school (Class 1–6) |
| 2 | Lower secondary | 12–14 | Junior secondary (Form 1–5, 6e–3e) |
| 3 | Upper secondary | 15–17 | Senior secondary (Sixth Form, Terminale) |
| 4 | Post-secondary non-tertiary | 18–19 | Vocational diploma, trade school |
| 5 | Short-cycle tertiary | 18–20 | HND, associate degree |
| 6 | Bachelor's | 18–22 | University undergraduate |
| 7 | Master's | 22–24 | Postgraduate |
| 8 | Doctoral | 24+ | PhD programmes |
5. Action Plan
5.1 Build Phases Overview
UADE, RBAC, AUTH — ~5 pages
CriticalTenant contextRBAC navSchool overview
StuLCE (66), ADME (62), StaME (60) — ~40 pages
CriticalStudentsAdmissionsStaff
PME (46), CME (77), MaSyE (50), GME (103), ATME (28), ASME (21), QBE (20) — ~55 pages
CriticalProgrammesCoursesGradingAttendanceAssignmentsOnline Exams
ACCTE/FME (98), WME (53), SCIE (160), DTGE (38) — ~50 pages
HighFeesWalletSchedulingTimetableDocuments
SHME (72), SBME (88), LME (95), HME (57), RCM (32), TME (62) — ~65 pages
HighHealthBehavior & EWSLibraryHostelCanteenTransport
NSE (30), MSGE (33) — ~12 pages
HighNotificationsMessagingWebSocket
SCME (91), OvME (82), SAPE (109), OrgPE (25) — ~40 pages
MediumScholarshipsOversightProvisioningOrg Portal
Platform (35), SBE (37), RBAC (15) — ~15 pages
MediumAuditPrivacyWebhooksSubscriptionsRBAC
5.2 Delivery Sequence
- Phase 1 must come first — without the shell, nothing else has a home.
- Phase 2 before Phase 3 — you need students and staff before you can grade or schedule them.
- Phase 3 before Phase 4 — academic structure must exist before fees and timetables.
- Phase 4 and Phase 5 can run in parallel — independent domains.
- Phase 6 can run in parallel with Phase 5 — messaging is independent.
- Phase 7 after Phase 4 — scholarships need fee engine, oversight needs school data.
- Phase 8 last — admin/platform features.
6. Phase 1 — Shell & Navigation
Goal: A logged-in school admin clicks a school card on UADE and lands in a functional school dashboard shell with RBAC-filtered sidebar navigation and a school overview page.
6.1 Deliverables
| # | Deliverable | Description |
| 1.1 | Tenant Context Provider | React context wrapping all school routes. Sets X-Tenant-Id header on every API call. Exposes tenantId, iscedLevels, educationSystemCodes, boardingType, permissions[], featureGates[]. |
| 1.2 | School Dashboard Layout | /dashboard/school/[tenantId]/ — sidebar + top bar + content area. Sidebar collapses on mobile. |
| 1.3 | RBAC-Filtered Navigation | Sidebar menu items generated from the permission set returned by GET /uade/permissions/:tenantId. Menu items hidden when the user lacks the required permission. Feature-gated items hidden when the gate is not active. |
| 1.4 | School Overview Page | /dashboard/school/[tenantId]/overview — consumes GET /uade/dashboard/school/:tenantId. Stat cards: student count, staff count, programme count, pending fees, upcoming events, notifications. |
| 1.5 | Wire UADE enterRoute | Clicking a school card on the UADE landing navigates to /dashboard/school/<tenantId>. |
| 1.6 | Tenant Switcher | Dropdown in top bar for users with multiple school roles (fused buckets from Role Card Registry). |
6.2 API Endpoints Consumed
| Endpoint | Purpose |
| GET /uade/dashboard | Role cards with enterRoute for school navigation |
| GET /uade/permissions/:tenantId | Permission set for RBAC filtering |
| GET /uade/dashboard/school/:tenantId | School overview stats |
6.3 Navigation Menu Structure (Complete — All 257 Tags Covered)
School Dashboard (sidebar)
|
+-- Overview (school stats, quick actions)
|
+-- Students
| +-- All Students (StuLCE) (list, profile, add)
| +-- Admissions (ADME) (applications, offers, enrollment)
| +-- Guardians & Family
| +-- Class Placement
| +-- Student Groups
| +-- Transfers
| +-- ID Cards [if gate enabled]
| +-- Achievements & Awards
| +-- Appointments
| +-- Pastoral Notes
| +-- Documents
| +-- Import
| +-- Clearance [if gate enabled]
| +-- Re-enrollment
| +-- Settings → Custom fields, config, status rules
|
+-- Academics
| +-- Programmes (PME) (lifecycle, levels, progression, specializations, graduation)
| +-- Courses (CME) (catalogue, offerings, syllabus, curriculum map, topics, outcomes, materials)
| +-- Course Registration [ISCED 5+] (electives, minors, credits, waitlist, substitutions)
| +-- Syllabus (MaSyE) (master syllabus, school adoption, custom builder, review pipeline)
| +-- Settings → Programme config, course config
|
+-- Timetable (SCIE)
| +-- Grid View (weekly per level/class)
| +-- My Schedule (personal — student/teacher)
| +-- Slot Management (create, edit, approve, publish)
| +-- Conflicts (detection + resolution proposals)
| +-- Substitutions (leave coverage)
| +-- Slot Swap Board (teacher swaps)
| +-- Auto-Generate (algorithmic + DeepSeek AI)
| +-- Export (PDF, iCal/Google Calendar)
| +-- Share (public links)
| +-- Clone (term rollover)
| +-- Bell Schedule
| +-- Settings → Timetable config, swap policies
|
+-- Grading & Assessment
| +-- Dashboard
| +-- Assessments (GME) (create, manage lifecycle)
| +-- Score Entry (single, bulk, import)
| +-- Grade Computation (term, year, batch)
| +-- GPA / CGPA [ISCED 5+]
| +-- Sequences [ISCED 2-3]
| +-- Report Cards (DTGE) (generate, publish)
| +-- Grading Templates
| +-- Graduation (eligibility, promotion, cohort progression)
| +-- Online Exams (QBE + OEE) (question bank, papers, sessions)
| +-- Settings → Grade scales, categories, config
|
+-- Attendance (ATME)
| +-- Mark Attendance
| +-- Reports & Alerts
| +-- Devices (biometric)
| +-- Grading Bridge
| +-- Settings → Attendance config
|
+-- Assignments (ASME)
| +-- All Assignments
| +-- Submissions
| +-- Settings → Auto-scoring, contestation
|
+-- Finance (ACCTE/FME)
| +-- Dashboard (revenue, outstanding, collections)
| +-- Fee Structure (categories, schedules)
| +-- Billing (generate invoices)
| +-- Payments (record, receipts, pay links)
| +-- Payment Gateways (webhook status, transaction log)
| +-- Installments
| +-- Waivers
| +-- Discounts (auto-discount rules)
| +-- Debt Management
| +-- Revenue Share
| +-- Tax Configuration
| +-- Auto-Enroll on Payment
| +-- Reports
| +-- Settings → Fee config, billing policies, tax, discounts
|
+-- Wallet (WME) [if gate enabled]
| +-- Dashboard
| +-- Student Wallets
| +-- Parent Funding
| +-- Merchant Points
| +-- Catalogue
| +-- POS Transactions
| +-- Fee Bridge
| +-- Reports
| +-- Settings → Wallet config, exchange rate
|
+-- Staff (StaME)
| +-- Dashboard
| +-- Staff Directory
| +-- Onboarding
| +-- Contracts & Compensation
| +-- Qualifications & CPD
| +-- Appraisals
| +-- Documents
| +-- Leave (SCIE integration)
| +-- Status Management
| +-- Reports
| +-- Settings → Ranks, config, employment types
|
+-- Calendar & Events (SCIE)
| +-- Academic Calendar (years, terms)
| +-- Events (school events, closures)
| +-- Event RSVP & Check-In
| +-- Deadlines
| +-- Sports & Activities
| +-- Facility Booking
| +-- Settings → Calendar config, event categories, notification rules
|
+-- Messaging (MSGE)
| +-- Inbox / Conversations
| +-- Group Chats
| +-- Topics
| +-- Broadcast Channels [if gate enabled]
| +-- Settings → Auto-post config, moderation rules
|
+-- Library (LME) [if gate enabled]
| +-- Dashboard
| +-- Catalogue
| +-- Circulation
| +-- Holds & Reservations
| +-- Cards
| +-- Textbooks
| +-- Digital Resources
| +-- Reading Lists
| +-- Inventory & Stock-Take
| +-- Fines
| +-- Clearance
| +-- Reports
| +-- Settings → Config, locations, lending rules
|
+-- Health (SHME) [if gate enabled]
| +-- Dashboard
| +-- Health Records
| +-- Clinic Visits
| +-- Sickbay
| +-- Immunizations
| +-- Allergies
| +-- Dietary Restrictions
| +-- Medications
| +-- Pharmacy
| +-- Growth & Screening
| +-- Reports
| +-- Settings → Health config, enrollment gate
|
+-- Behavior (SBME) [if gate enabled]
| +-- Dashboard
| +-- Events & Summaries
| +-- At-Risk Detection (EWS)
| +-- Counseling Referrals
| +-- Rewards & Recognition
| +-- Hearings & Escalation
| +-- Behavioral Contracts
| +-- Restorative Actions
| +-- Peer Reports
| +-- Parent Feed
| +-- Settings → Categories, houses, groups, templates
|
+-- Canteen (RCM) [if gate enabled]
| +-- Dashboard
| +-- Meal Plans
| +-- Meal Sessions
| +-- Check-In
| +-- Tables & Seating
| +-- Menu Schedule
| +-- Dietary Alerts
| +-- Reports
| +-- Settings → Refectory config
|
+-- Hostel (HME) [if gate enabled, boarding]
| +-- Dashboard
| +-- Infrastructure (hostels, floors, rooms, beds)
| +-- Allocation
| +-- Exeat Permits
| +-- Inspections
| +-- Visitors
| +-- Operations
| +-- Hostel Staff
| +-- Fees
| +-- Settings → Hostel config, visiting hours
|
+-- Transport (TME) [if gate enabled]
| +-- Dashboard
| +-- Routes & Stops
| +-- Vehicles
| +-- Drivers
| +-- Student Enrollment
| +-- Schedules
| +-- Trips
| +-- Attendance
| +-- Maintenance & Inspection
| +-- Incidents
| +-- Analytics
| +-- Settings → Transport config
|
+-- Documents (DTGE)
| +-- Templates (manage, clone)
| +-- Report Card Templates
| +-- Generation (generate, preview, bulk)
| +-- Verification (QR, DAC, logs)
| +-- Settings → Document config, verification pricing, signatories
|
+-- Notifications (NSE)
| +-- Inbox
| +-- Templates (2-layer inheritance)
| +-- Channels (email, SMS, WhatsApp, push)
| +-- Provider Registry
| +-- Logs & Analytics
| +-- Settings → Preferences, channel config
|
+-- Scholarships (SCME) [if gate enabled]
| +-- Dashboard
| +-- Programs & Pools
| +-- Applications
| +-- Committee Review
| +-- Awards & Lifecycle
| +-- Disbursement
| +-- Donors & Funds
| +-- Marketplace [if sub-gate]
| +-- Academic Honors
| +-- Reports & Compliance
| +-- Settings → Scholarship config
|
+-- Exam Timetable (SCIE)
| +-- Exam Slots (create, schedule, publish, cancel)
| +-- Invigilators (assign, confirm, remove)
| +-- Clash Detection (report, resolve)
| +-- Accommodations (special needs exam accommodations)
| +-- Board Exam Registration (external exam body registration)
| +-- Settings → Exam timetable config
|
+-- Settings (Global)
+-- School Profile (SAPE) (provisioning status, academic structure)
+-- Template Banks (SAPE) (pull subjects, grading, reports from platform)
+-- Roles & Permissions (RBAC) (role management, permission assignment)
+-- Subscription & Billing (SBE)
| +-- Current Plan
| +-- Available Gates (browse + purchase)
| +-- Available Tiers (bundle comparison)
| +-- Payment History
+-- Feature Gates (SBE) (what's enabled)
+-- Privacy & Compliance (consent, deletion, export)
+-- Audit Log (all mutations, immutable)
+-- Integrations / Webhooks (outbound webhooks, API keys)
+-- Notification Preferences
Total sidebar items: ~280+ pages covering all 257 Swagger tags and 1,772 endpoints.
Organisation Dashboard (separate context — accessed from UADE):
Organisation Dashboard
+-- Organisation Overview
+-- Schools (list, add, transfer)
+-- KYC / Compliance
+-- Command Center Members
+-- Access Management
+-- Settings
7. Phase 2 — Core School Operations
7.1 Students Module StuLCE — 66 endpoints
| Page | API Endpoints | UI Components |
| Student List | GET /stulce/students (query: page, limit, levelId, programmeId, status, search) | TanStack Table, Select filters, SearchInput, Badge (status), bulk action toolbar |
| Student Profile | GET /stulce/students/:id | Tabs (identity, guardian, documents, groups, pastoral notes, achievements, appointments), Card |
| Add Student | POST /stulce/students | Multi-step Form (react-hook-form + Zod), Dialog for guardian add |
| Guardian Management | GET /stulce/guardians, POST /stulce/guardians, POST /stulce/guardian-relationships | TanStack Table, Sheet (add guardian), Select (relationship type) |
| Class Placement | GET /stulce/class-placements, POST /stulce/class-placements, PUT /stulce/class-placements/:id | DnD (dnd-kit) or TanStack Table, Select (level/class) |
| Student Groups | GET/POST/PUT/DELETE /stulce/student-groups | Card grid, Sheet (add members), Badge (group type) |
| Transfers | GET/POST/PUT /stulce/transfers | TanStack Table, Dialog (transfer wizard), Badge (status) |
| ID Cards | GET/POST /stulce/id-cards, POST /stulce/id-cards/batch | Card grid, Button (generate), batch action toolbar |
| Import | POST /stulce/import | Dropzone (react-dropzone), Preview Table, progress bar |
| Clearance | GET /stulce/clearance/:studentId | Checklist Card per department, Badge (cleared/pending) |
| Custom Fields | GET/POST/PUT/DELETE /stulce/custom-fields | TanStack Table, Dialog (field builder), Select (field type) |
| Re-enrollment | POST /stulce/re-enrollment, GET /stulce/re-enrollment/status | Wizard Form, Card (status display) |
| Achievements | GET/POST/PUT/DELETE /stulce/achievements | TanStack Table, Sheet (add achievement) |
| Appointments | GET/POST/PUT/DELETE /stulce/appointments | Calendar view or TanStack Table, Dialog (schedule) |
| Pastoral Notes | GET/POST/PUT/DELETE /stulce/pastoral-notes | Timeline view, Sheet (add note), Badge (severity) |
| Documents | GET/POST/PUT/DELETE /stulce/documents | TanStack Table, Dropzone (upload), Badge (type) |
| Status Management | GET /stulce/student-status/:studentId, PUT /stulce/student-status/:id, POST .../transition | Select (status), Dialog (confirm transition), Timeline (history) |
| Settings | GET/PUT /stulce/config | Form (react-hook-form), Switch toggles, Card sections |
7.2 Admissions Module ADME — 62 endpoints
| Page | API Endpoints | UI Components |
| Admission Dashboard | GET /adme/admissions (query: status, page, limit) | Recharts funnel, stat Cards, Badge (status) |
| Admission Sessions | POST /adme/admissions, PUT /adme/admissions/:id, GET /adme/admissions/:id | TanStack Table, Sheet (create/edit), DatePicker (window) |
| Application Config | GET/POST /adme/application-config/templates, POST .../adopt | Form builder, Accordion (sections), Switch (toggle sections) |
| Application List | GET /adme/applications (query: page, limit, status, admissionId, search) | TanStack Table, Badge (status), bulk action toolbar |
| Application Review | GET /adme/applications/:id, PUT /adme/applications/:id/review | Tabs (form data, documents, scores), Textarea (notes), Select (decision) |
| Merit Scoring | POST /adme/merit/trigger, POST /adme/merit/cutoff, GET /adme/merit/rankings | TanStack Table (ranked), Input (scores), Button (trigger/cutoff) |
| Offers | GET /adme/offers, POST .../accept, POST .../decline, POST .../revoke | TanStack Table, Badge (status), Dialog (revoke confirm) |
| Enrollment | POST /adme/enrollment/confirm, GET /adme/enrollment/placements | Wizard Form, TanStack Table (placements), Badge (status) |
| Manual Admission | POST/GET /adme/manual-admission, PUT .../approve | TanStack Table, Sheet (create), Select (reason), Dialog (approve) |
| Dismissal & Appeal | POST /adme/appeals, PUT /adme/appeals/:id/review | TanStack Table, Sheet (submit appeal), Textarea (decision note) |
| Transfer Admissions | POST/GET /adme/transfers, PUT .../approve | TanStack Table, Sheet (create), Dropzone (documents), Dialog (approve) |
7.3 Staff Module StaME — 60 endpoints
| Page | API Endpoints | UI Components |
| Staff Directory | GET /stame/staff (query: page, limit, departmentId, status, search) | TanStack Table, Badge (role/status), Avatar, SearchInput |
| Staff Profile | GET /stame/staff/:id | Tabs (identity, contracts, qualifications, CPD, appraisals, documents), Card |
| Onboarding | POST /stame/staff, POST /stame/staff/:id/contracts | Multi-step Form, DatePicker, Select (employment type, rank) |
| Contracts & Compensation | GET /stame/staff/:id/contracts, POST .../contracts, PUT /stame/contracts/:id | TanStack Table (history), Sheet (add contract), Input (salary) |
| Qualifications & CPD | GET/POST /stame/staff/:id/qualifications, POST .../cpd | TanStack Table, Sheet (add), Dropzone (certificate upload) |
| Appraisals | GET/POST/PUT /stame/appraisals | TanStack Table, Form (scoring rubric), Badge (cycle status) |
| Documents | GET/POST /stame/staff/:id/documents | TanStack Table, Dropzone (upload), Badge (type) |
| Status Management | PUT /stame/staff/:id/status, GET .../status-history | Select (status), Dialog (confirm), Timeline (history) |
| Configuration | GET/POST /stame/config/ranks, GET /stame/config | TanStack Table (ranks), Form (config), Card sections |
| Reports | GET /stame/reports/demographics, GET /stame/reports/attrition | Recharts (bar, pie), Card (stat summaries) |
8. Phase 3 — Academic Engine Modules
8.1 Programmes PME — 46 endpoints
| Page | API Endpoints | UI Components |
| Programme List | GET /pme/templates (query: educationSystemCode, iscedLevel) | Card grid or TanStack Table, Badge (ISCED level), Select (filter) |
| Programme Detail | GET /pme/lifecycles/:programmeId, GET .../level-configs | Tabs (levels, progression, curriculum), Card, Accordion |
| Programme Builder | POST /pme/lifecycles, POST .../level-configs | Multi-step Form, Select (ISCED, progression mode), Switch |
| Calendar | GET/POST /pme/calendars, POST .../term-calendars, POST /pme/cohorts | TanStack Table, DatePicker (term dates), Card (cohort) |
| Enrollment | POST /pme/enrollment/admit, POST .../bulk, GET /pme/students/:id/path | Wizard Form, TanStack Table, Badge (path status) |
| Progression | POST /pme/progression/evaluate, POST .../process, GET .../history/:pathId | Card (evaluation result), Dialog (confirm decision), Timeline |
| Graduation | POST /pme/graduation/check-eligibility, POST .../process, POST .../revoke, GET /pme/graduation | Card (eligibility), TanStack Table (records), Dialog (confirm) |
| Specializations | GET/POST /pme/specializations, POST .../declare, .../complete, .../withdraw | TanStack Table, Sheet (declare), Badge (status) |
8.2 Courses CME — 77 endpoints
| Page | API Endpoints | UI Components |
| Course Catalogue | GET /cme/courses, PUT .../version, .../approve, .../deactivate | TanStack Table, Badge (status), SearchInput, Dialog (confirm) |
| Course Offerings | GET/POST/PUT /cme/offerings, POST .../submit, .../approve, .../open | TanStack Table, Sheet (create/edit), Badge (state machine), Select (term) |
| Syllabus | GET/POST/PUT /cme/syllabi, POST .../submit, .../approve, .../publish | Tabs (topics, LOs, materials, scheme), Badge (state), rich text Editor |
| Curriculum Map | GET/POST/PUT /cme/curriculum-map, POST .../adopt | Visual tree (programme > level > course), Sheet (add entry), Badge (type) |
| Course Registration | POST /cme/registration/auto-enroll, GET .../available, POST .../select-electives | Card (credit tracker), Checkbox group (electives), Badge (status) — [ISCED 5+] |
| Minor Selection | GET /cme/minors/available, POST .../select, POST .../change | Card grid (available minors), Select, Dialog (change confirm) — [ISCED 5+] |
| Waitlist | POST /cme/waitlist/join, .../leave, .../accept, .../process | TanStack Table, Badge (position), Button (process) — [ISCED 5+] |
| Credit Recognition | POST/GET /cme/credit-recognition, POST .../review | TanStack Table, Sheet (submit), Dialog (review decision) — [ISCED 5+] |
| Substitutions | POST/GET /cme/substitution-rules, POST .../apply, POST .../approve | TanStack Table, Sheet (create rule), Dialog (approve) |
| Content & Materials | GET /cme/content/.../materials, POST/GET /cme/materials, POST .../log-access | Card grid (materials), Dropzone (upload), Badge (type) |
8.3 Master Syllabus MaSyE — 50 endpoints
| Page | API Endpoints | UI Components |
| Master Syllabus Browser | GET /masye/master (query: countryCode, educationSystemCode, subjectCode, iscedLevel, status, search) | TanStack Table, Select filters (country, system, subject), Badge (status) |
| Syllabus Detail | GET /masye/master/:id | Tabs (papers, topics, objectives, weights), Accordion (topic tree) |
| School Adoption | GET /masye/adoption/available, POST .../adopt, GET .../status/:courseId, POST .../sync, POST .../detach | Card (adoption status), Button (adopt/sync/detach), Badge (stale/current) |
| Custom Builder | POST /masye/builder/custom, POST .../submit, POST .../import-csv, GET .../quality-score/:id | Multi-step Form, Dropzone (CSV), Progress (quality score) |
| Review Pipeline | GET /masye/review/queue, POST .../approve, .../reject, .../promote | TanStack Table, Dialog (approve/reject), Textarea (feedback) |
8.4 Grading GME — 103 endpoints
| Page | API Endpoints | UI Components |
| Assessment Manager | GET/POST/PUT /gme/assessments, POST .../activate | TanStack Table, Sheet (create), Badge (state: DRAFT→ACTIVE→SCORING→RELEASED→FINALIZED) |
| Score Entry | POST /gme/scores/bulk, PUT /gme/scores/:id, POST /gme/scores/import | Spreadsheet-style TanStack Table (editable cells), Input (score), bulk paste |
| Grade Computation | POST /gme/compute/term-grade, .../batch-term-grades, .../year-grades, .../student-summary, .../class-ranking | Button (trigger computation), Card (results), TanStack Table (rankings) |
| GPA / CGPA | POST /gme/compute/cumulative-gpa, GET .../academic-standing/:studentId | Card (GPA display), Badge (honors: Summa/Magna/Cum Laude) — [ISCED 5+] |
| Sequences | GET/POST/PUT /gme/sequences | TanStack Table, Form — [ISCED 2-3 only] |
| Report Cards | POST /gme/reports/report-card, .../batch-report-cards, GET .../report-cards, POST .../publish | TanStack Table, Button (generate/batch), Badge (published), Dialog (publish) |
| Grading Config | GET/PUT /gme/school-grading-config, GET/POST /gme/grade-scales, POST .../grade-scale-entries, GET .../assessment-categories | Form (config), TanStack Table (scales, entries), Sheet (add) |
| Graduation | POST /gme/graduation/check-eligibility, .../batch-check, .../finalize-promotion, .../progress-cohort, .../dismiss | Card (eligibility), TanStack Table (batch), Dialog (confirm), Select (decision) |
| Online Exams (OEE) | POST /gme/oee/sessions, .../activate, .../close, .../start, .../submit, GET .../results, .../analytics | Card (session), Timer, Radio/Checkbox (MCQ), Textarea (essay), TanStack Table (results), Recharts (analytics) |
8.5 Question Bank QBE — 20 endpoints
| Page | API Endpoints | UI Components |
| Question Bank | GET/POST/PUT /qbe/questions, POST .../retire, .../clone, .../bulk-import | TanStack Table, Sheet (create/edit), Select (type, difficulty, Bloom's), Badge (status) |
| Exam Papers | GET/POST /qbe/papers, POST .../questions, .../auto-generate, .../publish, GET .../printable, .../marking-guide | TanStack Table, DnD (question ordering), Form (auto-generate rules), Badge (status), Button (print/marking guide) |
| Audit Logs | GET /qbe/audit-logs (query: paperId) | TanStack Table (read-only), Badge (action type) |
8.6 Attendance ATME — 28 endpoints
| Page | API Endpoints | UI Components |
| Mark Attendance | POST /atme/lesson, /school-day, /hostel, /staff, /activity, /refectory | Checkbox grid (per student), Select (event type, status), DatePicker |
| Reports & Stats | GET /atme/records, GET /atme/stats/:studentId | Recharts (attendance rate), TanStack Table, Card (per-student stats) |
| Alerts | POST/GET/PUT/DELETE /atme/alert-rules | TanStack Table, Sheet (create rule), Select (trigger condition) |
| Devices | POST/GET/PUT /atme/devices, GET .../vendors, .../device-models, POST .../ingest | TanStack Table, Sheet (register device), Select (vendor/model), Badge (status) |
| Grading Bridge | POST /atme/grading/compute, GET .../bridges, POST .../exam-gate-override, GET .../exam-eligibility/:studentId | TanStack Table, Button (compute), Dialog (override), Badge (eligible/blocked) |
| Config | POST /atme/event-definitions/seed, GET .../event-definitions, GET/PUT /atme/config | Form (config), TanStack Table (event defs), Switch toggles |
8.7 Assignments ASME — 21 endpoints
| Page | API Endpoints | UI Components |
| Assignment List | GET/POST/PUT/DELETE /asme/assignments | TanStack Table, Badge (state: DRAFT→PUBLISHED→CLOSED→RELEASED→FINALIZED→GRADED) |
| Assignment Detail | GET /asme/assignments/:id, POST .../transition, .../release, .../finalize, GET .../stats | Tabs (detail, submissions, stats), Card (stats), Badge (state) |
| Create Assignment | POST /asme/assignments | Form (react-hook-form + Zod), Textarea (description), Dropzone (files), Input (points, MCQ answer key), DatePicker |
| Submissions | POST .../submit, GET .../submissions, GET /asme/my-submission/:assignmentId | TanStack Table, Dropzone (submit), Badge (late/on-time) |
| Scoring | POST /asme/submissions/:id/score, POST .../bulk-score, POST .../auto-score | Spreadsheet-style TanStack Table (editable), Input (score, feedback), Button (auto-score MCQ) |
| Contestation | POST .../contest, POST .../resolve-contestation | Dialog (contest form), Badge (status), Textarea (reason), Select (resolution) |
9. Phase 4 — Financial & Administrative
9.1 Fees & Billing ACCTE/FME — 98 endpoints
| Page | API Endpoints | UI Components |
| Finance Dashboard | GET /accte/dashboard, GET /accte/finance/revenue, GET /accte/finance/transactions | Recharts (revenue/collection), stat Cards, TanStack Table (transactions) |
| Fee Structure | POST /accte/fee-categories, GET /accte/fee-categories, POST /accte/fee-schedules, GET /accte/fee-schedules, POST .../publish | TanStack Table, Sheet (create category/schedule), Badge (DRAFT/PUBLISHED) |
| Billing | POST /accte/invoices/generate, POST .../custom, GET /accte/invoices, GET .../:id, POST .../cancel | TanStack Table, Button (batch generate), Sheet (custom invoice), Badge (status) |
| Payments | POST /accte/payments/initiate, .../manual, .../bank-deposit, GET /accte/payments, GET .../receipt, POST /accte/pay-links, POST .../pay/:token | TanStack Table, Sheet (record payment), Dialog (receipt), Badge (method) |
| Installments | POST /accte/installments, GET /accte/installments, POST .../pay, POST .../cancel | TanStack Table, Sheet (create plan), Progress (payment progress) |
| Waivers | POST /accte/waivers, GET /accte/waivers, POST .../revoke | TanStack Table, Sheet (create waiver), Badge (active/revoked) |
| Discounts | POST/GET/PUT/DELETE /accte/discount-config | TanStack Table, Sheet (create rule), Select (type: sibling/staff-child) |
| Debt Management | PUT /accte/debt/config, GET .../config, GET .../clearance/:studentId, POST .../write-off, GET /accte/debt | TanStack Table, Form (config), Badge (hold type), Dialog (write-off confirm) |
| Revenue Share | GET /accte/admin/rev-share/ledger, POST .../platform-invoices/generate, GET .../platform-invoices, GET .../standing | TanStack Table, Recharts (revenue split), Badge (standing) |
| Tax Config | POST/GET/PUT /accte/tax-config | TanStack Table, Sheet (create), Select (inclusive/exclusive) |
| Auto-Enroll | POST/GET/PUT /accte/auto-enroll-config | TanStack Table, Sheet (create rule), Select (fee category → service) |
9.2 Student Wallet ACCTE/WME — 53 endpoints
| Page | API Endpoints | UI Components |
| Wallet Dashboard | GET /accte/wallet (query: page, limit, status), GET .../balance | Stat Cards (balance/hold/available), TanStack Table (wallets) |
| Student Wallets | POST /accte/wallet, GET .../:studentId, POST .../freeze, POST .../unfreeze, PUT .../limits | TanStack Table, Sheet (create), Badge (active/frozen/suspended), Dialog (freeze) |
| Parent Funding | POST /accte/wallet/funding/top-up, .../bank-deposit, .../verify, .../parent-account | TanStack Table (deposits), Sheet (top-up), Badge (pending/verified) |
| Merchant Points | POST/GET/PUT /accte/wallet/merchants, POST .../operators | TanStack Table, Sheet (create merchant), Badge (type) |
| Catalogue | POST/GET /accte/wallet/merchants/:merchantId/catalogue | TanStack Table, Sheet (add item), Input (price) |
| POS Transactions | POST /accte/wallet/pos/purchase, POST .../refund, GET .../merchant/:id | TanStack Table, Sheet (purchase), Dialog (refund) |
| Fee Bridge | POST /accte/wallet/fee-bridge/pay, GET .../check | Card (pre-check), Button (pay from wallet), Badge (sufficient/insufficient) |
| Reports | GET /accte/wallet/reports/spending, .../top-ups, .../merchant-revenue, .../wallet-summary | Recharts (spending analysis), Card (summary), TanStack Table |
| Config | GET/PUT /accte/wallet/config | Form (react-hook-form), Input (exchange rate, points label) |
9.3 Scheduling & Timetable SCIE — 160 endpoints
| Page | API Endpoints | UI Components |
| Academic Calendar | GET /scie/calendar (query: startDate, endDate, audienceScope), POST /scie/events, POST .../publish, POST /scie/closures, GET /scie/public-holidays | Calendar view (month/week), Card (event), Badge (type), DatePicker |
| Event RSVP | POST /scie/rsvp/invite, POST .../respond, GET .../attendees/:eventId, GET .../my/:eventId | TanStack Table (attendees), Badge (accepted/declined/tentative), Button (respond) |
| Class Timetable | GET /scie/timetable/slots (query: gridId, levelId, termId), POST .../slots, PUT .../slots/:id, POST .../submit, .../approve, .../publish | Grid view (day x period), DnD (dnd-kit), Badge (DRAFT→SUBMITTED→APPROVED→PUBLISHED), Select (level/term) |
| My Schedule | GET /scie/timetable/my/lecturer, .../student, .../availability | Weekly grid (read-only), Card (slot detail), Badge (course) |
| Timetable Conflicts | GET /scie/timetable/conflicts, POST .../resolve, POST .../dismiss | TanStack Table, Badge (severity: hard/soft), Dialog (resolve/dismiss) |
| Substitutions | GET /scie/timetable/substitutions/needed, POST .../assign, POST .../approve | TanStack Table, Sheet (assign substitute), Badge (covered/uncovered) |
| Slot Swap Board | POST /scie/timetable/swaps, GET .../swaps, POST .../approve, POST .../reject | TanStack Table, Sheet (request swap), Badge (pending/approved), Select (one-off/permanent) |
| Auto-Generate | POST /scie/timetable/generate/algorithmic, POST .../ai, GET .../logs | Form (constraints), Button (generate), Progress, TanStack Table (logs) |
| Export | POST /scie/timetable/export/pdf, POST .../ical, POST .../share | Button (download PDF/iCal), Dialog (share link), Input (share URL) |
| Exam Timetable | GET/POST/PUT /scie/exams, POST .../publish, POST .../invigilators | TanStack Table, Sheet (create slot), Select (room/invigilator), Badge (published) |
| Staff Leave | POST /scie/staff-leave, GET .../staff-leave, POST .../approve, POST .../reject | TanStack Table, Sheet (submit request), Badge (status), Calendar view |
| Facilities | GET/POST /scie/facilities, GET .../availability, POST .../bookings | TanStack Table, Calendar (availability), Sheet (book), Badge (type) |
| Deadlines | POST /scie/deadlines, POST .../extend, POST .../cancel, POST .../mark-passed | TanStack Table, DatePicker, Badge (active/passed/cancelled) |
9.4 Documents DTGE — 38 endpoints
| Page | API Endpoints | UI Components |
| Template Manager | GET/POST/PUT /dtge/templates, POST .../clone/:id | TanStack Table, Sheet (create/edit), CodeEditor (HTML), Badge (system/custom) |
| Report Card Templates | POST /dtge/report-templates/seed, POST/PUT/GET /dtge/report-templates, GET .../preview | TanStack Table, Form (zones/config), Dialog (preview), Badge (active) |
| Generate Documents | POST /dtge/generate, GET /dtge/documents, GET .../:id, POST .../bulk, POST .../publish, POST .../preview | TanStack Table, Button (generate/batch), Dialog (preview), Badge (pending/ready), Select (type) |
| Verification | GET /dtge/verify/:documentId/:shortHash (@Public), POST .../initiate, POST .../authorize, GET .../log | Card (verification result), TanStack Table (log), Badge (status) |
| Config | GET/PUT /dtge/config, GET/PUT .../report, POST .../pricing, POST .../signatories | Form (school config), TanStack Table (signatories/pricing), Dropzone (logo) |
10. Phase 5 — Student Welfare & Operations
10.1 Health SHME — 72 endpoints
| Page | API Endpoints | UI Components |
| Health Records | GET /shme/health-records (query: studentId, page, limit), POST .../health-records, GET .../:id, PUT .../:id | TanStack Table, Sheet (create/edit), Tabs (conditions, contacts, blood type) |
| Clinic Visits | GET /shme/clinic-visits (query: date, page, limit), POST .../clinic-visits, PUT .../:id | TanStack Table, Sheet (log visit), Select (triage, disposition), Badge (severity) |
| Sickbay | GET /shme/sickbay, POST .../admit, POST .../discharge, GET .../beds | Card grid (beds), Badge (occupied/available), Dialog (admit/discharge) |
| Immunizations | GET /shme/immunizations (query: studentId), POST .../immunizations, PUT .../:id | TanStack Table, Sheet (record), Badge (complete/due/overdue), DatePicker |
| Allergies | GET/POST/PUT/DELETE /shme/allergies | TanStack Table, Sheet (add), Select (type: food/environmental/medical), Badge (severity) |
| Dietary Restrictions | GET/POST/PUT /shme/dietary | TanStack Table, Sheet (add), Select (type: halal/vegetarian/etc.) |
| Medications | GET/POST/PUT /shme/medications | TanStack Table, Sheet (add), Input (dosage, frequency) |
| Pharmacy | GET /shme/pharmacy/inventory, POST .../dispense, POST .../restock, GET .../log | TanStack Table (inventory), Sheet (dispense), Badge (stock level), Input (quantity) |
| Growth & Screening | GET /shme/growth/:studentId, POST .../growth, GET .../enrollment-gate/:studentId | Recharts (growth chart), Card (BMI), Badge (gate: pass/fail) |
| Config | GET/PUT /shme/config | Form (react-hook-form), Input (capacity, hours), Switch toggles |
10.2 Behavior & EWS SBME — 88 endpoints
| Page | API Endpoints | UI Components |
| Behavior Dashboard | GET /sbme/events/summary/:studentId, GET /sbme/analytics | Recharts (trends, category breakdown), stat Cards, TanStack Table (recent events) |
| Events | POST /sbme/events, POST .../bulk, GET .../events (query: studentId, termId, page, limit), POST .../void | TanStack Table, Sheet (record event), Select (category, polarity), Badge (positive/negative) |
| Categories | GET/POST/PUT /sbme/categories, POST .../seed | TanStack Table, Sheet (create), Switch (active), Badge (polarity) |
| EWS Dashboard | GET /sbme/ews/dashboard, GET .../trends, POST .../run-detection | Recharts (signal trends), stat Cards (by severity), Badge (WATCH/CONCERN/CRITICAL) |
| At-Risk Alerts | GET /sbme/at-risk, POST .../acknowledge, POST .../resolve, POST .../evaluate/:studentId | TanStack Table, Badge (severity), Dialog (acknowledge/resolve) |
| Counseling | POST /sbme/counseling, GET .../counseling, PUT .../accept, PUT .../close | TanStack Table, Sheet (create referral), Badge (state: PENDING→ACCEPTED→IN_PROGRESS→COMPLETED) |
| Escalation & Hearings | POST /sbme/escalations/pathways, POST .../escalate, POST .../resolve, POST .../hearing, POST .../outcome | TanStack Table, Sheet (escalate), Dialog (hearing outcome), Badge (status), Textarea (defense/notes) |
| Contracts | POST /sbme/contracts, GET .../contracts, POST .../sign, POST .../review | TanStack Table, Sheet (create), Badge (unsigned/active/completed), Checkbox (conditions) |
| Rewards | GET /sbme/rewards, POST .../rewards, POST .../award, GET .../recognition-board | Card grid (recognition board), Sheet (award), Badge (milestone) |
| Config | GET/PUT /sbme/config, GET/POST /sbme/houses, POST /sbme/templates/apply | Form (config), TanStack Table (houses, groups), Select (template) |
10.3 Library LME — 95 endpoints
| Page | API Endpoints | UI Components |
| Library Dashboard | GET /lme/reports/dashboard | Recharts (circulation), stat Cards (in-circulation, overdue, holds) |
| Catalogue | GET /lme/catalogue (query: search, page, limit), POST .../catalogue, PUT .../:id, POST .../import, GET .../search (@Public OPAC) | TanStack Table, Sheet (add), SearchInput, Dropzone (bulk import), Badge (type) |
| Circulation | POST /lme/circulation/checkout, .../return, .../renew/:id, .../bulk-checkout, GET .../patron-status/:studentId | TanStack Table, Sheet (checkout: scan barcode), Badge (status), Card (patron summary) |
| Holds | POST /lme/holds, GET .../patron/:studentId, POST .../cancel, .../fulfill, .../process-expired | TanStack Table, Badge (WAITING/READY/FULFILLED), Button (fulfill/cancel) |
| Cards | POST /lme/cards, GET .../cards, POST .../suspend, .../lift-block, .../replace, .../renew, .../revoke | TanStack Table, Sheet (issue card), Badge (ACTIVE/SUSPENDED/REVOKED) |
| Textbooks | POST /lme/textbooks, GET .../textbooks, POST .../assign, .../bulk-assign, .../return, .../report-lost | TanStack Table, Sheet (assign), Badge (DISTRIBUTING/COMPLETED), Dialog (report lost) |
| Fines | POST /lme/fines, GET .../patron/:studentId, POST .../waive, .../reconcile, GET .../summary | TanStack Table, Sheet (manual fine), Button (waive), Badge (PENDING/PAID/WAIVED) |
| Stock-Take | POST /lme/stock-take, POST .../scan, .../bulk-scan, .../reconcile, .../complete | Progress (scanned/expected), TanStack Table (entries), Input (barcode scan), Badge (status) |
| Config | GET/POST/PUT /lme/config | Form, Switch (feature toggles), Input (loan days, max items) |
10.4 Hostel HME — 57 endpoints
| Page | API Endpoints | UI Components |
| Infrastructure | POST /hme/hostels, GET .../hostels, POST .../rooms, POST .../beds, GET .../occupancy | Accordion (hostel > room > bed tree), Badge (occupancy %), Sheet (add) |
| Allocation | POST /hme/allocations, POST .../auto, PUT .../reassign, POST .../end | TanStack Table, Sheet (allocate), Select (hostel/room/bed), Badge (ACTIVE/VACATED), Switch (dryRun) |
| Exeat | POST /hme/exeat, GET .../exeat, POST .../approve, POST .../confirm-return, GET .../overdue | TanStack Table, Sheet (submit), DatePicker, Badge (PENDING→APPROVED→RETURNED), Badge (overdue) |
| Inspections | POST /hme/inspections, POST .../findings, POST .../cancel | TanStack Table, Sheet (schedule), Form (findings), Badge (PASS/FAIL), Select (rating) |
| Visitors | POST /hme/visitors/sign-in, POST .../sign-out, GET .../active/:hostelId | TanStack Table, Sheet (sign-in), Badge (signed-in/signed-out) |
| Staff | POST /hme/staff/managers, POST .../captains, GET .../managers, POST .../remove | TanStack Table, Sheet (assign), Select (hostel/room), Badge (role) |
| Fees | GET/POST/PUT /hme/fees | TanStack Table, Sheet (set fee), Select (cascade level: bed/room/hostel) |
10.5 Canteen RCM — 32 endpoints
| Page | API Endpoints | UI Components |
| Meal Plans | POST /rcm/meal-plans, GET .../meal-plans, PATCH .../:id, DELETE .../:id, POST .../assign | TanStack Table, Sheet (create), Select (meal types, days), Input (price) |
| Student Plans | GET /rcm/students/:id/meal-plans, POST /rcm/bulk-assign, PATCH .../suspend, PATCH .../resume | TanStack Table, Button (bulk assign boarders), Badge (ACTIVE/SUSPENDED) |
| Meal Sessions | POST /rcm/sessions, GET .../sessions (query: date, mealType, page, limit), PATCH .../open, PATCH .../close | TanStack Table, Badge (SCHEDULED→OPEN→CLOSED), Button (open/close) |
| Check-In | POST /rcm/sessions/:id/check-in, GET .../check-ins | TanStack Table (check-ins), Input (student scan), Badge (entitlement/wallet/complimentary), Alert (dietary) |
| Tables | POST /rcm/tables, GET .../tables, PATCH .../:id, POST .../assign | TanStack Table, Sheet (create), Input (capacity) |
| Reports | GET /rcm/reports/meal-attendance, .../plan-uptake, .../dietary-summary | Recharts (consumption), Card (stats), TanStack Table |
| Config | GET/PUT /rcm/config | Form (react-hook-form), Select (charge source) |
10.6 Transport TME — 62 endpoints
| Page | API Endpoints | UI Components |
| Routes & Stops | GET/POST/PUT /tme/routes, POST .../stops, DELETE .../stops/:stopId | TanStack Table, Sheet (create route), DnD (stop ordering), Badge (active) |
| Vehicles | GET/POST/PUT/DELETE /tme/vehicles | TanStack Table, Sheet (register), Badge (status), Input (capacity, registration) |
| Drivers | GET/POST/PUT /tme/drivers, POST .../assign | TanStack Table, Sheet (create), Dropzone (license upload), Select (route assignment) |
| Enrollment | POST/GET/PUT/DELETE /tme/enrollment | TanStack Table, Sheet (enroll student), Select (route/stop) |
| Trips | POST/GET/PUT /tme/trips | TanStack Table, Sheet (log trip), DatePicker, Badge (status) |
| Incidents | POST/GET/PUT /tme/incidents | TanStack Table, Sheet (report), Textarea (description), Badge (severity) |
| Maintenance | POST/GET/PUT /tme/maintenance | TanStack Table, Sheet (schedule), DatePicker, Badge (due/overdue) |
| Analytics | GET /tme/analytics/routes, .../enrollment, .../fleet | Recharts (route usage, enrollment trends), Card (stats) |
11. Phase 6 — Communication & Collaboration
11.1 Notifications NSE — 30 endpoints
| Page | API Endpoints | UI Components |
| Inbox | GET /nse/inbox (query: page, limit), POST .../:id/read, POST .../read-all, GET .../unread-count | TanStack Table, Badge (unread), Button (mark all read) |
| Templates | GET/POST/PUT /nse/templates, POST .../preview | TanStack Table, Sheet (create/edit), Tabs (email/sms/push/inApp preview) |
| Channels | POST/GET/PUT /nse/channels, POST .../test | TanStack Table, Sheet (configure), Select (type: email/SMS/WhatsApp/push), Badge (active) |
| Providers | GET /nse/providers | Card grid (available providers), Badge (configured/not) |
| Preferences | GET/PUT /nse/preferences | Form (per-channel switches), Note (email/inApp cannot be disabled) |
| Analytics | GET /nse/logs (query: channel, status, startDate, endDate), GET /nse/analytics, GET .../sms-cost | Recharts (delivery matrix), TanStack Table (logs), Card (cost report) |
11.2 Messaging MSGE — 33 endpoints
| Page | API Endpoints | UI Components |
| Conversations | GET /msge/conversations, POST .../conversations, GET .../:id | List sidebar + chat panel (resizable-panels), Avatar, Badge (unread), Input (compose) |
| Messages | POST /msge/messages, GET .../messages (query: conversationId, cursor, limit), PUT .../edit, POST .../read | Message list (cursor pagination), Textarea (compose), Button (send), WebSocket (real-time) |
| Topics | POST /msge/topics, GET .../:conversationId, PUT .../:id | Tabs (per topic), Badge (write permission), Select (permission level) |
| Participants | POST/PUT/DELETE /msge/participants | TanStack Table, Sheet (add), Select (role: OWNER/ADMIN/MEMBER/READONLY) |
| Auto-Post Config | GET /msge/auto-post, PUT .../:id, POST .../seed, POST .../reset | TanStack Table, Switch (enable/disable per event), Badge (event source) |
| Admin Moderation | POST /msge/admin/pin/:messageId, DELETE .../:messageId, GET .../search, GET .../stats, POST .../broadcast | SearchInput (admin search), TanStack Table, Button (pin/delete), stat Cards |
12. Phase 7 — Advanced & Cross-Engine
12.1 Scholarships SCME — 91 endpoints
| Page | API Endpoints | UI Components |
| Programs & Pools | GET/POST/PUT /scme/programs, POST .../pools | TanStack Table, Sheet (create), Form (eligibility criteria), Badge (active/closed) |
| Applications | POST /scme/applications, GET .../applications (query: programId, status, page, limit), POST .../shortlist | TanStack Table, Badge (status), Button (bulk shortlist) |
| Committee Review | POST /scme/committees, POST .../reviewers, POST .../reviews, POST .../consensus | TanStack Table (reviewers), Form (scoring), Badge (quorum met/not), Dialog (consensus) |
| Awards | POST /scme/awards/reserve, POST .../confirm, .../activate, .../revoke, .../renew | TanStack Table, Badge (state: RESERVED→CONFIRMED→ACTIVE→COMPLETED), Dialog (revoke/renew) |
| Disbursement | POST /scme/disbursements/schedule, POST .../record, POST .../fail | TanStack Table, Progress (installments paid), Badge (status), Button (record) |
| Donors & Funds | GET/POST/PUT /scme/funds, POST .../contribute | TanStack Table, Sheet (create), Input (amount), Badge (type: endowment/annual) |
| Marketplace | POST /scme/marketplace/proposals, PUT .../submit, POST .../review, GET .../matchmaking | TanStack Table, Sheet (submit proposal), Dialog (review), Card (matchmaking suggestions) |
| Sponsorship | POST /scme/sponsorships/consent, POST .../profiles, POST .../publish, GET .../match | TanStack Table, Form (consent), Card (profile), Badge (published/private) |
| Academic Honors | POST /scme/honors/types, POST .../compute, POST .../certificate | TanStack Table, Form (threshold criteria), Button (compute), Badge (honor type) |
| Reports | POST /scme/reporting/donor-report, GET .../program-analytics/:programId | Recharts (funnel, disbursement), Card (impact summary), Button (generate PDF) |
12.2 Oversight OvME — 82 endpoints
| Page | API Endpoints | UI Components |
| Jurisdiction | POST /ovme/jurisdiction, GET .../subtree, .../country-tree, POST .../assign-schools, GET .../stats | Tree view (iterative BFS), TanStack Table (schools), stat Cards, DnD (school assignment) |
| Oversight Bodies | POST /ovme/bodies, POST .../officers, POST /ovme/access/grant, POST .../revoke | TanStack Table, Sheet (create), Select (access level: VIEWER/ADMIN), Badge (active) |
| Dashboard | GET /ovme/dashboard/overview/:jurisdictionId, .../attendance, .../academic, .../enrollment, .../finance | Tabs (9 views), Recharts (per-school comparison), stat Cards, TanStack Table |
| Compliance | POST /ovme/compliance/frameworks, POST .../categories, POST .../items | Accordion (framework > category > items), Sheet (create), Input (maxScore), Switch (isRequired) |
| Inspections | POST/PUT /ovme/inspections, POST .../advance-status, POST .../findings, POST .../corrective-actions | TanStack Table, Sheet (schedule), Form (findings), Badge (SCHEDULED→IN_PROGRESS→CLOSED), Timeline (actions) |
| Analytics | GET /ovme/analytics/compare-schools, .../gender-analysis, .../rankings, .../outliers | Recharts (comparison bar, GPI), TanStack Table (rankings), Badge (outlier) |
| Alerts | GET /ovme/alerts, POST .../acknowledge, POST .../escalate, POST .../threshold | TanStack Table, Badge (severity), Dialog (acknowledge/escalate), Form (threshold config) |
12.3 School Provisioning SAPE — 109 endpoints
| Page | API Endpoints | UI Components |
| Provisioning Status | POST /sape/provision, GET .../status | Card (route 1/2/3 status), Progress (steps completed), Badge (complete/pending) |
| Academic Structure | POST /sape/academic/faculties, GET .../faculties, POST .../departments, .../subjects, .../programmes, .../levels, .../courses, .../assign-dean, .../assign-hod, .../subject-teachers | Accordion (faculty > dept > subject > course tree), Sheet (create each level), Select (dean/HOD/teacher), TanStack Table |
| Calendar & Terms | POST /sape/calendar/years, GET .../years, POST .../terms, POST .../term-enrolments | TanStack Table, Sheet (create year/term), DatePicker (start/end), Badge (current) |
| Grading & Assessment | POST /sape/grading/grade-scales, GET .../grade-scales, POST .../assessment-categories | TanStack Table, Sheet (create), Input (grade entries: letter, min, max, points) |
| Facilities | POST /sape/facilities/bell-schedules, .../hostels, PUT .../report-config, POST .../document-templates, .../verification-pricing | TanStack Table, Sheet (create), Form (bell schedule times), Dropzone (logo) |
| Course Proposal | GET /sape/course-proposal, POST .../confirm, GET .../additional | Card grid (grouped by programme > level), Checkbox (select subjects), Button (confirm) |
| Template Banks | GET /sape/banks/subjects, POST .../import, GET .../grading, POST .../adopt, GET .../report-cards, POST .../clone, GET .../calendars, POST .../import | TanStack Table (browse), Button (adopt/import/clone), Badge (adopted), Dialog (confirm) |
| Platform Seed | POST /sape/seed/subjects, POST .../profiles, POST .../grading | Button (seed), TanStack Table (results), Badge (seeded) — platform admin only |
12.4 Organisation Portal OrgPE — 25 endpoints
NOTE: This is a SEPARATE dashboard context from the school dashboard, accessed from UADE via /dashboard/org/[orgId]/.
| Page | API Endpoints | UI Components |
| Access Dashboard | GET /org/access-dashboard | Card grid (schools + orgs), stat Cards (school count, member count) |
| Context Switch | POST /org/switch-context | Select (school/org), Badge (role in each) |
| Org Overview | GET /org/organizations/:id, GET .../dashboard | stat Cards, TanStack Table (schools), Badge (KYC status) |
| Organisation CRUD | POST/GET/PUT /org/organizations | TanStack Table, Sheet (create), Form (name, slug, settings) |
| School List | GET /org/organizations/:id/schools, POST .../schools | TanStack Table, Sheet (add school), Badge (status) |
| School Access | POST /org/school-access/grant, .../revoke, GET .../school-access, PUT .../role | TanStack Table, Sheet (grant), Select (role), Dialog (revoke confirm) |
| CC Members | POST /org/cc-access/invite, .../request, .../approve/:id, .../revoke/:id, GET .../:orgId | TanStack Table, Sheet (invite), Badge (PENDING/ACTIVE), Dialog (approve/revoke) |
| KYC | POST /org/kyc/submit, GET .../status/:orgId, POST .../review/:orgId | Form (document upload), Badge (UNDER_REVIEW/APPROVED/REJECTED), Dropzone (documents) |
| School Transfers | POST /org/schools/:tenantId/detach, POST .../attach | Dialog (confirm detach/attach), Badge (independent/attached) |
| Onboarding | POST /org/onboard (@Public), GET /org/status/:orgId | Multi-step wizard Form (6 steps), Progress, Badge (status) |
13. Phase 8 — Platform Infrastructure & Settings
13.1 Audit Trail Platform — 8 endpoints
| Page | API Endpoints | UI Components |
| Audit Log | GET /audit/entries (query: userId, entityType, engine, action, startDate, endDate, page, limit), GET .../:id | TanStack Table, Select filters (engine, action, date range), Badge (action type), DatePicker |
| Audit Stats | GET /audit/stats | Recharts (by engine, by action), stat Cards (total today) |
| Audit Config | GET/PUT /audit/config | Form (retention days, excluded engines), Note (platform minimum enforced) |
| Platform Audit | GET/PUT /audit/platform-config, GET /audit/platform/entries | Same as above but cross-tenant (super admin only) |
13.2 Data Privacy & Compliance Platform — 15 endpoints
| Page | API Endpoints | UI Components |
| Consent Policies | GET/POST/PUT /privacy/policies, POST .../seed | TanStack Table, Sheet (create), Badge (mandatory/optional), Switch (active) |
| Consent Records | POST /privacy/consent, GET .../student/:studentId, GET .../status | TanStack Table, Badge (granted/declined/needs re-consent), Switch (grant/revoke) |
| Deletion Requests | POST /privacy/deletion-request, GET .../deletion-requests, PUT .../approve, PUT .../reject | TanStack Table, Badge (PENDING/PROCESSING/COMPLETED/REJECTED), Dialog (approve — shows blockers) |
| Data Export | POST /privacy/export-request, GET .../export-requests, GET .../download | TanStack Table, Button (request export), Badge (PROCESSING/READY/EXPIRED), Link (download) |
| Compliance Dashboard | GET /privacy/dashboard, GET .../compliance-report | stat Cards (consent rate, pending deletions), Recharts (per-policy rates), Card (avg deletion response time) |
13.3 Outbound Webhooks Platform — 12 endpoints
| Page | API Endpoints | UI Components |
| Subscriptions | POST/GET/PUT/DELETE /webhooks/subscriptions, GET .../:id, POST .../test | TanStack Table, Sheet (create — HTTPS URL, events), Button (test), Badge (active/paused), Switch (enable) |
| Delivery Logs | GET /webhooks/subscriptions/:id/logs (query: success, page, limit), POST .../retry | TanStack Table, Badge (success/failed), Button (retry), Badge (attempt count) |
| Event Catalogue | GET /webhooks/events | Card grid (15 event types + wildcard), Badge (category) |
| API Keys | POST /webhooks/api-keys, GET .../api-keys, POST .../revoke | TanStack Table, Button (generate — show once dialog), Badge (active/revoked) |
13.4 RBAC & Role Management RBAC — 15 endpoints
| Page | API Endpoints | UI Components |
| Permissions | GET /rbac/permissions, GET .../me, POST .../check | Accordion (grouped by module), Badge (permission key), SearchInput |
| Roles | GET/POST/PUT/DELETE /rbac/roles | TanStack Table, Sheet (create), Checkbox group (permissions), Badge (system/custom) |
| Assignment | PUT /rbac/users/:userId/role, POST /rbac/roles/bulk-assign | Select (role), Button (assign), TanStack Table (user list), Dialog (bulk assign) |
13.5 Subscription & Billing SBE — 37 endpoints
| Page | API Endpoints | UI Components |
| Current Plan | GET /sbe/tenant-subscriptions, POST .../change-tier | Card (current plan details), Badge (active), Button (change tier) |
| Feature Gates | GET /sbe/feature-gates, POST .../seed-status, PUT .../toggle | TanStack Table, Switch (toggle), Badge (active/inactive), stat Cards (seed status) |
| Tiers | GET/POST /sbe/subscription-tiers | Card grid (tier comparison), Badge (current), Button (upgrade) |
| Overrides | GET/POST /sbe/feature-overrides | TanStack Table, Sheet (create override), Select (GRANT/REVOKE), Badge (override type) |
| School Self-Service | GET /sbe/school/gates, POST .../request-upgrade, POST .../change-tier | Card grid (available gates), Button (request), Badge (enabled/locked) |
| Dashboard | GET /sbe/dashboard/overview, GET .../mrr | Recharts (MRR, gate adoption), stat Cards (subscribers, revenue) |
| Enforcement | POST /sbe/enforcement/check, POST .../invalidate-cache | Button (check gate), Badge (result), Button (invalidate cache) |
14. Module-to-Engine Mapping (Full Data)
| Frontend Module | Engine | Endpoints | Tags | Permission Namespace | ISCED Filter | Feature Gate |
| Students | StuLCE | 66 | 16 | student:* | All | Core (carve-outs: student_id_cards, student_clearance) |
| Admissions | ADME | 62 | 9 | admission:* | All | admission_management |
| Staff | StaME | 60 | 9 | staff:* | All | Core |
| Programmes | PME | 46 | 7 | programme:* | All | Core |
| Courses | CME | 77 | 16 | course:* | All (registration: 5+) | Core |
| Syllabus | MaSyE | 50 | 11 | syllabus:* | All | syllabus_management |
| Grading | GME | 103 | 9 | grading:* | All (GPA: 5+) | grading_management |
| Online Exams | QBE + GME/OEE | 45 | 4 | exam:*, qbank:* | All | online_examination + question_bank |
| Attendance | ATME | 28 | 5 | attendance:* | All | attendance_management |
| Assignments | ASME | 21 | 2 | assignment:* | All | assignment_management |
| Fees & Billing | ACCTE/FME | 98 | 13 | fee:*, finance:* | All | fee_management |
| Student Wallet | ACCTE/WME | 53 | 9 | wallet:* | All (essential: 5+) | student_wallet |
| Scheduling | SCIE | 160 | 17 | schedule:* | All | scheduling |
| Library | LME | 95 | 14 | library:* | All | library_management |
| Health | SHME | 72 | 12 | health:* | All | student_health |
| Behavior & EWS | SBME | 88 | 12 | behavior:* | All | student_behavior |
| Canteen | RCM | 32 | 1 | rcm:* | Boarding/mixed | refectory |
| Hostel | HME | 57 | 8 | hostel:* | Boarding only | hostel_management |
| Transport | TME | 62 | 10 | transport:* | All (more relevant 0-3) | transport_management |
| Documents | DTGE | 38 | 5 | document:* | All | document_generation |
| Notifications | NSE | 30 | 7 | notification:* | All | Core |
| Messaging | MSGE | 33 | 6 | messaging:* | All | messaging |
| Scholarships | SCME | 91 | 10 | scholarship:* | All | scholarships |
| Oversight | OvME | 82 | 12 | oversight:* | All | Core |
| Provisioning | SAPE | 109 | 8 | admin:* | All | Core |
| Org Portal | OrgPE | 25 | 7 | org-level RBAC | All | Core (CC gated by KYC) |
| Subscriptions | SBE | 37 | 7 | platform:* | All | Core |
| Audit | Platform | 8 | 1 | audit:* | All | Core |
| Privacy | Platform | 15 | 1 | privacy:* | All | Core |
| Webhooks | Platform | 12 | 1 | webhook:* | All | outbound_webhooks |
| RBAC | RBAC | 15 | 1 | core:* | All | Core |
15. RBAC & Permission Surface
15.1 Permission Files (21 files, 511 lines)
Top files by line count: programme.permissions.ts (96), grading.permissions.ts (60), messaging.permissions.ts (45), admission.permissions.ts (34), fee.permissions.ts (30), exam.permissions.ts (26), partner.permissions.ts (17), behavior.permissions.ts (15), core.permissions.ts (14), scheduling.permissions.ts (13), scholarship.permissions.ts (12), plus 10 more.
15.2 4-Scope RBAC Architecture
| Scope | Mechanism | Guard | Decorator |
| School | UserSchoolProfile → Role → permissions[] | RbacGuard | @RequirePermission() |
| Platform | User.platformRole string field | PlatformRbacGuard | @RequirePlatformRole() |
| Partner | PartnerAccess → static PARTNER_ROLE_PERMISSIONS | PartnerRbacGuard | @RequirePartnerPermission() |
| Organisation | OrgAccess → role (hierarchy: viewer < admin < owner) | OrgRbacGuard | @RequireOrgRole() |
15.3 Permission Inheritance
module.manage grants all actions. create/edit/approve imply view. submit implies view+create. publish implies view+approve.
15.4 How RBAC Drives Navigation
User clicks school card →
GET /uade/permissions/:tenantId →
returns { role: "Principal", permissions: ["grading:*", "student:*", "fee:*", ...] }
→ frontend filters sidebar items:
if permissions.some(p => p.startsWith("grading:")) → show Grading menu
if permissions.some(p => p.startsWith("fee:")) → show Finance menu
if permissions.includes("*") → show everything (super admin)
15.5 System Roles (20 pre-defined)
6 system roles: Super Admin, School Admin, Teacher, Accountant, Student, Parent
14 suggested roles: Principal, Vice Principal, Dean of Studies, Head of Department, Registrar, Admissions Manager, Bursar, Counselor, IT Administrator, Librarian, Hostel Warden, Canteen Manager, Nurse/Health Officer, Sports Master
16. Feature Gate Matrix
Feature gates are enforced by the FEATURE_MAP in src/rbac/constants/feature-map.ts. If a school's subscription tier does not include the gate, the API returns 403 and the frontend should hide the module.
16.1 Top-Level Gates (30)
| Gate Code | Feature | Engines Affected | Category |
| grading_management | Grading & report cards | GME | Academic |
| assignment_management | Assignments | ASME | Academic |
| online_examination | Online exam delivery | GME/OEE | Academic |
| question_bank | Question bank | QBE | Academic |
| attendance_management | Attendance tracking | ATME | Academic |
| syllabus_management | Syllabus management | MaSyE | Academic |
| fee_management | Fee & billing | ACCTE/FME | Finance |
| student_wallet | Student wallet & micropayments | WME | Finance |
| scholarships | Scholarship management | SCME | Finance |
| student_behavior | Behavior management | SBME | Operations |
| admission_management | Full admission management | ADME | Operations |
| scheduling | Timetable & calendar | SCIE | Operations |
| document_generation | Document generation | DTGE | Platform |
| hostel_management | Hostel operations | HME | Operations |
| transport_management | Transport management | TME | Operations |
| library_management | Library management | LME | Operations |
| student_health | General student health | SHME | Operations |
| refectory | Canteen management | RCM | Operations |
| messaging | Two-way messaging | MSGE | Communication |
| outbound_webhooks | Webhook integrations | Platform | Platform |
| student_id_cards | ID card generation | StuLCE | Platform |
| student_clearance | Student clearance | StuLCE | Platform |
16.2 Sub-Gates (within top-level gates)
| Sub-Gate Code | Parent Gate | Feature |
| admission_portal | admission_management | Online application portal |
| admission_merit | admission_management | Merit scoring |
| admission_transfers | admission_management | Transfer admissions |
| clinic_management | student_health | School clinic |
| pharmacy_management | student_health | School pharmacy |
| health_screening | student_health | Health screening |
| messaging_broadcast | messaging | Broadcast channels (premium) |
16.3 Frontend Implementation
const { featureGates } = useSchoolContext();
// Hide entire sidebar module
{featureGates.includes("library_management") && <LibraryNavItem />}
// Hide sub-feature within a module
{featureGates.includes("admission_merit") && <MeritScoringTab />}
// Premium sub-gate
{featureGates.includes("messaging_broadcast") && <BroadcastButton />}
17. Frontend Architecture Decisions
17.1 Technology Stack (Already Established)
| Layer | Technology | Notes |
| Framework | Next.js 14+ (App Router) | Server components for initial loads, client components for interactivity |
| UI Library | shadcn/ui + Tailwind CSS | Consistent with existing UADE dashboard |
| State Management | TanStack Query v5 | Already wired for UADE. Server state only — no Redux. |
| Forms | React Hook Form + Zod | Already used in existing form components |
| Tables | TanStack Table | For all data tables |
| Auth | NextAuth.js + Authentik | JWT bearer token flow, already working |
| API Client | Custom apiClient() / serverApiClient() | Already built in src/lib/api-client.ts. Injects Bearer + X-Tenant-Id. |
| Routing | Next.js App Router | [tenantId] dynamic segment for tenant scoping |
| URL State | nuqs (NuqsAdapter) | For filter/pagination/search state in URL |
| Command Palette | KBar | Already wired |
| Real-time | WebSocket (Socket.io) | For messaging (MSGE gateway at /messaging namespace) |
17.2 Key Architectural Patterns
Tenant Context Provider
/dashboard/school/[tenantId]/layout.tsx
→ TenantProvider (fetches permissions, iscedLevels, features)
→ SchoolSidebar (RBAC-filtered + feature-gated)
→ SchoolTopBar (tenant switcher)
→ {children}
Feature Module Pattern (per engine)
src/features/<engine>/
api/
queries.ts ← TanStack Query options (queryKey, queryFn, staleTime)
mutations.ts ← useMutation hooks for POST/PUT/DELETE
types.ts ← TypeScript interfaces matching backend DTOs
service.ts ← apiClient() calls (raw fetch wrappers)
components/
<engine>-list.tsx ← Data table with filters, search, pagination
<engine>-detail.tsx ← Detail/edit view
<engine>-form.tsx ← Create/edit form
<engine>-dashboard.tsx ← Module overview/stats
hooks/
use-<engine>.ts ← Custom hooks combining queries + mutations
constants/
columns.tsx ← Table column definitions
schemas/
<engine>.schema.ts ← Zod validation schemas
ISCED-Aware Rendering
const { iscedLevels } = useSchoolContext();
const isTertiary = iscedLevels.some(l => l >= 5);
const isSecondary = iscedLevels.some(l => l >= 2 && l <= 4);
// Conditional field
{isTertiary && <GpaDisplay studentId={id} />}
// Conditional label
<Label>{isTertiary ? "Semester" : "Term"}</Label>
// Conditional column in table
const columns = [
...baseColumns,
...(isTertiary ? [creditHoursColumn, gpaColumn] : []),
];
18. ISCED-Conditional Rendering Map
Complete map of every UI element that changes based on ISCED level:
| Module | Component | ISCED 0-2 (Primary) | ISCED 3-4 (Secondary) | ISCED 5-8 (Tertiary) |
| Programmes | Level label | "Class" / "Grade" | "Form" / "Year" | "Year" / "Level" |
| Programmes | Progression mode | Auto-promote | Exam-gated | Credit-accumulation |
| Programmes | Specializations | Hidden | Hidden | Visible (major/minor) |
| Courses | Credit hours column | Hidden | Hidden | Visible |
| Courses | Course registration | Hidden | Hidden | Full self-service |
| Courses | Waitlist / Minor / Credit recognition | Hidden | Hidden | Visible |
| Grading | Grade display | Marks /10 or /20 | Marks + letter (A-E) | GPA 0.0–4.0 |
| Grading | CGPA panel | Hidden | Hidden | Visible |
| Grading | Sequences tab | Hidden | Visible (1st, 2nd, 3rd) | Hidden |
| Grading | Graduation check | Age/completion | National exam results | CGPA + credit threshold |
| Score Entry | Score format | Numeric (0-10/20) | Numeric (0-20) | Numeric + letter grade |
| Report Cards | Format | Simple marks sheet | Marks + class rank + conduct | Transcript + GPA + credits |
| Attendance | Granularity | Per-day (full class) | Per-period (per-subject) | Per-lecture (optional) |
| Fees | Structure | Flat annual/termly | Flat + exam fees | Per-credit differential |
| Timetable | Complexity | Simple grid (1:1) | Subject rotation | Multi-section + labs |
| Student List | Guardian column | Prominent | Visible | Minimal/hidden |
| Student List | GPA column | Hidden | Hidden | Visible |
| Library | Features | Basic lending | + textbooks | + digital + reserves |
| Hostel | Visibility | Hidden (unless boarding) | Visible (if boarding) | Visible |
| Transport | Visibility | Prominent | Visible | Hidden |
| Term label | Label | "Term 1, 2, 3" | "Term 1, 2, 3" | "Semester 1, 2" |
| EWS signals | Academic signals | Minimal | 8 rules (ISCED 3-4) | 11 rules (ISCED 5-8) |
19. Route Map
Complete Next.js App Router route structure (~190 page.tsx files):
/dashboard/school/[tenantId]/
+-- page.tsx → School Overview
+-- layout.tsx → TenantProvider + SchoolSidebar + TopBar
|
+-- students/
| +-- page.tsx → Student List
| +-- [studentId]/page.tsx → Student Profile (tabbed)
| +-- new/page.tsx → Add Student Form
| +-- import/page.tsx → CSV/Excel Import
| +-- guardians/page.tsx → Guardian List
| +-- class-placement/page.tsx → Class Placement Board
| +-- groups/ | transfers/ | id-cards/ | clearance/
| +-- achievements/ | appointments/ | pastoral-notes/ | documents/
| +-- re-enrollment/ | settings/page.tsx
|
+-- admissions/
| +-- page.tsx → Admission Dashboard (funnel)
| +-- applications/page.tsx → Application List
| +-- applications/[id]/page.tsx → Application Review
| +-- config/ | merit/ | offers/ | enrollment/ | manual/ | appeals/ | transfers/
|
+-- staff/
| +-- page.tsx | [staffId]/page.tsx | new/ | contracts/ | qualifications/ | appraisals/ | documents/ | config/ | reports/
|
+-- academics/
| +-- programmes/ (page, [id], new, enrollment, progression, graduation, specializations)
| +-- courses/ (page, [id], offerings, registration, curriculum-map, curriculum-docs, substitutions)
| +-- syllabus/ (page, adoption, custom, review)
| +-- calendar/page.tsx | templates/page.tsx
|
+-- timetable/ (page, my-schedule, slots, conflicts, substitutions, swaps, generate, export, exam, bell-schedule, settings)
+-- grading/ (page, assessments, assessments/[id], scores, computation, report-cards, sequences, gpa, graduation, config, online-exams/)
+-- attendance/ (page, reports, alerts, devices, grading-bridge, config)
+-- assignments/ (page, [id], new, settings)
+-- finance/ (page, fee-structure, billing, payments, installments, waivers, discounts, debts, revenue, tax, auto-enroll, config)
+-- wallet/ [if gate] (page, wallets, funding, merchants, catalogue, pos, fee-bridge, reports, config)
+-- calendar/ (page, events, rsvp, deadlines, leave, activities, facilities, settings)
+-- messaging/ (page, conversations, [conversationId], auto-post, admin, settings)
+-- library/ [if gate] (page, catalogue, circulation, holds, cards, textbooks, digital, reading-lists, inventory, fines, clearance, reports, config)
+-- health/ [if gate] (page, records, records/[studentId], clinic, sickbay, immunizations, allergies, dietary, medications, pharmacy, growth, config)
+-- behavior/ [if gate] (page, events, at-risk, ews, counseling, hearings, contracts, restorative, peer-reports, rewards, parent-feed, config)
+-- canteen/ [if gate] (page, meal-plans, student-plans, sessions, check-in, tables, menu, reports, config)
+-- hostel/ [boarding] (page, infrastructure, allocations, exeat, inspections, visitors, operations, staff, fees, config)
+-- transport/ [if gate] (page, routes, vehicles, drivers, enrollment, schedules, trips, attendance, incidents, maintenance, analytics, settings)
+-- documents/ (page, report-templates, generate, verify, config)
+-- notifications/ (page, templates, channels, providers, devices, preferences, analytics, settings)
+-- scholarships/ [if gate] (page, programs, applications, committee, awards, disbursement, donors, marketplace, sponsorship, honors, reports, settings)
+-- settings/ (page, academic, template-banks, calendar, grading, facilities, course-proposal, roles, subscription, features, privacy, audit, webhooks, notifications)
/dashboard/org/[orgId]/ → Organisation Dashboard (separate)
+-- page.tsx | schools/ | members/ | kyc/ | access/ | settings/
/shared/ → Public routes (no auth)
+-- timetable/[token]/page.tsx → Public Timetable View
+-- verify/[code]/page.tsx → Public Document Verification (QR)
Total new routes: ~190 page.tsx files across 22 top-level sections + 1 org context + public routes.
20. Delivery Approach Options
Option A — Full Manual Build (Claude + Developer)
Method: Build every module by hand — feature module, API layer, components, forms, tables, ISCED logic.
~25 modules
~185 pages
~500+ components
Enterprise-grade, full control over every line
Best for: When quality and customization matter more than speed.
Option B — Lovable-Generated + Manual Wiring
Method: Use Lovable to rapidly generate page shells and components from mockups/descriptions, then manually wire them to the real API.
Best for: When speed of visual delivery matters most. Governance rules already in place.
Option C — Hybrid (Recommended)
- Phase 1 (Shell) — built manually. The tenant context provider, RBAC navigation, and school layout are architectural foundation. Must be built right.
- Phases 2-8 (Feature modules) — Lovable generates, developer wires. Feed Lovable the Swagger spec + mockup. Lovable generates layouts, table columns, form fields. Developer wires to real API, adds ISCED/RBAC/gate logic, QAs against live data.
Best for: Delivering a demoable product quickly while maintaining enterprise-grade API integration.
21. Risk Register
R01Feature gate enforcement missing
Schools see modules their subscription doesn't include.
@RequireFeature() guard decorator needs to be written and deployed before frontend launches.
R02ISCED rendering untested
No real university tenant exists to test ISCED 5+ features.
Create test tenants at different ISCED levels with representative data.
R03Performance at scale
Data tables with 1,000+ rows may lag.
All list endpoints support ?page=&limit= — use server-side pagination.
R04Multi-tenant data leaks
Bug in tenant context causes cross-school exposure.
X-Tenant-Id header enforced on every backend endpoint. Frontend must always set it.
22. Success Criteria
01School admin can enter dashboard — UADE enterRoute works, school overview renders with real data
02RBAC-filtered navigation — Users only see what their role permits
03Feature-gate filtered modules — Disabled gates hide modules
04Student CRUD end-to-end — Create, read, update, search, filter, paginate
05Admission pipeline flows — Apply → review → score → offer → accept → enroll
06Grading for ISCED 2 + ISCED 6 — Score entry, computation, report cards for secondary; GPA/CGPA for university
07Fee collection works — Structure → invoice → payment → receipt
08ISCED-conditional rendering — Same dashboard renders differently for primary vs. university
09Mobile-responsive — Works on tablet (1024px) and mobile (375px)
10All data tables handle scale — Server-side pagination, no client-side lag
23. Internationalization (i18n)
All user-facing text in the frontend MUST use next-intl translation functions. No hardcoded English strings in components.
23.1 Reference Document
See frontend/planning/TRANSLATION_PROTOCOL.md v1.0: next-intl + Zustand locale persistence, ICU message format for plurals/interpolation, EN + FR launch languages.
23.2 Implementation (Proof of Concept Complete)
UADE proof of concept deployed: src/i18n/config.ts, src/i18n/messages/en.json + fr.json, src/stores/locale-store.ts, src/components/language-switcher.tsx. All UADE components use useTranslations() — zero hardcoded strings.
23.3 Rules for New Modules
- Add translation keys to
en.json and fr.json under its namespace
- Import
useTranslations from next-intl in every component that renders text
- Use
t('key') for all labels, buttons, headings, placeholders, tooltips
- Use
useFormatter() for dates, numbers, currencies — never hardcode locale strings
- Use ICU format for plurals:
{count, plural, one {# item} other {# items}}
// Pattern for every component:
import { useTranslations, useFormatter } from 'next-intl';
export function StudentList() {
const t = useTranslations('students');
const tc = useTranslations('common');
const format = useFormatter();
return (
<div>
<h1>{t('title')}</h1>
<Button>{tc('actions.add')}</Button>
<span>{format.dateTime(date, { dateStyle: 'long' })}</span>
</div>
);
}
24. API Client Configuration
24.1 File Location
src/lib/api-client.ts — custom fetch wrapper used by all TanStack Query hooks.
24.2 How It Works
// Every request automatically includes:
// 1. Authorization: Bearer {accessToken} — from NextAuth session
// 2. X-Tenant-Id: {tenantId} — from TenantProvider context (Zustand)
// 3. Accept-Language: {locale} — from locale store (for backend i18n)
// 4. Content-Type: application/json
const apiClient = async (path: string, options?: RequestInit) => {
const session = await getSession();
const { tenantId } = useTenantStore.getState();
const { locale } = useLocaleStore.getState();
const res = await fetch(`${NEXT_PUBLIC_API_URL}${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${session?.accessToken}`,
'X-Tenant-Id': tenantId ?? '',
'Accept-Language': locale,
...options?.headers,
},
});
if (res.status === 401) {
signIn('authentik');
throw new Error('Session expired');
}
if (!res.ok) {
const error = await res.json().catch(() => ({}));
throw new Error(error.message || `API error: ${res.status}`);
}
return res.json();
};
24.3 Environment Variables
| Variable | Value | Purpose |
| NEXT_PUBLIC_API_URL | https://api.academia.vivabox.net | Backend API base URL |
| NEXTAUTH_URL | https://app.academia.vivabox.net | Frontend URL for NextAuth callbacks |
| AUTH_SECRET | (secret) | NextAuth encryption key |
25. Feature Gate Frontend Implementation
25.1 Gate Check in Sidebar Navigation
const navItems = [
{ label: t('nav.students'), href: '/students', icon: Icons.student, gate: null }, // core — always shown
{ label: t('nav.library'), href: '/library', icon: Icons.library, gate: 'library_management' },
{ label: t('nav.health'), href: '/health', icon: Icons.health, gate: 'student_health' },
// ...
].filter(item => !item.gate || featureGates.includes(item.gate));
25.2 Gate Check on Page Load
export default function LibraryPage() {
const { featureGates } = useSchoolContext();
if (!featureGates.includes('library_management')) {
return <FeatureLockedPage gate="library_management" />;
}
return <LibraryDashboard />;
}
25.3 Sub-Gate Check for Features Within a Module
// Show merit scoring only if the sub-gate is active:
{featureGates.includes('admission_merit') && (
<TabsTrigger value="merit">{t('admissions.meritScoring')}</TabsTrigger>
)}
// Premium messaging broadcast:
{featureGates.includes('messaging_broadcast') && (
<Button onClick={sendBroadcast}>{t('messaging.broadcast')}</Button>
)}
25.4 FeatureLockedPage Component
function FeatureLockedPage({ gate }: { gate: string }) {
const t = useTranslations('settings');
return (
<div className="flex flex-col items-center justify-center py-20 text-center space-y-4">
<Icons.lock className="size-12 text-muted-foreground" />
<h2 className="text-xl font-semibold">{t('featureGates')}</h2>
<p className="text-muted-foreground max-w-md">
This feature requires the <Badge>{gate}</Badge> subscription gate.
</p>
<Button variant="outline" asChild>
<Link href="/settings/subscription">View Subscription</Link>
</Button>
</div>
);
}
26. State Handling Patterns
26.1 Loading State (Skeleton)
function StudentListSkeleton() {
return (
<div className="space-y-4">
<Skeleton className="h-10 w-64" /> {/* search bar */}
<Skeleton className="h-8 w-full" /> {/* table header */}
{Array.from({ length: 5 }).map((_, i) => (
<Skeleton key={i} className="h-12 w-full" />
))}
</div>
);
}
26.2 Error State
function ErrorBanner({ error }: { error: Error }) {
const t = useTranslations('common');
return (
<Alert variant="destructive">
<AlertTitle>{t('error.title')}</AlertTitle>
<AlertDescription>{error.message}</AlertDescription>
<Button variant="outline" onClick={() => window.location.reload()}>
{t('actions.refresh')}
</Button>
</Alert>
);
}
26.3 Empty State
function EmptyState({ title, description, action }) {
return (
<div className="flex flex-col items-center justify-center py-16 text-center space-y-3">
<div className="bg-muted rounded-full p-4">
<Icons.inbox className="size-8 text-muted-foreground" />
</div>
<h3 className="text-lg font-semibold">{title}</h3>
<p className="text-muted-foreground text-sm max-w-md">{description}</p>
{action && <Button onClick={action.onClick}>{action.label}</Button>}
</div>
);
}
26.4 Permission Denied
function PermissionDenied() {
const t = useTranslations('common');
return (
<div className="flex flex-col items-center justify-center py-16 text-center space-y-3">
<Icons.shield className="size-12 text-muted-foreground" />
<h3>{t('error.permissionDenied')}</h3>
<p>{t('error.permissionDeniedDescription')}</p>
</div>
);
}
27. Data Table Column Specifications (Top 10 Pages)
27.1 Student List (/students)
| Column | Sortable | Filterable | Default Visible |
| Name (givenName + familyName) | Yes | Search | Yes |
| Student ID | No | No | Yes |
| Programme | Yes | Select dropdown | Yes |
| Level | Yes | Select dropdown | Yes |
| Status | Yes | Select dropdown | Yes |
| Gender | No | Select dropdown | Yes |
| Guardian | No | No | Yes (ISCED 0-4), Hidden (ISCED 5+) |
| GPA | Yes | No | Hidden (ISCED 0-4), Yes (ISCED 5+) |
| Enrollment Date | Yes | Date range | No (column toggle) |
Default sort: givenName ASC | Bulk actions: Export CSV, Change Status, Assign Group
27.2 Staff Directory (/staff)
| Column | Sortable | Filterable | Default Visible |
| Name | Yes | Search | Yes |
| Employee ID | No | No | Yes |
| Role | Yes | Select | Yes |
| Department | Yes | Select | Yes |
| Status | Yes | Select | Yes |
| Phone | No | No | Yes |
| Hire Date | Yes | Date range | No |
Default sort: givenName ASC | Bulk actions: Export CSV
27.3 Application List (/admissions/applications)
| Column | Sortable | Filterable | Default Visible |
| Applicant Name | Yes | Search | Yes |
| Programme | Yes | Select | Yes |
| Level | Yes | Select | Yes |
| Status | Yes | Select (AS_DRAFT, AS_SUBMITTED, AS_SHORTLISTED, etc.) | Yes |
| Merit Rank | Yes | No | Yes |
| Submitted At | Yes | Date range | Yes |
| Reviewer | No | Select | No |
Default sort: createdAt DESC | Bulk actions: Shortlist, Reject, Export
27.4 Invoice List (/finance/billing)
| Column | Sortable | Filterable | Default Visible |
| Invoice # | Yes | Search | Yes |
| Student | Yes | Search | Yes |
| Amount | Yes | No | Yes |
| Balance | Yes | No | Yes |
| Status | Yes | Select (DRAFT, SENT, PARTIALLY_PAID, PAID, CANCELLED) | Yes |
| Due Date | Yes | Date range | Yes |
| Programme | No | Select | No |
Default sort: createdAt DESC | Bulk actions: Send reminders, Export, Cancel
27.5 Assessment List (/grading/assessments)
| Column | Sortable | Filterable | Default Visible |
| Title | Yes | Search | Yes |
| Course | Yes | Select | Yes |
| Type | Yes | Select (CA, MIDTERM, FINAL) | Yes |
| Status | Yes | Select (DRAFT→FINALIZED) | Yes |
| Max Score | No | No | Yes |
| Scores Entered | No | No | Yes (progress bar) |
| Created At | Yes | No | No |
Default sort: createdAt DESC | Bulk actions: Activate, Release, Finalize
27.6 Timetable Slots (/timetable/slots)
| Column | Sortable | Filterable | Default Visible |
| Day | Yes | Select | Yes |
| Period | Yes | Select | Yes |
| Course | Yes | Select | Yes |
| Lecturer | Yes | Select | Yes |
| Room | Yes | Select | Yes |
| Level/Class | Yes | Select | Yes |
| Status | Yes | Select (DRAFT/APPROVED/PUBLISHED) | Yes |
Default sort: dayOfWeek ASC, periodIndex ASC | Bulk actions: Submit, Approve, Publish
27.7 Attendance Records (/attendance)
| Column | Sortable | Filterable | Default Visible |
| Student | Yes | Search | Yes |
| Date | Yes | Date range | Yes |
| Event Type | Yes | Select (LESSON, SCHOOL_DAY, etc.) | Yes |
| Status | Yes | Select (PRESENT, ABSENT, LATE, EXCUSED) | Yes |
| Course/Period | No | Select | Yes |
| Marked By | No | No | No |
Default sort: date DESC | Bulk actions: Export
27.8 Library Catalogue (/library/catalogue)
| Column | Sortable | Filterable | Default Visible |
| Title | Yes | Search | Yes |
| ISBN | No | Search | Yes |
| Author(s) | Yes | No | Yes |
| Type | Yes | Select (BOOK, JOURNAL, DIGITAL) | Yes |
| Copies (Total/Available) | Yes | No | Yes |
| Status | Yes | Select (ACTIVE, WITHDRAWN) | Yes |
Default sort: title ASC | Bulk actions: Import, Withdraw
27.9 Behavior Events (/behavior/events)
| Column | Sortable | Filterable | Default Visible |
| Student | Yes | Search | Yes |
| Category | Yes | Select | Yes |
| Polarity | Yes | Select (POSITIVE/NEGATIVE) | Yes |
| Points | Yes | No | Yes |
| Date | Yes | Date range | Yes |
| Recorded By | No | Select | No |
| Voided | No | Select | No |
Default sort: createdAt DESC | Bulk actions: Void, Export
27.10 Scholarship Applications (/scholarships/applications)
| Column | Sortable | Filterable | Default Visible |
| Applicant | Yes | Search | Yes |
| Programme | Yes | Select | Yes |
| Status | Yes | Select (SUBMITTED, SHORTLISTED, AWARDED, REJECTED) | Yes |
| Applied At | Yes | Date range | Yes |
| GPA | Yes | No | Yes |
| Committee Score | Yes | No | No |
Default sort: createdAt DESC | Bulk actions: Shortlist, Reject
Generated: 2026-04-15 | Academia V2.1 | School Admin Dashboard Build Plan v2.1
Source of truth: demofox VPS (77.237.247.146)
Backend: 30+ engines, 1,772 endpoints, 401 models, 327 enums, 257 Swagger tags, 3,607 tests — all green
Frontend: 285 files, 31 routes, 1 engine connected — build starts from here
Supersedes: v1.0 (2026-04-10) which was written against 1,548 endpoints and missed 7 entire modules