Make the invoice balance before creating rows
A purchase request contains more than a total to save. The service validates its fields, resolves the supporting document and converts amounts into bigint minor units. The calculator then rebuilds discounted lines, invoice components and allocated totals.
A missing document or nonzero allocation variance stops the write before the transaction begins. That gives storage an already-checked calculation to record instead of asking it to persist an invoice whose lines don't add up.
Identify the request and the purchase separately
Inside BEGIN IMMEDIATE, the wrapper checks the retry key against an operation name and canonical request digest. Matching both returns the saved result. Changing either fails, even if the caller reuses the old key.
A new key doesn't necessarily mean a new purchase. The purchase action separately rejects an existing invoice, and existing product IDs can't silently switch their product or supplier association. Request identity helps replay an operation; it doesn't replace the identities of the records being written.
Give the rows and receipt one outcome
The header, allocated lines, stock receipts, linked audit event and retry receipt commit together. An exception rolls them all back. Saving the receipt later could leave a purchase with no replay result; saving it first could claim success for a purchase that never committed.
This result confirms a local record, not an update to an external account. External work needs its own readback. The audit actor also comes from the trusted local caller, rather than a hosted authentication system.
The inspected tests cover exact retries, existing invoices sent with new keys, changed requests under used keys and attempts to edit audit rows. They weren't rerun, and no ledger data or external accounts were opened for this note.
Purchase mutation and retry branches
The same database transaction owns new business rows, the audit event and the replayable result.
Caller and response
Core operation
SQLite
Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.
Choose a component to explore
Select a numbered component on the map or use the component menu. Its details and connections will appear here.
No component selected.
All connections (10)
- 01 · Purchase request → 02 · Input and evidence checksstrict contract · Direct call
- 02 · Input and evidence checks → 03 · Exact allocationvalid input · Direct call
- 03 · Exact allocation → 04 · BEGIN IMMEDIATEbalanced allocation · Direct call
- 04 · BEGIN IMMEDIATE → 05 · Retry receiptslookup retry key · Direct call
- 05 · Retry receipts → 06 · Request and business identitysaved identity or absent · Response / return
- 06 · Request and business identity → 09 · CORE_RECORDED resultexact replay · Response / return
- 06 · Request and business identity → 08 · Typed failurechanged key use or duplicate invoice · Blocked / denied
- 06 · Request and business identity → 07 · Atomic record groupnew accepted operation · Direct call
- 07 · Atomic record group → 09 · CORE_RECORDED resultcommit · Response / return
- 07 · Atomic record group → 08 · Typed failureexception and rollback · Blocked / denied