Docs Index
finance central operator.md

Proof Card: FinanceCentral Operator Service

Status: beta Last verified: 2026-05-13 · git sha 88c21442

Claim

FinanceCentralOperatorService promotes the FinanceCentral approval workflow from in-memory Map demo to a durable, audited state machine. Operators approve or reject finance_central_approvals rows via POST /api/finance-central/approvals/:id/{approve,reject}. The approve path is a two-stage durable lease (pending → applying → accepted) that wraps the NetSuite update write between beginAccept and completeAccept; every failure mode (no netsuite_id, connector throw, connector returns null, completion lost-race) reverts the lease back to pending and stamps an audit_logs row keyed finance_central.approve with result='failure'. Reject is an atomic single-stage transition with no external write. Status is beta because all 5 production connectors plus credentials would need to be exercised against a live Squire NetSuite sandbox before promotion to production.

Source

Tests

Live vs Fixture

Known Gaps

Verification (60-second AI-reviewer recipe)

# Repo + operator-service unit tests
npx jest --runTestsByPath tests/unit/services/financeCentral/FinanceCentralRepository.test.ts tests/unit/services/financeCentral/FinanceCentralOperatorService.test.ts

# Route-level integration (in-memory SQLite, ConnectorManager.getConnector stubbed)
npx jest --config=jest.slow.config.cjs --runTestsByPath tests/integration/financeCentral-approveItem.test.ts

# UI-layer regression (Playwright, file:// + window.fetch stub)
npx playwright test --config=playwright.e2e.config.cjs tests/e2e/finance-central-approve.spec.ts

# Confirm the two-stage state machine is wired (NOT a single UPDATE)
grep -n "beginAccept\|completeAccept\|revertToPending" src/services/financeCentral/FinanceCentralOperatorService.ts | head -12

# Confirm the route maps each result code to the spec'd HTTP status
grep -n "RESULT_CODE_HTTP_STATUS\b" src/routes/financeCentral.ts

The first grep proves the approve path runs beginAccept → connector.update → completeAccept with revert on EVERY failure branch (no single-statement transition for approve). The second grep proves the route maps each ApprovalResultCode to its spec §2.D7 HTTP status: not_found=404, already_dispositioned=409, connector_unavailable=503, write_failed=502, state_drift=500 (R2 addition — Codex R1 BM-1 fix for the post-connector-write lease-loss race).