4. Identity, persistence, access, and evidence
Learn why review identity, saved versions, fact revisions, and policy versions are separate values.
Six values to keep separate
| Value | Purpose | Failure if confused |
|---|---|---|
| review.id / UUID | Stable storage and route key. New imports use UUIDv7. Deterministic fixtures use UUIDv5. | A repeated review number across years opens or overwrites the wrong work. |
| program + FFY + review number | Business uniqueness and refresh match, separate from UUID. | Source intake merges another program or fiscal year. Subtype uniqueness needs a production decision. |
| StoredReview.version | Database save concurrency. An accepted batch appends the next version. | Another user silently overwrites a newer saved copy. |
| review.revision | Domain fact/check revision. Stored validation must match current review facts. | An old check is accepted after facts change. |
| facts.inputsRevision | Calculation input revision. Final SAQC binds to it. | Changed income uses an obsolete final benefit. |
| calcVersion, checkVersion, policyId/copy | Algorithm identifiers, validation identifier, and dated amount table. | A historical review changes when new policy is published. |
Source: identity helpers, schema, rule IDs, and identity contract. Number-only and old FFY:number routes no longer open records. Use search and current UUID links.
What the database stores
| Table or store | Responsibility | Trade-off |
|---|---|---|
| snap_review_snapshots | Append-only complete review JSON, request ID, actor and saved time for each version. | Simple historical record, but repeated facts and Activity consume storage. This is snapshot history, not a complete event-replay system. |
| review_index | Current searchable fields, current version, and report projection. | Fast scoped lists. Projections must stay consistent and rebuild correctly. |
| inbox_events | Recipient notifications derived from saves. | Not proof that email was sent. |
| review_touches / inbox_visits | Staff flag, opened/read version, and inbox seen time. | Operational user state, separate from fact history. |
| Policy tables | Dated published tables and their values. | Publication/concurrency rules must protect historic meaning. |
| Private object storage / local disk | PDF bytes. Review snapshots contain document metadata and storage keys. | Bytes are outside the database transaction. Failed attachments can leave unreferenced objects. |
The review-store transaction appends the snapshot, updates review_index, creates inbox events, and updates save-side touch state. If snapshot version uniqueness fails, the batch rolls back. The local pg adapter and Neon batch serve that transaction contract. A backup plan must cover both database and PDF objects.
Two people editing the same review
- A and B load saved version 12.
- A saves request R1. The server appends version 13.
- B submits version 12. The server detects the mismatch and returns a stale-review conflict.
- The browser loads the current server copy and requires B to inspect it before editing again. Local edits are discarded on this conflict path.
- If A retries the same accepted request ID, the server returns the accepted result after checking access. It does not append a second version.
A request ID makes a retry idempotent, meaning that repeating that request has one accepted effect. It does not merge concurrent edits. A production UX should preserve a recoverable local draft or show a comparison if users need to recover conflict edits. Review current behavior before promising collaborative editing.
Authentication, capabilities, and scope
Authentication proves which account signed in. Authorization decides which work and actions it can access. Clerk public metadata supplies trusted role, staff ID, and program through the server. The server reads unsafe metadata only for preferences. A browser preference cannot grant a role.
Each actor currently has one program. Examiners see their work. Supervisors see their configured examiner team. Program manager, PEC, admin, and statistics can view program work. SQL reviewScope and object canAccessReview use the same examiner-scope helper. Tests should prove lists, direct URLs, saves, and documents agree.
Missing or invalid account metadata blocks setup. Development View as uses a separate restricted flow. Local browser tests require a secret, a localhost request, and a server outside Vercel. Those aids do not replace testing real agency accounts, SSO, offboarding, or multi-program membership.
Document evidence
Current uploads are PDFs of at most 10 MB. The server checks file shape and uploader ownership. For object storage, the browser uploads to a pending key, the server validates and copies it to a new final key, then the review attaches the key. A document read checks review access before issuing a short-lived URL. Current signed download URLs last 60 seconds.
Signature and size checks are not malware scanning or a records classification system. Production needs approved categories, checksum/integrity evidence, scan/quarantine state, retention, legal hold, authorized disposal, and access logs. Current orphan pruning protects objects referenced by snapshots and has a minimum-age grace period. It is not a retention policy.
Exercise and answer key
A user knows a review UUID. Another user publishes a new policy table. What changes for this user, and what grants access?
Answer
Knowing a UUID grants no access. The server still checks program and assignment/team scope. Publishing a policy table does not silently rebind the saved review. Its policy copy and algorithm/check IDs remain separate from its saved database version. A controlled apply-rules action can change the rule binding and must invalidate affected results/checks.