geocrop-platform./apps/nextgen/docs/spec-deviations.md

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/, or deployment.yaml files 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 licenses table + licenses_middleware.js exists, 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_KEY is 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 manualdocker-compose up --build for 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.