Architecture Decisions
The ADRs are the canon for why the system is shaped the way it is. They
live in the backend repo under docs/adr/ — this page is a map, not a
replacement. Read the source ADR before making a structural decision it
touches.
ADR-001 — Fork VLMIS into a Generic LMIS
Source: docs/adr/001-fork-vlmis-into-generic-lmis.md.
The founding decision. VLMIS was tightly coupled to Rwanda's DHIS2, TRVST, and HMIS. Rather than refactor in place (risky for the live deployment) or rewrite (throws away years of supply-chain logic), HLMIS is a fork with fresh git history, migrated incrementally. Every architectural rule on the Architecture page traces back here:
- pluggable integrations behind interfaces, toggled at runtime
- configuration table over environment variables
- database-driven permissions, not hard-coded roles
- TypeORM retained deliberately — not up for re-litigation
ADR-002 — Cross-Repo Version Tolerance & Rollout-Gating Flags
Source: docs/adr/002-cross-repo-version-tolerance.md.
Backend and frontend deploy independently. This ADR adds:
apiContractVersion— a small integer, bumped only on breaking API changes, compared bidirectionally by the frontend, rendered as a warn-only dismissible banner. Never blocks — a false lockout is worse than a missed warning. See API Contract & CI.- Feature flags reuse the
configurationtable under afeatures.key convention, global per backend instance (one instance = one deployment; there is no tenancy boundary in the codebase). - Both are exposed on
GET /api/config/capabilities.
ADR-003 — OpenAPI Spec as a Versioned, CI-Enforced Contract
Source: docs/adr/003-openapi-spec-as-versioned-contract.md.
Makes openapi.json a real deliverable, not a side effect of the /docs
page:
- committed at the repo root, regenerated by a script that boots the real app
- CI fails the build on any drift between code and the committed spec
- the
@nestjs/swaggerCLI plugin is enabled so response types come from real TS return types - coverage is intentionally <100%, documented rather than faked
The full mechanics are on API Contract & CI.
Adding an ADR
New architecturally-significant decisions get a new numbered file in the
backend's docs/adr/, following the existing format (Context / Decision /
Consequences / Alternatives Considered). Add a matching summary section
here so the docs site stays a complete index.