proposal-system/api/src/ProposalSystem.Api/Controllers
Adam Moussa 85bca54e08
feat(api): optimistic concurrency on the proposal aggregate + atomic audit staging
Phase 6a of the SHOC-alignment plan (ADR 0004, wire contract extracted
verbatim from shoc-backend PRs #10/#13-#18).

Concurrency (SHOC double-guard, Postgres port):
- long Version on Proposal + LineItem, IsConcurrencyToken, additive
  migration AddProposalLineItemVersion (DEFAULT 1; Up/Down inspected —
  no drift, exactly two AddColumn/DropColumn).
- Tokens are opaque base64 strings on the wire (RowVersionCodec:
  8-byte big-endian long), rowVersion on responses, proposalVersion on
  guarded requests. Missing -> 422 ProposalVersionRequired; malformed
  -> 422 InvalidRowVersion (BusinessRuleException carrier).
- Guarded: update, approve, return-to-review, send, revise, and bulk
  line-item update (proposal-level token — bulk replaces the item set
  wholesale, so per-item tokens are meaningless; deviation from the
  plan documented). Creates/deletes unguarded per SHOC precedent but
  bump the aggregate version.
- Conflict -> 409 { message, currentState } (SHOC envelope, reloaded
  row embedded); bare DbUpdateConcurrencyException -> 409
  { status, message, code } fallback. Both non-ProblemDetails,
  emitted by GlobalExceptionHandler.

Audit atomicity (stage-then-single-SaveChanges):
- IAuditService.Stage adds to the shared context without saving;
  every proposal/line-item mutation stages before its own single
  SaveChangesAsync, so mutation + audit commit or fail together.
  LogAsync (self-saving) remains for standalone events (downloads,
  role changes, delivery).
2026-07-13 20:48:28 -04:00
..
AdminController.cs fix(api): API-M2, M5, M7, M9, M10, M12, M13 — Medium audit findings 2026-05-27 18:18:44 -04:00
AuthController.cs fix: CORS, JWT auth, useBlocker crash, and auto-migration for production deploy 2026-05-27 19:20:29 -04:00
CustomersController.cs feat: proposal delivery — email customers the PDF on Mark as Sent (#126) 2026-06-18 12:40:55 -04:00
FilesController.cs fix(api): API-M2, M5, M7, M9, M10, M12, M13 — Medium audit findings 2026-05-27 18:18:44 -04:00
GeneratedPdfsController.cs fix(api): API-M2, M5, M7, M9, M10, M12, M13 — Medium audit findings 2026-05-27 18:18:44 -04:00
LineItemsController.cs fix: API medium findings (API-M3, M4, M6, M8, M11, M14) 2026-05-27 18:18:44 -04:00
PricingLibraryController.cs feat: pricing library — curated priced items feed the RAG corpus (#127) 2026-06-18 12:49:47 -04:00
ProposalsController.cs feat(api): optimistic concurrency on the proposal aggregate + atomic audit staging 2026-07-13 20:48:28 -04:00
SitesController.cs Add site search, PO number, service category Other, and form enhancements 2026-05-27 18:17:48 -04:00
UsersController.cs fix(api): API-M2, M5, M7, M9, M10, M12, M13 — Medium audit findings 2026-05-27 18:18:44 -04:00
VendorProposalsController.cs fix(api): API-M2, M5, M7, M9, M10, M12, M13 — Medium audit findings 2026-05-27 18:18:44 -04:00