5.9 KiB
SRS Specification Deviations — NFR1 & NFR5
Date: 2026-07-28
Status: Draft — pending client sign-off
Owner: Lesticom Development Team (fchin — review/merge owner)
Affects: NFR1 (Scalability), NFR5 (Deployability)
Source: Next Gen Learning SRS.pdf §3.2 + Next Gen Learning SRS and strategic summary.pdf §4.2, §4.1
1. NFR1 — Scalability (Kubernetes, 100→2,000+ schools)
What the SRS said
NFR1 (Scalability): The cloud architecture must dynamically scale using Kubernetes to support from 100 to over 2,000+ schools seamlessly, accommodating national rollout spikes.
The summary doc (§4.1) elaborated on this: declarative partitioning by tenant_id, horizontal sharding at the 50,000-student / 500 GB threshold, Supabase RLS at the kernel level, an API gateway that routes by school UUID, and stateless microservices.
What we shipped
- Single-container Docker (
Dockerfile+docker-compose.yml) — Express API + Vite-built React client + SQLite in one image. Local deploy story only. - No Kubernetes manifests — no
k8s/,helm/,argocd/, ordeployment.yamlfiles in the repo. - No sharding logic — single SQLite file (
server/data/school.db) with WAL mode. Works for one school; not designed for thousands. - Multi-tenant table is present but inert — the
licensestable +licenses_middleware.jsexists, and the RLS migration (2026072200000000_multitenant_licensing_rls.js) ships, but the runtime deployment has not been tested with multiple tenants concurrently. - Supabase target is configured but
SUPABASE_KEYis unset in dev, so the sync engine no-ops (per the SRS's offline-first design).
Why we deviated
The MVP scope was an 8-week delivery targeting a single pilot school. Building K8s manifests, a sharding gateway, and a multi-tenant production deployment was out of scope for the MVP and a follow-on Phase 2/3 item. The SRS explicitly placed K8s/scaling in §4.2 as the "scale-up phase" beyond the MVP, with Kubernetes described in the implementation roadmap (Gantt chart) as W9-10 work.
We kept the schema-level hooks in place (RLS migration, licenses table, tenant_id columns on key tables) so the Phase 2/3 build is a deployment change, not a schema migration.
What we ask the client to accept
Either:
(a) Formally accept the deviation — the MVP is single-school; K8s + sharding is a Phase 2 deliverable. Lock the W9-10 Gantt slot and refresh the SRS milestone dates accordingly.
(b) Move K8s into MVP — increase MVP scope and timeline. We can scope the work (estimate: 3 dev-weeks for K8s + HPA + sharding gateway + multi-tenant smoke test).
Risk if (a) is accepted and we ship before Phase 2
- Production deployment requires a Phase 2 K8s build before the 2,000-school scale.
- Local pilot (single school) is fully functional on the single-container Docker.
- The SRS Gantt chart places K8s at W9-10, which is after the MVP launch milestone.
2. NFR5 — Deployability (GitLab + ArgoCD GitOps)
What the SRS said
NFR5 (Deployability): All cloud updates must be deployed using a GitOps pipeline (GitLab + ArgoCD) ensuring zero-downtime continuous delivery.
The summary doc (§4.1) elaborated: GitLab as the central repo + CI, ArgoCD for CD, Kubernetes for orchestration.
What we shipped
- Gitea-hosted repo (not GitLab). The team's actual remote is
https://git.techarvest.co.zw/fchinembiri/next-gen.git. - Gitea Actions workflows (
.gitea/workflows/ci.yml+build-push.yaml) handle container build + push. - No ArgoCD — no
argocd/, no ArgoCD app definitions, no GitOps sync loops. - Deployment is manual —
docker-compose up --buildfor a single host. No zero-downtime rolling deploys.
Why we deviated
The hosting reality on the ground is a Gitea instance, not a GitLab SaaS subscription. The Gitea Actions CI is the closest functional equivalent to GitLab CI for a single-org project. The ArgoCD layer was not built because there is no K8s cluster to deploy into (see NFR1 deviation above) — ArgoCD is a deployment orchestrator and we don't have a deployment target for it.
What we ask the client to accept
Either:
(a) Formally accept the deviation — treat Gitea + single-container Docker as the deploy story for MVP. Document the Gitea Actions pipeline as the CI. Move ArgoCD into Phase 2 alongside the K8s work (NFR1).
(b) Add GitLab mirror + ArgoCD — we set up a GitLab mirror of the Gitea repo, run GitLab CI for tests, and have ArgoCD deploy to a test K8s cluster. Estimate: 1 dev-week for the pipeline plumbing + 1 dev-week for the K8s cluster bootstrap (depends on NFR1).
Risk if (a) is accepted
- No zero-downtime deploys until K8s is in place. Acceptable for an 8-week MVP pilot.
- The CI surface (
.gitea/workflows/ci.yml) already builds + pushes a container image, so the swap to GitLab CI later is config-only. - The SRS implementation roadmap (Gantt chart) places GitOps at W9-10, which is after the MVP launch.
3. What the client should do
Please confirm one of the two options above for each NFR (a or b). Lesticom will then either:
- Update the SRS Addendum with the accepted deviations and the new Phase 2/3 milestone dates, OR
- Submit a Change Request (per SRS §9.1) to expand the MVP scope to include NFR1 + NFR5 fully.
Either way, the deviation is documented and traceable, not silently dropped.
4. Reference
- Audit report:
evidence/audit-2026-07-28.md§3.3 P2-6 - NFR1 in SRS:
Next Gen Learning SRS.pdf§3.2 - NFR5 in SRS:
Next Gen Learning SRS.pdf§3.2 - NFR1/NFR5 in summary doc:
Next Gen Learning SRS and strategic summary.pdf§4.1, §4.2 - Gantt chart placement:
Next Gen Learning SRS and strategic summary.pdf§8 (K8s + GitOps at W9-10, after MVP launch)
Drafted 2026-07-28 by fchin (Lesticom). Review required by Next Gen delivery lead before sign-off.