Aldar Education

Aldar (29 schools, 33K students) conversion plan — five requirements as epics, with the license & isolation decision called out.

This is the delivery plan for Aldar Education — the five things Aldar asked for, shaped as epics and stories you can pick and ship. Sales, commercial structure, timeline, risks, and 3-year value scenarios live in personal artifacts cited under See also — this page stays focused on the work.

Status reconciled 2026-06-15 against origin/main @ 8fcea24d1. Epics 01–04 remain merged to main (eSIS connector, multi-method payments + per-school currency, multi-provider conferencing, parent portal — the portal is now fully AR-RTL-wired and security-hardened). Epic 03's built-in LiveKit and Epic 01's eSIS submission stay gated on external infra/credentials, not code. Epic 05 (on-premise) is no longer un-started: its Phase 0–2 scaffold — standalone Dockerfile, docker-compose.aldar.yaml, and an Ed25519 license-key library — is built in-flight on branch fix/stream-production-ready, not yet merged to main. Two product-wide renames since the last reconcile touch this doc: LiveClass→Conference and the ClickView LMS de-brand. Per-epic master trackers: #1 (01) · #356 (02) · #3 (03) · #4 (04) · #5 (05). Epics 06–07 have no tracker yet (unscoped).

Their five requirements

#RequirementMaps to epic
1Daily attendance submission to ADEKEpic 01
2Fee payment — cards, Apple Pay, offline bank transfer, ATMEpic 02
3Built-in video conferencing via LiveKit on dedicated serversEpic 03
4Parent portal — comms, progress, grades, downloadable reportsEpic 04
5Private/on-premise deployment + annual licensingEpic 05

Epics at a glance

#EpicTrackMaturityDetail
01ADEK attendance submissionTechBuilt (external-gated)attendance · #1
02Multi-method fees + Apple Pay + AEDTechShippedfinance · #356
03Conference (video conferencing)TechBuilt (external + native live · LiveKit SFU infra-gated)conference · #3 · #361
04Parent portal completionTechShippedparent · #4
05On-premise + licensingTechIn Progressself-hosting · #5
06Data migration from existing SISTechVaporware
07Security & complianceTechVaporware

Epics

01 — ADEK attendance submission · Tech · Built

attendance · framework at src/lib/compliance/; models at prisma/models/{attendance,compliance}.prisma; tracker hogwarts#1 (~600 attendance+compliance tests; #1 still open)

ADEK mandates daily upload to eSIS and parent contact within 2 hours of unreported absence. The connector is built and merged to main — all three submission paths (official API, Aldar credential piggyback, Playwright RPA) plus a DRY_RUN mode, the daily eSIS export cron, and the 2-hour parent-contact SLA cron. The only remaining work is external: Aldar/ADEK must hand over real eSIS access. Until then the connector runs in DRY_RUN.

  • ✅ Compliance schema — compliance.prisma (4 tables + 4 enums, generic naming) + AES-256-GCM encryption-at-rest with key-version rotation · #1
  • ✅ Daily eSIS CSV export cron at 14:00 GST — /api/cron/esis-submit, reuses the attendance/bulk pattern, CSV persisted inline + audit-downloadable · #1
  • ✅ Connector library — src/lib/compliance/providers/adek/{official,piggyback,rpa,dry-run,mapper,csv-schema}.ts + orchestrator + registry; circuit breaker (3 fails/1h → halt, 1h cooldown → HALF_OPEN) · #1
  • ✅ ADEK 2025/26 absence-category rules (authorized / unauthorized / cause-for-concern at rolling-30d >5%) in the orchestrator · #1
  • ✅ RPA worker scaffold (tools/adek-rpa-worker/, Dockerfile + Fly.io) — token-tenant-scoped claim/ack with lease-and-recovery · #1
  • ✅ 2-hour parent-contact automation — /api/cron/absence-followup (every 30 min, DST-safe UTC) writes an AttendanceIntervention as regulator audit evidence; email + WhatsApp channels · #1
  • 🔴 File formal eSIS-integration inquiry to ADEK via Aldar's compliance team — external, unblocks the official-API path
  • 🔴 Aldar group-level eSIS credential piggyback for the pilot — external, needs written consent
  • 🔴 eSIS portal access to capture Playwright RPA selectors — external, unblocks path C

02 — Multi-method fees + Apple Pay + AED · Tech · Shipped

finance · Source of truth: hogwarts#356 (P0+P1+P2+P3+P4 — merged to main; p1+p2 migrations + currency snapshot columns live on Neon; per-school currency #305 closed)

Stripe + Tap + Bankak webhooks shipped. Payment-method enum extended via ALTER TYPE ADD VALUE (APPLE_PAY / GOOGLE_PAY / MADA / KNET / ATM_DEPOSIT) in the canonical prisma/models/fees.prisma enum (renamed from finance-fees.prisma on main; not just the SaaS subscription enum). Currency snapshot columns landed on FeeStructure / FeeAssignment / Payment / Receipt with backfill from schools.currency (38 / 5906 / 600 / 0 rows). Parent-facing UI, AED localisation end-to-end, and the offline bank-transfer + ATM deposit reconciliation flows are all live.

  • ✅ Activated Apple Pay through Tap src_all source picker — Tap maps source.payment_method to canonical PaymentMethod enum; raw value persisted as Payment.gatewayMethod for audit · #356 P1.3+P1.4
  • ✅ Wired parent-side payment picker into fee-assignment page (FeePaymentMethods component); createFeePaymentCheckout auto-routes AE schools to Tap-first via resolveAvailableMethods. Stripe Checkout wallets (Apple Pay / Google Pay / Link) auto-unlocked by dropping the payment_method_types: ["card"] hardcode · #356 P0.3+P0.4
  • ✅ AED end-to-end audit — formatCurrency signature now requires explicit currency; ~100 callers migrated; AED renders correctly in fee structures, invoices, receipts, and the server PDF · #356 P0.1+P1.1
  • ✅ Per-school currency on School model (School.currency String @default("USD")) + propagate (shipped via sprint Epic 01 — hogwarts#305, closed 2026-05-26) — denormalized onto fee/payment rows so receipts stay correct after a currency switch · #356 P1.1
  • ✅ Offline bank-transfer recording flow — admin captures reference + bank name + branch + sender IBAN + deposit-slip URL; row lands in PaymentStatus.PENDING_VERIFICATION; admin clicks Mark as ClearedmarkPaymentCleared server action flips to SUCCESS inside $transaction, posts to double-entry ledger, syncs invoice, notifies student + guardians · #356 P2.1
  • ✅ ATM-deposit recording flow — new PaymentMethod.ATM_DEPOSIT enum value + conditional form variant; shares the same markPaymentCleared reconciliation path · #356 P2.2
  • ✅ Parent receipt PDF in AED with school logo + signature — server-rendered at /api/payment/[paymentId]/receipt via @react-pdf/renderer renderToBuffer; tenant-scoped + ACL'd (finance admin OR own student OR guardian); renders payment.currency snapshot through the canonical decimal-aware formatter (handles AED / KWD / BHD / OMR) · #356 P1.5+P2.4
  • ✅ Reconciliation report — manual payments vs gateway payments vs ledger; live 3-column diff per PaymentMethod at /finance/banking/reconciliation and /finance/accounts/reconciliation; default 30-day window via ?days=N; pending-verification banner shows offline payments awaiting clear · #356 P2.3

Ship checklist (deploy target): seed Aldar demo tenant (pnpm db:seed:aldar), set TAP_SECRET_KEY + TAP_WEBHOOK_SECRET on the deploy target (webhook now fails-closed), verify Apple Pay enabled on the connected Stripe account, browser-smoke on aldar.localhost:3000/ar. No code remaining — per-school currency (hogwarts#305) closed 2026-05-26.

03 — Conference (video conferencing) · Tech · Built

conference · block at src/components/school-dashboard/conference/ (LiveKit lib now at conference/livekit/); master hogwarts#3 · #355 (closed build tracker) · #361 (release)

The block was renamed and consolidated LiveClass → Conference on main (merge d086ad6d1); old /live-classes paths now redirect, DB tables preserved via @@map. Aldar still gets the LiveKit-on-dedicated-servers requirement they named — LiveKit is now one of three back-ends.

Shipped multi-provider — three meeting back-ends behind one UI. The external pasted-link provider (teacher pastes a Meet / Zoom / Teams URL with a set-once recurring link; students join from one button on their timetable) is live on main today — no infra, runs on Vercel. The native Meet / Zoom / Teams adapters (createMeeting wired through each vendor's API, dark until per-provider OAuth creds land) are also merged. The built-in LiveKit SFU is fully built (schema on Neon, token / room / egress / webhook lib, dedicated room UI, recording pipeline, 2 crons, full test suite) but dormant, production-gated on LIVEKIT_* env + a UAE-region SFU. What remains is infrastructure + the Meeting-3 in-school network test — not code.

  • Conference / ConferenceParticipant / ConferenceRecording / ConferenceEvent + ConferenceLink (recurring carry-forward) schema + retention/capacity columns on School, on Neon br-small-tooth-adscsfmb; DB tables preserved via @@map (zero-change rename) · #355
  • ✅ LiveKit lib — room provisioning + JWT tokens gated by getTenantContext, Egress, webhook (HMAC + idempotent), signed recording URLs, deterministic room naming · #355
  • ✅ Teacher "Start class" + student/parent "Join class" surfaces, timetable Join button, dedicated full-screen conference room page; plus HOST moderation (kick = SFU evict + DB status) and a per-section recording opt-out · #355 · #361
  • ✅ Recording pipeline — Egress → S3 me-central-1 (per-school s3Bucket/s3Region supports MinIO fallback), retention cron, reminders cron · #355
  • 🟡 Provision G42 Cloud SFU + coturn TURN-over-443-TCP + S3 bucket; set LIVEKIT_* env — infra, P0 for built-in video
  • 🔴 Meeting-3 network test inside an Aldar school WiFi (/conference/network-test) — non-negotiable pre-signature gate; block on TURN/443 failure (see the conference block's RUNBOOK.md 6-gate activation sequence)
  • ⚪ Capacity — single SFU pilot (~3-5K concurrent) → 3-node active-active by Wave 2 · future

04 — Parent portal completion · Tech · Shipped

parent · routes at src/app/[lang]/s/[subdomain]/(school-dashboard)/parent/*; tracker hogwarts#4 (former #357 consolidated; ~186 tests, post-reconcile security-hardened)

All 7 phases shipped to main. Every parent-facing surface Aldar asked for — "communicate, follow up on children's progress, view grades, download reports" — is live.

  • ✅ Parent-side per-child grades view consuming the grades API (with GUARDIAN auto-scope data-leak fix) · #4
  • ✅ Downloadable report-card PDF — async cron (process-report-card-pdfs) + signed-URL gate at /api/parent/report-cards/[id]/download · #4
  • ✅ Parent ↔ teacher messaging deep-links (role-dispatches GUARDIAN → children's teachers + admin) · #4
  • ✅ Parent-side fee balance + payment surface (/parent/fees, cross-link Epic 02) · #4
  • ✅ Parent-side video-class join surface (cross-link Epic 03) · #4
  • ✅ Attendance excuse submission (<ExcuseForm>) · #4
  • ✅ Push (FCM no-op scaffold, ops opt-in) + email + WhatsApp notification preferences per parent, with per-channel quiet hours · #4
  • ✅ Public transcript verification (/verify/transcript/[code]) + term-end report-card cron · #4
  • ✅ Post-reconcile security hardening (e23bea936) — mobile excuse IDOR gate (canAccessStudent + Zod), fail-closed isAuthorizedCron on the report-card cron, parent/layout.tsx GUARDIAN/DEVELOPER route gate, per-IP rate-limit on public transcript verify, schoolId-scoped fee updateMany · #4
  • ✅ AR (RTL) i18n wiring — new parentPortal namespace (en+ar), all 4 child views dictionary-wired, STATIC-GAP ratchet at 0 · #4
  • ⚪ Parent-portal RTL Playwright e2e polish pass + FCM SDK opt-in (still a no-op scaffold at src/lib/notifications/push-fcm.ts) — deferred, non-blocking

05 — On-premise + licensing · Tech · In Progress

self-hosting · master hogwarts#5 (12 sub-epics) · multi-tenant adapter at src/lib/multi-tenant-prisma-adapter.ts is production-grade. On main, deployment is still Vercel-only (Dockerfiles present: socket-server/Dockerfile, tools/adek-rpa-worker/Dockerfile). The Phase 0–2 on-prem scaffold is built in-flight on branch fix/stream-production-ready — not yet merged to main.

Aldar wants the platform on their UAE infrastructure with annual licensing. Build in the unified hogwarts codebase for now; the SaaS/standalone split is its own decision — see License & isolation.

  • ✅ Top-level Dockerfile for the Next.js app (standalone output pattern, gated BUILD_STANDALONE=true so Vercel is unaffected) · Built in-flight on fix/stream-production-ready (455f3d158), not yet merged to main
  • docker-compose.aldar.yaml — web, socket-server, postgres, redis, livekit, livekit-egress, minio, caddy + deploy/Caddyfile & LiveKit/Egress configs · Built in-flight (bf4288756), not merged; observability stack still not included
  • ✅ License-key library (src/lib/licensing/license.ts) — Ed25519-signed envelope, validated on boot + every 6h, 30-day grace, DEPLOY_MODE=onprem gate, 9 tests · Built in-flight (27a7ffacc), not yet merged to main
  • Telemetry beacon — hourly outbound metadata-only payloads to telemetry.databayt.org (no PII) · needs issue
  • databayt-cli upgrade --version X.Y.Z — pull signed images, run migrations, rollback path · needs issue
  • Backup runbook — nightly pg_dump + WAL archive + MinIO replication · needs issue
  • Helm chart for Wave 2 (K8s HA across multi-school) · needs issue
  • Postgres primary + replica with auto-failover (Wave 2) · needs issue
  • Group-level admin views — extend getTenantContext to support Aldar HQ users spanning multiple schoolIds · needs issue

06 — Data migration from existing SIS · Tech · Vaporware

Per-school work — Aldar has 13 disparate SIS systems underneath their Salesforce + MuleSoft layer.

A generic bulk-onboarding CSV importer (students / parents / staff) already ships in hogwarts — src/components/file/import/csv-import.ts (importStudents/importTeachers/importStaff/importGuardians), hardened 2026-06-15 with crypto-secure temp-credential minting — and is the reuse base for the migration kit. Everything else below (discovery, field-mapping, section/timetable/historical/fee importers, reconciliation, cut-over) is still unbuilt, so the epic stays Vaporware.

For the Yasmina BA pilot we need a per-school discovery + import workflow. Without it the cut-over is impossible. The MuleSoft connector is the longer arc; the importers are the immediate need.

  • Discover Yasmina BA's source SIS (likely SchoolBase, iSAMS, or Engage) · needs discussion
  • Field-mapping spreadsheet template (signed by school IT before any import) · needs issue
  • Idempotent CSV importers — students, parents, staff already exist (generic bulk-onboarding, reusable as the migration base); still needed for SIS migration: sections, timetables, 1-year historical attendance, 1-year historical grades, fee balances · needs issue
  • Daily reconciliation report during parallel run · needs issue
  • Cut-over runbook — source SIS → read-only, hogwarts → system-of-record, <1% discrepancy gate · needs issue
  • MuleSoft connector — OpenAPI spec + adapter for student/staff/parent record sync into Salesforce (Wave 2) · needs issue
  • Per-school importer parameterisation so Wave 2/3 schools onboard via the same kit · needs issue

07 — Security & compliance · Tech · Vaporware

Procurement gate. Aldar will accept "in flight" if the roadmap is dated and funded — but the workflows must be in product on day one. Foundations already exist from Epic 01 — AES-256-GCM encryption-at-rest (src/lib/compliance/encryption.ts), namespaced audit actions, and a country-gated compliance settings surface — but the named stories below (consent capture, SAR export, retention enforcement, admin MFA) are not yet built.

  • Parental-consent capture workflow in the parent portal (PDPL Jan 2027 prep) · needs issue
  • Data-export endpoint per subject-access-request (PDPL) · needs issue
  • Data retention policy enforcement per school + per data type · needs issue
  • Mandatory MFA for admin + staff roles via Auth.js v5 · needs issue
  • Audit log for every admin action touching PII (extend audit.prisma coverage) · needs issue
  • Threat model (STRIDE) for the on-prem deployment · needs issue
  • Pen test engagement (Help AG or DTS, UAE) — first pass during pilot Month 4 · needs issue
  • ISO 27001 audit prep — BSI Middle East, target Month 12 · needs issue
  • SOC 2 Type 1 prep — target Month 18 · needs issue
  • Source-code escrow agreement (NCC Group Middle East) · needs issue
  • Background-check process for engineers with prod access · needs issue

Stack & tooling

Two of the epics ride on tool choices that need a real comparison, not a default pick. Both are listed below as living tables — claim a row, add data, push the recommendation through a Discussion thread.

Video conferencing stack (Epic 03)

Current lean is LiveKit self-hosted on a UAE-region SFU because Aldar explicitly named LiveKit and dedicated servers, and because LiveKit's licensing (Apache 2.0) fits the open-core posture. Worth confirming the alternatives are worse before committing — UAE network behaviour can change the calculus. Note: as of the Conference consolidation the product also ships native Meet / Zoom / Teams adapters (real meetings via each vendor's API, dark until OAuth creds) as a complementary link-based tier alongside the LiveKit SFU — so the Meet/Zoom/Teams rows below are no longer just "don't pick / vendor-lock", they're a fallback already implemented.

OptionLicenseUAE / MENA fitOpen-core compatibleNotes
LiveKit (self-hosted SFU)Apache 2.0Deploy in G42 Cloud or Etisalat AWS me-central-1YesAldar named it; recording via Egress; TURN-over-443 fallback supported
Daily.coSaaS, proprietaryGlobal PoPs; UAE not nativeNo (vendor lock)Fastest to ship; doesn't fit "dedicated servers" requirement
JitsiApache 2.0Self-host anywhereYesMature; recording (Jibri) is heavier; less polished SDK than LiveKit
Twilio VideoSaaS, proprietaryGlobal; no UAE PoPNo (vendor lock)EOL announced; do not pick
AgoraSaaS, proprietaryStrong APAC; UAE OKNo (vendor lock)Cost scales steeply with concurrency
100msSaaS, proprietaryIndia-centric; UAE OKNo (vendor lock)Good DX; same vendor-lock problem as Daily
Whereby / Zoom SDKSaaS, proprietaryVariableNoWhereby light; Zoom SDK heavy and expensive

Tasks:

  • Network test inside an Aldar school WiFi at Meeting 3 — confirms LiveKit works before signing · needs issue (cross-link Epic 03)
  • Spike — stand up Jitsi alongside LiveKit, compare CPU / bandwidth / quality on the same UAE node · needs discussion
  • Decide on recording storage — MinIO on-prem vs AWS S3 me-central-1 vs Aldar's existing object store · needs discussion

ADEK attendance submission paths (Epic 01)

Three paths in priority order. We commit to the outcome (daily submission on time) and pick whichever path ADEK + Aldar make real. Each row is one delivery track in Epic 01.

PathEffortRiskTime-to-first-submissionNotes
A — Official eSIS APIMediumDepends on ADEK docs landing4–8 weeks after docsCleanest long-term; requires vendor certification; the email to ADEK is the unblocker
B — Aldar group-credential piggybackLowCompliance approval from Aldar1–2 weeksPilot accelerator; reuses Aldar's existing eSIS tenant; requires written consent
C — Playwright RPA on the eSIS portalMediumBrittle to portal UI changes2–4 weeksDefinitely works; credentials in encrypted column; monitor for portal changes

Tasks:

  • File formal eSIS-integration inquiry to ADEK via Aldar's compliance team · needs issue (cross-link Epic 01)
  • Ask Aldar in Meeting 2 whether they'll share group-level eSIS credentials for the pilot · needs issue (cross-link Epic 01)
  • Spike — single-school Playwright RPA against esis.adek.gov.ae in a sandbox tenant to validate path C end-to-end · needs discussion
  • Decide on credential storage — encrypted Postgres column vs HashiCorp Vault vs Aldar's own secret manager · needs discussion

License & isolation

This is the most important decision on this page, raised multiple times by Moataz (team UAE advisor) and originally by Ahmed Bahaa from King Fahd Academy. Aldar wants their own infrastructure; we want one codebase. Resolving how those two truths coexist is upstream of every on-prem epic. The broader spectrum of delivery models — SaaS → Private — lives in delivery; the section below applies that spectrum to the Aldar-specific decision.

The licensing model itself is settled — open-core, per share-economy: hogwarts stays SSPL-1.0 on GitHub, enterprise customers buy a commercial license that grants on-prem use without SSPL's network-copyleft trigger. Source code escrow (NCC Group Middle East) layered on top.

What's not settled is how we organise the code for the two delivery shapes:

PathWhat it meansProsCons
A — Standalone project (founder-preferred)Sibling repo hogwarts-enterprise consuming hogwarts core. Own DB, dedicated servers, licensing, compliance posture. SaaS continues independently.Clean separation; enterprise can move at procurement speed; SaaS stays nimbleTwo codebases to maintain; feature drift risk; harder to keep parity
B — Long-lived enterprise branchSame repo, main (SaaS) + enterprise branch. Development stays unified.Single source of truth; backports trivial; one CI; team contextBranch divergence over time; cherry-pick fatigue; complex release matrix

Stance for now: keep features in the unified databayt/hogwarts codebase (Epic 05 lives there — the commercial license-key library src/lib/licensing/license.ts is now scaffolded in-flight on fix/stream-production-ready with SSPL-1.0 header + Ed25519 commercial-license validation, operationalising the open-core model above), defer the split until we have signal. The next signal that forces the call: first paying on-prem customer signs or before Aldar Wave 2 rollout, whichever comes first.

  • Pick A or B before Aldar Wave 2 kickoff (~Month 5 post-pilot) · needs discussion
  • If A: scaffold databayt/hogwarts-enterprise repo from the hogwarts standalone Docker output · needs issue (post-decision)
  • If B: define the enterprise branch ruleset (protected, restricted reviewers, release tags) · needs issue (post-decision)
  • Commercial license template — terms, escrow trigger, indemnification cap, exit/handover · needs issue
  • "Powered by databayt" branding toggle for enterprise installs · needs issue
  • Telemetry payload spec — what we measure, what we never measure, parental review · needs issue

Open questions

Discussion threads, not yet concrete stories. Each becomes a hogwarts Discussion thread before it can be picked.

  • ADEK eSIS API — does a documented API exist? Authentication model? Vendor certification process? · needs discussion
  • Aldar's group-level eSIS credentials — can we piggyback for the pilot, or must we get our own vendor cert? · needs discussion
  • Yasmina BA's source SIS — SchoolBase, iSAMS, Engage, or something else? Determines migration scope · needs discussion
  • MuleSoft contract boundary — what record types does Salesforce read from hogwarts; which way does the truth flow? · needs discussion
  • UAE hosting — G42 Cloud vs Etisalat AWS me-central-1? VoIP throttling tolerances inside Aldar networks? · needs discussion
  • Apple Pay merchant ID — does Aldar's existing Apple Pay merchant work with Tap, or do we provision per-school? · needs discussion
  • ISO 27001 certifying body — BSI Middle East default; alternatives? Budget timing? · needs discussion
  • Escrow agent — NCC Group ME or local alternative? · needs discussion
  • PDPL DPA timing — when does Aldar Legal want it signed (contract vs PDPL effective date 1 Jan 2027)? · needs discussion
  • LiveKit recording retention — Aldar Legal default; per-brand variance for Cranleigh / Charter? · needs discussion

See also

  • Private strategy plan (founder only): ~/.claude/plans/a-very-good-company-peppy-frost.md — sales, commercial structure, timeline, risks, KPIs, recommendations
  • Memory (founder only): ~/.claude/projects/-Users-abdout-kun/memory/project_aldar_prospect.md · reference_adek.md · feedback_enterprise_licensing_open_core.md
  • kun delivery — SaaS → Private spectrum (where Aldar's Private-enterprise package fits) · sprint — Q3 2026 epics across the whole org · share-economy — open-source doctrine the license decision flows from · self-hosting — on-prem deployment doc · repositories — hogwarts repo reference · team — who owns what · captain — CEO brain
  • Aldar Education · ADEK · eSIS Portal · UAE PDPL