proposal-system/shared/api-contracts
Adam Moussa d6404edefc
feat(contracts+web): thread concurrency tokens and 409 conflict handling through the domain layer
Phase 6b of the SHOC-alignment plan — client side of the optimistic-concurrency
wire contract shipped in 6a.

shared/api-contracts (additive):
- rowVersion: string on ProposalListItem, ProposalDetail, and LineItem
- proposalVersion?: string on UpdateProposalRequest and
  BulkUpdateLineItemsRequest; new ProposalVersionRequest
- ConcurrencyConflict<T> { message, currentState } — the SHOC ADR 0004
  409 envelope (guarded path; the unguarded fallback carries no state)
- matching zod schemas, all kept under the satisfies z.ZodType<T> coupling

web:
- lib/api/errors.ts: ConflictError carrying the server's reloaded
  currentState; client.ts interceptor throws it on 409 (WEB-M2 401
  handling untouched)
- guarded mutations read the token from the cached proposal detail at
  mutate time; the save flow chains rotated tokens (PUT response token
  into the bulk replace) and ends with a detail refetch so
  approve-after-save never sends a stale version
- 409 recovery in the admin use-cases: write currentState into the
  detail cache, invalidateProposalViews() (stale-queue invariant holds
  on the failure path too), and toast the conflict instead of the
  generic failure message
- e2e smoke mock payloads carry rowVersion; vitest coverage for the
  interceptor ConflictError paths, token threading/rotation, and 409
  cache recovery

Verified: shared typecheck, web tsc/vitest (69)/build/prettier/Playwright
smoke, mobile tsc (create-only, no changes needed).
2026-07-13 21:01:46 -04:00
..
src feat(contracts+web): thread concurrency tokens and 409 conflict handling through the domain layer 2026-07-13 21:01:46 -04:00
package-lock.json feat(contracts): adopt shared api-contracts in web, add zod schemas and ProblemDetails codes 2026-07-13 17:19:42 -04:00
package.json fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup) 2026-07-13 19:06:08 -04:00
tsconfig.json Initial scaffold: monorepo structure, CDK stacks, CI/CD, domain model 2026-05-16 18:40:46 -04:00