Repository navigation
QE-07: an order held by price exposure answers 409 with its blockers - #263
Open
futurebuildai wants to merge 8 commits into
Open
futurebuildai wants to merge 8 commits into
futurebuildai wants to merge 8 commits into
Conversation
Confirming or fulfilling an order whose source quote carries an unresolved lumber-index exposure is refused by the service with the pricing exposure error, which the two handlers pass to the error writer unmapped, so the desk sees 500 internal_error. Four wire tests state the contract: the 409 with the exposure blockers (the blocker code and the quote) on confirm and on fulfil, and the confirm that goes through after the customer acknowledges the price change on the quote or an owner overrides the gate. Signed-off-by: colton <colton@futurebuild.ai>
… fulfil HandleTransition and HandleFulfil pass the pre-ship gate's pricing exposure error through exposureBlockers onto the same 409 conflict envelope the exposure-gate route answers, instead of the error writer's 500 internal_error, so the dealer is told which quote holds the order and what clears it. The delivery assign route already mapped the error; the order module's two write routes now agree with it. Signed-off-by: colton <colton@futurebuild.ai>
Confirm Order and Fulfil Order catch the pre-ship gate's 409 and render the blockers inline: which quote holds the order (linked by its number), the indexes that moved and the exposure dollars, and the two ways clear, the customer acknowledging the price change on the quote or an owner overriding the gate. A refusal is no longer a generic error toast. The figures and the number are read best effort after the refusal, so the panel still speaks when those reads fail. Signed-off-by: colton <colton@futurebuild.ai>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: colton <colton@futurebuild.ai>
…mmodity The seed catalog holds more than one page of products, so the framing stud was not always in the first 200. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: colton <colton@futurebuild.ai>
…anned Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: colton <colton@futurebuild.ai>
…ate can arm Migration 081 backfills is_commodity on the lumber subtree, but migrations run before the seed, on an empty products table, so every seeded lumber product kept the flag false and a quote send snapshotted no price escalator. seedQECommodities (core/internal/app/seed/qe.go) runs the same backfill from Run after every product insert, covering the base seed and the opt in catalogue import. The characterization goldens re-recorded through the harness's -update: the quote exposure answer now names the framing composite in indexes, and the quote.exposure.ack_required event data carries index_code, both with state and dollars unchanged. Signed-off-by: colton <colton@futurebuild.ai>
…wers the same blockers The spec now finds the framing stud by a SKU the seed actually makes (LUM-248-PREM, or DL_SPF_2X4_L08_S under the catalogue import), quotes a quantity of ten that stays under the seeded stock, and sends the convert with If-Match carrying the quote's revision as the quote last answered it, asserting 201. Releasing a held order can meet the same exposure refusal as confirm and fulfil, so handleRelease shows the blocker panel instead of a generic toast, with a unit test beside it. Signed-off-by: colton <colton@futurebuild.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
QE-07: confirming or fulfilling an order held by quote price exposure now answers 409 with its blockers (it was 500), and the desk says so in plain words.
Row (audit QE-07 settlement 1, slice QE-07-a first backend bullet): a dealer who confirms an order whose source quote has an unresolved price exposure needing acknowledgement gets the gate's blockers, not a server error.
What was not true and is now:
HandleTransitionandHandleFulfilpassedErrUnresolvedExposuretohttpx.WriteError(500). Both now map it throughexposureBlockersto the same 409HandleExposureGateanswers. The delivery handler already mapped it.OrderDetailshows a panel on that 409 naming the source quote (linked), the indexes and exposure dollars when readable, and the two ways clear: the customer acknowledges on the quote, or an owner overrides.Tests:
internal/order/qe07_exposure_test.go):TestQE07_ConfirmBlockedByExposureAnswers409,TestQE07_FulfilBlockedByExposureAnswers409,TestQE07_ConfirmAfterAcknowledgeSucceeds,TestQE07_ConfirmAfterOverrideSucceeds. Each mapping removed in turn shows red (confirm three tests, fulfil one), restored green.OrderDetail.test.ts): blockers from a confirm 409 and from a fulfil 409.web/e2e/order-exposure-gate.spec.ts.Money checklist: 1 n/a (no new check and write pair, the gate only maps an existing refusal); 2 n/a; 3 n/a (no new lock); 4 n/a (no new money write, no transaction added); 5 n/a; 6 done (server enforces, screen only reports); 7 n/a; 8 done (gate read at confirm and fulfil); 9 n/a; 10 n/a; 11 n/a; 12 n/a; 13 n/a; 14 n/a; 15 n/a (gate runs under the existing order wall); 16 done (test asserts the refused confirm leaves the draft on revision 1); 17 n/a; 18 done (apicontract and characterization green, no contract change); 19 not yet run by me (see lead report); 20 done (desk vitest clean).
Model: Sonnet 5.5 finished it; the first commits were written by GLM-5.3.
🤖 Generated with Claude Code