Raisd campus — what we are building
Plain-language overview of the Raisd portals, how they sit on the existing campus CMS, where we are today, where we are going, and the migration stages to get there. Pilot project: Lesotho (Working Group, 3 Oct 2026) — first acceptance campus; newer CMS screenshots are the feature benchmark. See Lesotho feature analysis. Technical diagrams and SDD detail live one click away.
Project progress (high level)
Snapshot for sponsor weekly % reporting. Checklist Live from SDD-13 (sheet 19 Sep 2026). FE Demo depth and platform readiness include engineering work through 7 Oct 2026 (Schema v4, Applicant Demo HTTP, Lesotho inventory). Live = 0% until durable CMS-backed journeys pass acceptance. Week-by-week narrative: Reports (W01–W04 from 18 Sep).
Bar — milestone progress %
Frontend started vs estimated platform readiness (not Live).
| Milestone | FE started | Platform readiness | What the percentages mean |
|---|---|---|---|
| M1 Confirm rules & integration | 0% | ~50% | Almost no frontend rows on the sheet (operating / rules milestone). Platform ~50% reflects ADR-1, Schema v4 Demo, CAP-53 Partial, and architecture docs — while owners, target weeks, and backend commitment remain TBC. |
| M2 Admissions launch | ~50% | ~40% | FE ~50% = 9 of 18 applicable admissions rows with Demo depth (4 student-side sheet starts + 5 Applicant Demo capabilities with hosted HTTP). Staff admissions review remains not started. Platform ~40% = Applicant Demo HTTP + schema v4; real CMS-backed apply→enrol is not Live. |
| M3 Core student portal | 31% | ~45% | FE 31% = 16 of 51 applicable rows started — student Demo/Partial screens are deepest. Lecturer and staff paths for the same CAPs are still 0. Platform ~45% reflects student portal UI + Schema v4 academic/profile model; durable CMS writes and cross-role Live journeys are ahead. |
| M4 Lesotho pilot acceptance | 0% | ~22% | FE 0% — acceptance / training row, not a UI feature pack on the sheet. Platform ~22% = pilot decided (3 Oct), screenshot inventory + DB gap probe published; Live SoR path undecided, old CMS dump pending, NMDS/LGCSE/Loti parity not yet Live. |
| M5 Campus expansion | 35% | ~28% | FE 35% = 12 of 34 applicable expansion rows started on the sheet (not a licence to pull M5 ahead of admissions). Platform ~28% = Cyberjaya / Botswana / Sierra Leone inventories and dumps analysed for later rollout; no campus Live acceptance yet. |
Cumulative readiness over WG weeks
Platform work rising; Live stays at zero until CMS-backed acceptance. Dates are Working Group checkpoints, not a committed delivery calendar.
| WG date | Platform readiness | FE started (sheet) | Checklist Live | What changed |
|---|---|---|---|---|
| 18 Sep 2026 | ~15% | 31% | 0% | Architecture / WG kickoff context; FE snapshot already at ~31% from student Demo/Partial rows. |
| 22 Sep 2026 | ~30% | 31% | 0% | Campus inventories and dump analysis underway; FE sheet unchanged. |
| 25 Sep 2026 | ~45% | 31% | 0% | Schema v3 Demo and Portal API / CAP-53 Partial strengthen platform readiness; FE still flat. |
| 1 Oct 2026 | ~55% | 31% | 0% | Docs and campus baselines deepen; no Live checklist movement. |
| 3 Oct 2026 | ~60% | 31% | 0% | Lesotho pilot decided; screenshot inventory and DB gap probe start to land. |
| 5 Oct 2026 | ~65% | 31% | 0% | Prior cut: platform ~65%, FE still sheet-flat at 31%, Live still 0%. |
| 7 Oct 2026 | ~72% | ~36% | 0% | Current cut: Schema v4 + Applicant Demo HTTP hosted; FE Demo depth lifts on admissions; Live still 0%. |
Pie — work mix (applicable rows)
Engineering Demo cut 7 Oct 2026 (sheet baseline from SDD-13 plus Applicant Demo). Slice counts sum to 103 applicable frontend rows (M2+M3+M5). Live = 0 is omitted from the pie.
%%{init: {'pie': {'textPosition': 0.5}, 'themeVariables': {'pieOuterStrokeWidth': '2px', 'fontSize': '16px'}}}%%
pie showData
title Applicable frontend rows by portal (103 total; Live 0 omitted · cut 7 Oct)
"Started — Student" : 31
"Started — Shared (CAP-53)" : 1
"Started — Applicant" : 5
"Not started — Student" : 9
"Not started — Applicant" : 2
"Not started — Lecturer" : 18
"Not started — Admin/staff" : 37
| Milestone | Sheet rows | Applicable FE | Started | Not started | Live | FE started % | Detail |
|---|---|---|---|---|---|---|---|
| M1 | 1 | 0 | 0 | 0 | 0 | — | Rules / integration — no frontend rows on the sheet |
| M2 Admissions | 23 | 18 | 9 | 9 | 0 | ~50% (9÷18) | 4 student-side sheet starts + 5 Applicant Demo; staff half not started |
| M3 Core portal | 51 | 51 | 16 | 35 | 0 | 31% (16÷51) | Student Demo/Partial deepest; lecturer + staff paths still 0 |
| M4 Lesotho pilot | 1 | 0 | 0 | 0 | 0 | — | Acceptance / training row — no frontend pack |
| M5 Expansion | 36 | 34 | 12 | 22 | 0 | 35% (12÷34) | Sheet starts only — do not pull ahead of admissions |
| Pie scope (M2+M3+M5) | 110 | 103 | 32 | 71 | 0 | 31% (32÷103) | 4+16+12 = 32 · 14+35+22 = 71 · 18+51+34 = 103 |
| All milestones (sheet) | 112 | 103 | 32 | 71 | 0 | 31% | 112 = 1+23+51+1+36; Live KPI = 0 of 112 |
| Portal | Applicable FE | Started | Not started | Live | How it maps to the pie |
|---|---|---|---|---|---|
| Applicant | 7 | 0 | 7 | 0 | Whole slice: Not started — Applicant (7) |
| Student | 40 | 31 | 9 | 0 | Two slices: Started — Student (31) + Not started — Student (9) |
| Lecturer | 18 | 0 | 18 | 0 | Whole slice: Not started — Lecturer (18) |
| Admin / staff | 37 | 0 | 37 | 0 | Whole slice: Not started — Admin/staff (37) |
| Shared system | 1* | 1 | 0 | 0 | Slice: Started — Shared CAP-53 Partial (1). *Counted in the 103 applicable / 32 started totals |
| Total | 103 | 32 | 71 | 0 | 7+40+18+37+1 = 103 · 0+31+0+0+1 = 32 · 7+9+18+37 = 71 |
Delivery sequence (order only)
Agreed milestone order — kickoff and every target week on the sheet are still TBC.
| Order | Track | Item | Status | Depends on | Notes |
|---|---|---|---|---|---|
| 1 | Milestone | M1 Confirm rules and integration | Open | — | Rules, owners, API access — unblocks later work |
| 2 | Milestone | M2 Admissions launch | Open | M1 | Apply → enrol on real records; CAP-53 first slice |
| 3 | Milestone | M3 Core student portal | Open | M2 | Student + lecturer/staff paths Live or verified old CMS |
| 4 | Milestone | M4 Lesotho pilot acceptance | Critical | M3 | Pilot campus accepts product; NMDS / LGCSE / Loti parity |
| 5 | Milestone | M5 Campus expansion | Open | M4 | Cyberjaya, Eswatini, Cambodia, Botswana, Sierra Leone, … |
| — | Foundation | Schema v3 + Portal API docs | Done | Parallel | Published; Demo schema_version 3 |
| — | Foundation | Campus CMS inventories (CY / BW / SL) | Done | Parallel | Dump-backed E2E hubs on Pages |
| — | Foundation | Lesotho screenshot + DB gap probe | Active | Parallel | Feature benchmark + proxy gap vs Schema |
| — | Foundation | Lesotho old CMS structure dump | Critical | Vara | Pending — needed for CAP-53 / physical ACL |
| Status | Item | Notes |
|---|---|---|
| Done / strong | ADR-1 · Schema v3 Demo · ERD/DFD · campus inventories · Lesotho pilot decision | Architecture and evidence base ready for integration design |
| In progress | Portal API · applicant portal UI · student Demo screens · CAP-53 Partial | Frontend ahead of Live CMS writes; admissions applicant/staff not started |
| Pending | Owners + target weeks · backend off “Needs checking” · M2 applicant/staff CAP rows · Lesotho old dump | All 112 sheet owners/dates still TBC (SDD-13) |
| Blockers | No Live CMS path yet · Lesotho SoR path undecided · NMDS≠DTEF unknown · no shareable newer-CMS schema | Block Live M2–M4 until ACL + campus materials unblock |
| To achieve | M1 freeze → M2 admissions Live → M3 core student Live → M4 Lesotho pilot accept → M5 expand | Parity with Lesotho newer CMS (NMDS, LGCSE, clearance, Loti) |
Executive summary
Raisd is modernising how applicants, students, lecturers, and staff use campus systems — without throwing away the working campus CMS family that already holds the official records. Lesotho is the pilot project and first acceptance campus (Working Group, 3 Oct 2026 — supersedes Cyberjaya-first).
Think of it as four new front doors (Applicant, Student, Lecturer, Staff) that all talk to one Portal API. That API is the only bridge to the existing CMS. Nobody’s browser talks to the database or file store directly.
This phase (confirmed 23 Sep 2026; pilot campus updated 3 Oct): keep the existing campus CMS family as the system of record; ship better portal experiences; do not rebuild operational desks that already work; aim for parity with Lesotho’s newer CMS. Longer term: one unified Raisd CMS with databases placed by country (Lesotho, Malaysia, Singapore, Sierra Leone, Botswana, …), white-labelling, and feature toggles — reached via M5 progressive migration, not a launch rewrite.
- Now: student UI is largely demo/mock; applicant / lecturer / staff portals and live CMS writes are still ahead.
- Next: agree rules (M1), then admissions end-to-end on real records (M2).
- Then: core student journeys (M3), Lesotho pilot acceptance (M4), other campuses including Cyberjaya (M5), then distributed ideal.
Lesotho pilot project
Confirmed Working Group weekly, 3 October 2026 (Read.ai). Full rationale: lesotho-pilot.md · diagram analysis: old-cms-lesotho/.
High-level architecture
Four role portals → Portal API → anti-corruption layer (CAP-53) → existing CMS. Planned Postgres holds portal maps, audit, and session — not a second copy of CMS data. Detail: Architecture review · SDD-02 · ADR-1.
Who uses what
Browsers never talk to CMS, Postgres, or files directly.
flowchart LR
subgraph People
A[Applicants]
S[Students]
L[Lecturers]
T[Staff]
end
subgraph Raisd["Control plane"]
W[Role portal webs]
API[Portal API]
ACL["CMS bridge CAP-53"]
end
subgraph Campus
CMS[(Existing CMS
system of record)]
PG[(Postgres planned)]
FS[(Evidence files)]
IDP[Login / IdP]
end
A --> W
S --> W
L --> W
T --> W
W --> API
IDP --> API
API --> ACL
ACL --> CMS
API --> PG
API --> FS
Public endpoints
Everything below is reachable from the internet today. Demo Portal API runs on UltaHost k3s
at api.raisd.co / api.lesotho.raisd.co against VPS Postgres
(Neon dump restored). Vercel portal SPAs call https://api.raisd.co;
Lesotho campus SPAs call https://api.lesotho.raisd.co (same service).
Legacy raisd-portal-api.vercel.app redirects to api.raisd.co.
Checked 14 Oct 2026.
Websites
| Site | URL | Access | Hosted on · deployed by |
|---|---|---|---|
| Campus landing (Lesotho) | lesotho.raisd.co | Open — chooser into Apply / Student / Staff / Teach | UltaHost k3s · hostPath nginx |
| Demo Keychain | keychain.raisd.co | WG master password · Open filled for Demo desks | UltaHost k3s · hostPath nginx |
| Student portal | raisd-student-portal.vercel.app | Demo student number + password (via Keychain) | Vercel · GitHub Actions on push to main |
| Applicant portal | raisd-applicant-portal.vercel.app | Demo scenarios (via Keychain) | Vercel · GitHub Actions on push to main |
| Lecturer portal | raisd-lecturer-portal.vercel.app | Demo lecturers Adam / Laura (via Keychain) · Materials publish | Vercel · CLI / Actions deploy |
| Staff portal | raisd-staff-portal.vercel.app | Demo Registry / Bursary desks (via Keychain) | Vercel · CLI / Actions deploy |
| Portal API | api.raisd.co · api.lesotho.raisd.co | Meta routes open; portal calls need a bearer token | UltaHost k3s · VPS Postgres (legacy Vercel alias redirects here) |
| Documentation (this site) | docs.raisd.co | Site password (via Keychain → Control Plane) | UltaHost k3s · hostPath nginx (mirror: GitHub Pages) |
| Swagger UI | docs.raisd.co/openapi.html | Site password; “Try it out” calls the Portal API | UltaHost k3s |
| DB admin | db-admin.raisd.co | Team only — sign-in via Keychain; read-only | UltaHost k3s · hostPath Node (mirror redirect: Vercel) |
Portal API routes
Base URL https://api.raisd.co (Lesotho alias https://api.lesotho.raisd.co). Contract:
Swagger UI · openapi.yaml.
Browsers may call it only from the portal origins and this docs site (CORS allowlist).
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | / | None | Redirects to /v1/meta |
| GET | /health | None | Liveness: service, session store (postgres), CMS mode (stub), server time |
| GET | /v1/meta | None | Version, Demo scenarios, default scenario, CMS and session modes; links /v1/meta/lms |
| GET | /v1/meta/staff-progression | None | Reserved staff methods — deferred until a Live staff API exists |
| GET | /v1/meta/lms | None | Demo LMS catalogue — Materials / assignments / lecturer review × CAP × tables; deferred quiz / live-class / forum names (not callable). Not a Live LMS |
| GET | /openapi.yaml | None | Redirects to the published contract |
| GET | /docs | None | Redirects to Swagger UI |
| GET | /favicon.ico · /favicon.svg · /apple-touch-icon.png | None | Redirect to the Raisd icons on this site |
| POST | /v1/auth/login | Body: scenarioId + password | Issues a 12-hour bearer token. 401 wrong password · 400 bad body · 503 credentials not configured |
| POST | /v1/auth/logout | Bearer | Revokes the token |
| POST | /v1/auth/scenario | Bearer | Switches the session to another Demo student |
| POST | /v1/portal/{method} | Bearer | Calls one portal method with { "args": [...] }; returns { result, cms }. 401 no session · 404 unknown method |
Portal methods (POST /v1/portal/{method})
55 methods, all bearer-authenticated. Writes are Demo only: every response carries
cms.acknowledged = true, mode = "stub" until the CMS bridge
(CAP-53) is connected.
| Area | Read | Write (Demo) |
|---|---|---|
| Dashboard & records | getDashboard · getPortalRecordGraph · getCalendarMonth · getCommunity | — |
| Academic | getAcademicContext · getAcademicPerformance · getAcademicModules · getAcademicModuleDetail · getAcademicModuleAttendance · getAcademicModuleMaterials · getAcademicModuleMaterialDetail · getAcademicTimetable · getAcademicStudyPlan · getAcademicGraduation · getAcademicModuleRegistration · getModuleRegistrationFeePreview | confirmModuleRegistrations · submitAssignment · deleteAssignmentSubmission |
| Online forms | getOnlineForms · getOnlineForm · getOnlineFormSubmission | startOnlineForm · saveOnlineFormDraft · submitOnlineForm · withdrawOnlineForm · sendOnlineFormMessage · markOnlineFormRead |
| Immigration | getImmigration | — |
| Finance | getFinanceStatement | submitFinancePaymentProof · deleteFinancePaymentProof |
| Profile | getPersonalProfile · getAcademicProfile · getDocumentsProfile · getPrivacySecurity · getResumeProfile · getPortfolioProfile | updatePersonalProfile · updateResumeProfile · createPortfolioProject · updatePortfolioProject · deletePortfolioProject |
| Announcements & policies | getAnnouncements · getAnnouncement · getUniversityPolicies | — |
| Services | getServices · getServicePage | — |
| Lecturer review | getLecturerReview | submitLecturerReview |
| Chat | getChatConversations · getChatConversation | markChatConversationRead · sendChatMessage · deleteChatMessage |
Distributed CMS — ideal end state (high level)
End goal: one Raisd CMS product with a database (and preferably API capacity) per country / region, each campus white-labelled and feature-toggled. Global control plane holds tenancy, branding, flags, and identity maps — not student ledgers. Full step-by-step: Distributed CMS architecture.
flowchart LR
subgraph Product["One product"]
P[Four portals]
API[Portal API]
end
subgraph Control["Global control plane"]
T[Tenant · white-label · flags · IdP]
end
subgraph Data["Country data planes"]
MY[(Malaysia)]
SG[(Singapore)]
SL[(Sierra Leone)]
BW[(Botswana)]
MORE[(…)]
end
P --> API
T -.-> API
API --> MY
API --> SG
API --> SL
API --> BW
API --> MORE
Current state, target state, and what needs to be done
Baseline product truth: SDD-01. “Demo” on screen is not “Live” — Live needs durable save, real records, and server-enforced permissions.
Current state
- Student portal: deepest UI, still mostly demo / mock data.
- Applicant, lecturer, and staff portals: not launched as Live products.
- Backend: contracts and mock runtime; CMS writes not Live.
- Auth: mock student session; real SSO / CMS login still ahead.
- Staff work: continues on the existing LUCT CMS desks.
- Docs & diagrams: published for the working group (this site).
This-phase target (M1–M4)
- Four portals on real campus CMS records via Portal API — Lesotho pilot first.
- Admissions first, then core student journeys and Lesotho acceptance (M4).
- Parity with Lesotho’s newer CMS (screenshots); staff stay on verified old CMS unless a gap is proven.
- Phone-friendly core journeys (not a native app mandate).
- Monitoring, backups, privacy, and training ready for Lesotho pilot go-live.
What needs to be done
- Agree campus rules, owners, and API access (M1).
- Ship Portal API first slice + admissions end-to-end (M2 / CAP-53).
- Wire Live auth that respects CMS login rules.
- Make student learning, fees, and support paths Live or keep them on verified old CMS (M3).
- Complete Lesotho pilot acceptance and ops readiness (M4).
- Only then expand campuses and migrate remaining CMS domains with a written strategy (M5).
| Layer | Where we are | This-phase Live target |
|---|---|---|
| Student UI | Demo / Partial on mock data | Role journeys on real CMS records via Portal API |
| Applicant UI | No Live product yet | Application → enrolment on CMS via Portal API |
| Lecturer UI | No Live product yet | Publish / attendance / marking — prefer verified old Lecturer Portal where it works |
| Staff UI | Ops on existing CMS desks | New screens only for verified gaps; else keep the desk |
| Backend | Mock runtime; CMS path stubbed | Portal API ↔ campus CMS family / Lesotho path (CAP-53) |
| Auth | Fixed mock session | Real login / SSO honouring CMS rules where required |
Migration stages (M1–M5)
Order is admissions-first. A milestone is when something must work, not when investigation starts. Dates are TBC until the working group locks them. Full plan: Migration · SDD-03.
flowchart LR M1["M1 Confirm rules
and integration"] --> M2["M2 Admissions
launch"] M2 --> M3["M3 Core student
portal"] M3 --> M4["M4 Lesotho
pilot acceptance"] M4 --> M5["M5 Campus expansion
and remaining CMS"]
| Stage | In plain words | Release condition (summary) | Hosting |
|---|---|---|---|
| M1 | Get the rules and access straight | Rules, API access, and operating responsibilities agreed | Before stage 1 install |
| M2 | Open admissions for real | Application-to-enrolment works with real records | Stage 2 |
| M3 | Day-to-day student life works | Student + staff/lecturer paths Live or on verified old CMS | Stage 3 |
| M4 | Lesotho says “we accept this” | Lesotho campus accepts pilot; training and ops ready; parity with newer CMS | Stage 4 |
| M5 | Grow out + tidy remaining CMS | Each campus accepts rollout; SoR moves only with written strategy | Stage 5 |
Explore further
Deeper technical material for architects, developers, and AI agents.
cmscbj) — M5
LUCT Botswana CMS
Sister campus dump (cmsbotswana) — M5 · old Lesotho family hint
ICA Sierra Leone CMS
E2E hub · ERD · DFD · integrations · 3-campus compare (ems_sierraleone)
Software Design Documents
Working-group baseline (SDD-00 … SDD-15)
AI knowledge base
Agent instructions and catalogues
Portal API OpenAPI
Swagger UI for POST /v1/portal/:method