5. Delivery5.6 Backend
Backend Implementation
API domains, SWDA hub, Xero sync, data model priorities, and engineering standards.
Backend strategy
Domain-driven API with event-driven integration for SWDA and Xero. UI apps never call government APIs directly.
Apps -> SOQ API Gateway -> Domain Services
│
├─ Core TMS (programmes, runs, enrolment, attendance, assessment)
├─ CRM (leads, opportunities, commissions)
├─ Finance Orders (pricing, subsidies, invoices mirror)
├─ Content/Learn (materials, progress)
│
└─ Outbox Events -> Workers
├─ SWDA Integration Hub
└─ Xero Sync Service
Recommended stack
| Layer | Choice | Why |
|---|---|---|
| API | NestJS (Node/TypeScript) or .NET 8 | Enterprise modules, DI, clear boundaries |
| DB | PostgreSQL | Relational integrity for funding/grades |
| Queue | Redis + BullMQ (or equivalent) | Retries, rate limits for SWDA |
| Object storage | S3-compatible | Documents, SCORM, recordings |
| Auth | OIDC + Singpass adapter + MFA for staff | SG compliance |
| Secrets | Vault / cloud secrets manager | SWDA credentials isolation |
| Observability | OpenTelemetry + structured logs | Trace registration -> SWDA submit |
Domain services (high level)
| Service | Responsibilities |
|---|---|
| Identity | Users, roles, Singpass links, MFA, sessions |
| Catalogue | Programmes, courses, modules, versions, fees |
| Scheduling | Runs, intakes, venues, Zoom, conflicts |
| Admissions | Applications, offers, exemptions |
| Enrolment | Student status, class assignment, Student 360 API |
| Attendance | Sessions, QR tokens, approvals, % rules |
| Assessment | Papers, attempts, marks, certificates |
| CRM | Leads, Privyr import, pipeline, commissions |
| Orders | Pricing engine, subsidies, SFC allocation, refunds |
| Notify | Email/SMS/in-app templates |
| Audit | Append-only activity & PII access logs |
| SWDA Hub | Mapping, submit, reconcile, ops dashboard APIs |
| Xero Sync | Contacts, invoices, payments, trainer bills |
Critical backend rules
- Idempotency keys on all SWDA and Xero writes
- Evidence gates — funding claim cannot submit without attendance/assessment evidence
- Configurable policies — 18-month exemption window as config
- TMS owns orders; Xero owns GL — never reverse that
- Outbox pattern — domain commit + event; workers process async
- PDPA — retention jobs, anonymisation, consent flags
SWDA Integration Hub (must-build)
| Capability | Detail |
|---|---|
| Environments | Sandbox + production configs |
| Auth | Secure credential store; rotation |
| Mapping | SOQ domain ↔ SWDA payloads |
| Jobs | Scheduled + real-time triggers |
| Ops UX API | Status by run, errors, resubmit |
| Audit | Full request/response retention policy |
Functional coverage (confirm in discovery): course runs, registration, eligibility, grants, SFC, attendance, assessment, completion, disbursement status.
Data priorities (build order)
- Tenant/User/Role + Audit
- Course / CourseRun / Enrolment / Session / Attendance
- Orders / Payments (local) -> Xero later
- Assessment / Certificate
- CRM Lead / Opportunity
- ExternalSyncJob (SWDA) + reconciliation tables
Backend quality bar
| Area | Standard |
|---|---|
| API design | Versioned REST (+ OpenAPI); optional GraphQL later |
| Tests | Unit for pricing/eligibility; contract tests for SWDA adapters |
| Perf | Enrolment list p95 < 300ms; SWDA workers durable under rate limits |
| Security | RBAC at row level for student PII; encryption in transit |
| DR | Daily backups; RPO <= 24h MVP, tighten for go-live |