Proposed production architecture
Build a new internal application for about 41 review staff. Use clear module boundaries, approved agency services, and a controlled path for SPII.
Start with a modular monolith
A modular monolith is one application codebase with enforced business-module boundaries. Deploy a web/API process and a separate worker process from that codebase. Use one approved relational database and private document storage initially. About 41 users do not justify separate services for every screen. The worker handles slow or retried work without blocking a review save.
Agency workstation / approved remote access
→ internal DNS + TLS + agency reverse proxy
→ agency identity service with approved MFA/SSO
→ internal web/API tier
→ review / assignment / program rules / policy modules
→ document / correspondence / reporting / DCA modules
→ approved relational database
current records + revisions + audit + outbox
→ private document store
quarantine → scanned approved objects
Internal worker tier ← committed outbox / durable jobs
→ approved template rendering / print-mail handoff
→ certified export / approved receiving-system adapters
Restricted monitoring + backup services → service owners
Internal only means the app has no public user entry point. The agency must define office and remote-access network paths. Access still requires identity and record authorization inside the network. Do not give a browser direct database credentials. External delivery, if later approved, goes through a named controlled adapter.
Module ownership and dependency rules
| Module | Owns | Boundary |
|---|---|---|
| Identity and access | Staff membership, roles, program/team/region scope, delegates and access review | Agency identity proves account identity. The app resolves authorized memberships. No user-editable metadata grants scope. |
| Review core | Review identity, source/QC fact layers, assignments, lifecycle and decisions | Other modules reference review UUID and source revision. They do not silently edit QC facts. |
| Program packages | Typed facts, field catalog, calculation, validation, output mapping and workflow decisions per program | Pure rule code depends on common value contracts, not UI, auth provider or database. |
| Policy registry | Immutable effective-dated tables/rules, publication and controlled rebinding | Approvers publish supported versions. Old results remain reproducible. |
| Documents and correspondence | Object metadata, scan state, categories, templates, generated artifacts, mail status and receipts | Document ownership and read rights are explicit. Delivery states have real evidence. |
| Reporting and exports | Versioned derived views, report runs, frozen export batches and reconciliation | Reports never define the source truth. Export snapshots bind to source revisions and receiving contracts. |
| Corrective action / DCA | Action work, assignments, submissions, decisions, extensions, follow-up and closure | DCA status is separate from QC approval and reporting release. |
| Operations | Jobs, audit, observability, migrations, backup and recovery | No general support role receives unlogged unrestricted data access. |
Keep UI components concerned with display and user input. Application services authorize actions, load records, invoke rules, and coordinate transactions. Domain functions return decisions and validation findings. Infrastructure adapters implement storage, identity, file, print and receiver interfaces. Enforce imports with lint/build checks and architecture review.
Proposed data model
| Entity | Key and content | Reason |
|---|---|---|
| reviews | UUID, program, subtype, FFY, review number, month, current state and revision | Separate opaque identity from business identity. Decide whether subtype participates in uniqueness before adding programs. |
| source_batches / source_rows | Source system/layout version, file hash, upload actor, raw row, validation outcome, normalized values | Retain source evidence and replay/reconcile an intake safely. Retention/access must account for SPII in raw files. |
| review_facts / fact_revisions | Typed current facts plus schema version, changed actor/time, before/after or immutable revision | Use relational fields for frequent constraints/queries. Use versioned JSON for program-specific fact structures with runtime validation. |
| assignments / memberships | Original and current owners, effective periods, program/team/region rights | Support staff changes and multiple program memberships without rewriting historic approvals. |
| calculation_runs / validation_runs | Input revision, algorithm/check version, policy table ID, results/findings, actor/time | Reproduce the outcome and make stale results explicit. |
| approvals / decisions / issues | Stage, decision, reason, revision, approver and time, issue identity | Do not collapse independent approvals or multiple issues into one status field. |
| documents / generated_artifacts | Review/action link, object ID, checksum, size, category, scan state, template version and access classification | Keep immutable issued documents traceable to their facts and template. |
| memos / deliveries / responses | Memo revision/type, approved content, issuance, recipient, delivery evidence, deadline calendar and responses | Amendment creates a revision and an explicit response-clock rule. |
| corrective_actions / submissions / follow_ups | Review and source memo revision, owner, state, repeatable submissions and decisions | Avoid numbered fields or parallel editable copies of QC facts. |
| report_runs / export_batches / receipts | Parameters, included review revisions, format version, digest, receiver status/rejections | Prove which data was sent and reconcile acceptance. |
| audit_events / outbox / job_attempts | Actor, action, correlation ID, source revision, event, delivery state and retries | A transaction commits the business change and the intent to notify or integrate. |
Do not copy the whole SnapReview snapshot as the only production model by default. Review the query, constraint, history, and retention needs first. Keep a hybrid model when program fact structures vary. Audit evidence must remain queryable and protected without retaining unnecessary duplicate SPII forever. Schema migration must preserve the meaning of old revisions.
Command and read contracts
For writes, accept a named action, expected revision, request ID, and typed payload. Resolve the actor server-side. Validate membership, record access, field rights, state, and policy rules. Commit the new record/revision, audit evidence, derived projection, and outbox intent together. Return the accepted revision and actionable validation errors.
Use explicit errors for unauthorized work, invalid input, invalid transition, and stale revision. Do not automatically merge approvals or calculations from stale data. Preserve or export a safe local conflict draft where permitted. Read APIs use paginated scoped queries and approved fields. A UUID remains a reference, not a capability.
Reliable work outside a transaction
- An approved memo action stores the approved artifact revision and an outbox event in the same transaction.
- A worker claims the event and creates a delivery job using an idempotency key based on memo revision and delivery action.
- The adapter records the real receiver/print/mail result. A local sent flag cannot stand in for a receipt.
- If the worker stops after a remote effect but before recording success, it checks the remote identifier/receipt before repeating.
- If a receiver lacks idempotency or receipt lookup, put uncertain deliveries in manual reconciliation. Do not promise exactly-once delivery.
- Retry transient failures with limits. Show exhausted jobs, owner and last safe action. Replays retain the original source version.
SPII controls for agency review
| Control area | Proposed implementation | Evidence owner |
|---|---|---|
| Data classification/minimization | Inventory SPII in forms, raw imports, PDFs, logs, backups, search, reports and exports. Mask unnecessary fields. | Privacy/data owner and product owner. |
| Identity lifecycle | Agency SSO/MFA, controlled provisioning, prompt offboarding, expiry of temporary coverage and periodic access reviews. | Identity administrator and security. |
| Authorization | Role plus program/assignment/region scope. Apply to reads, writes, object download, exports and support tools. | Engineering with security validation. |
| Network and encryption | Approved internal ingress, isolated app/data tiers, TLS, approved encryption at rest and key/secret management. | Agency infrastructure/security. |
| Documents | Scan/quarantine before user access, type/size limits, checksums, private store, short-lived authorized retrieval. | Platform engineer and records owner. |
| Audit and administration | Record sensitive reads/downloads/exports and decisions. Restrict audit deletion and privileged changes. Define break-glass approval. | Security and service owner. |
| Logs and monitoring | Log correlation IDs and safe operational metadata. Redact names, SSNs, raw payloads and session credentials. | Engineering and security operations. |
| Retention and recovery | Approved retention/disposal and legal holds. Backup DB and objects, restrict restore access, prove point-in-time recovery. | Records and infrastructure owners. |
| Dependencies and delivery | Review AI-assisted code, dependency licenses/vulnerabilities, lockfile and artifacts. Isolate environments and secrets. | Engineering lead and release owner. |
Use NIST SSDF as a secure-development reference and OWASP ASVS to select verifiable application controls with security. These sources inform the proposal. The agency must identify its binding standards and assessment route. No particular government authorization or certification is inferred from a vendor plan.
Capacity and recovery assumptions
Size for 41 named staff, with an initial assumption of 12 simultaneous active editors. Test all 41 signed in and sending a burst of queue/search/save requests, plus intake/report/export jobs. Measure review/year, edit count, PDF volume, retention and backup size before capacity selection. Synchronous read/write paths and batch work need separate targets.
Proposed service targets are business-hours availability of 99.5%, recovery within 4 hours, and no more than 15 minutes of unrecoverable committed data. IT and operations must confirm whether available services support them and what exclusions apply. These are not promises or current measurements. A 15-minute recovery-point target does not permit silent loss of a required approval receipt.
What to carry forward from the demo
| Candidate | Reuse condition |
|---|---|
| Workflow knowledge, field inventory, decision gaps | Keep as traced requirements. Resolve authority conflicts with policy owners. |
| UI patterns and screens | Re-test task fit, accessibility, SPII masking, dense forms and error recovery. |
| Calculation and validation functions | Independent expected cases, approved policy version, workbook-difference review and dependency cleanup. |
| Command/concurrency tests | Port as examples, then test the new contracts and storage implementation. |
| Database and auth adapters | Review against approved agency drivers, identity and deployment topology. Demo getDb selects Neon for every non-localhost host, so it is not a ready internal PostgreSQL adapter. |
| Demo seeds, reset and View as | Keep in an isolated synthetic environment. Remove demo mutation paths from operational deployments. |
Continue with delivery stages, test gates, and program packages.