Objective
Make approval, denial, Needs Info, stat review, audit writes, and projection enqueueing atomic and recoverable.
Dependency
Blocked until db-v1.0.0 is canonical and both consumers are pinned to its immutable contract.
Migration scope
Add service-role-only functions:
resolve_pending_action(...) returns jsonb
resolve_pending_stat_record(...) returns jsonb
create_pending_action(...) returns jsonb
Add operation_outbox with unique deduplication keys, leasing, attempts, availability, external IDs, errors, and pending | processing | completed | dead_letter states.
Required behavior
- verify actors against
admin_users, lock related rows, validate payloads, mutate domain state, transition lifecycle state, write audit rows, and enqueue projections in one PostgreSQL transaction
- approve/deny from
pending or pending_info; Needs Info only from pending
- require notes for denial and Needs Info
- return terminal decisions idempotently
- cancel stale match actions with an audit row
- reject unimplemented
alias_change without state change
- pin
search_path; revoke public/anon/authenticated execution; grant service role only
- cover Discord projections, captain notifications, proof-thread closure, and standings recalculation topics
Acceptance
- concurrent decisions produce one mutation and one audit pair
- forced audit/outbox failures roll back the transaction
- real-PostgreSQL tests cover stat concurrency, stale matches, invalid payloads, Needs Info resumption, terminal idempotency, and unauthorized access
- two workers cannot claim the same row; expired leases recover; failed rows back off and dead-letter after ten attempts
- rollout evidence includes one staged approval flow and one controlled production flow before legacy helpers are removed
Objective
Make approval, denial, Needs Info, stat review, audit writes, and projection enqueueing atomic and recoverable.
Dependency
Blocked until
db-v1.0.0is canonical and both consumers are pinned to its immutable contract.Migration scope
Add service-role-only functions:
resolve_pending_action(...) returns jsonbresolve_pending_stat_record(...) returns jsonbcreate_pending_action(...) returns jsonbAdd
operation_outboxwith unique deduplication keys, leasing, attempts, availability, external IDs, errors, andpending | processing | completed | dead_letterstates.Required behavior
admin_users, lock related rows, validate payloads, mutate domain state, transition lifecycle state, write audit rows, and enqueue projections in one PostgreSQL transactionpendingorpending_info; Needs Info only frompendingalias_changewithout state changesearch_path; revoke public/anon/authenticated execution; grant service role onlyAcceptance