Repository navigation
C3-1b: the inventory read on the contract - #48
Conversation
… facts The levels list as the ADR 0001 envelope with the cursor walk and include=total; each row's quantities as scale 4 decimal strings with available (quantity - allocated) and the stocking unit's uom beside them (ADR 0006 7.2); the product summary under include=product and only there; product_id and location_id as filters; unknown parameters, bad values, bad limits and malformed cursors refused naming the field. The branch wall arm of the serve wiring test now reads the envelope, so an empty grant list answers an empty page, never every branch's rows. Both tests fail on the base commit b5151dc: the route answers a bare array of float quantities with no unit, no available and no paging, and the wall test cannot decode it as a page.
GET /api/v1/inventory is the levels list of ADR 0006 7.2: the ADR 0001 envelope, keyset paged on (created_at, id) newest first, every quantity a scale 4 decimal string in the product's stocking unit with available (quantity - allocated) and uom beside it, the location's name beside its id, the product summary embedded under include=product and only then, product_id and location_id as filters that filter, and the strict query guard (unknown parameters, bad UUIDs, bad limits, malformed cursors and unknown include names are 400s naming the field, where the base answered a bare array and 500'd a bad product_id). The branch wall PR 44 settled is kept statement for statement in the page and the count. Migration 098 gives inventory the created_at its ordering keys on (backfilled from updated_at, NULLs filled, NOT NULL with a default for raw writers) and the keyset index; the down drops both. The read side only: no write path, no Qty function, no cycle 2 module touched. The portal's in-process read (ListByProduct) stays as the unconverted float seam, the pattern of product's QtyFloat.
The fragment declares the envelope (InventoryLevelPage), the row (InventoryLevel) and the product summary embedded under include=product (InventoryProductSummary, the expansion ADR 0001 section 1 names); the model shape test binds the two new wire structs. The goldens pin the converted read: the empty page is [], the transfer group's list reads the envelope with include=product and the unknown parameter's 400, and the sales group's unfiltered page replaces the missing product_id 400 (product_id is now a filter). Three CONTRACT-CHANGES rows.
The desk's InventoryService reads items from the cursor envelope (the levels wire of C3-1b): quantities arrive as scale 4 decimal strings with available and uom beside them, so the stock tab and the yard lookup sum and display them through the money helpers (the sums on the scaled integers, one division at the end), the transfer modal lists locations by location_name and caps the move on the parsed quantity, and the Inventory type drops the deprecated location text. The fulfilment e2e helper reads the page's available strings. No screen layout changes.
|
Review of PR 48 (C3-1b, inventory levels read), head cb654b4, base refactor/v1. Reviewer: Sonnet 5.5, round 1. Verdict: CLEAN (no P1, no P2; three P3). Checked
Findings
Exit test lines run (worktree wt/rev-48 at cb654b4, container gv1-rev48-pg on 55464, URL on each command)
Not verifiedDesk screens and a local typecheck of the desk (hosted CI's Frontend and Playwright jobs stand for them). Contract-ts was not run locally. CleanupWorktree |
PR 48 second review (data class), Sonnet 5.5PR: #48 (refactor/c3-1b-inventory-read, head cb654b4) into refactor/v1. Verdict: CLEAN (no P1, no P2; two P3 notes) Probes (my own, on gv1-rev48b-pg port 55465, URL on each command)
Exit tests run
Findings
Checked and fineSPDX headers on migration, down, levels.go and the new tests; no secret, dealer or person content; no transaction opened (reads go through Not checkedWeb (vitest, tsc, e2e/Playwright) was not run; only the Go side and the desk diff read. Hosted CI status not read. CleanupWorktree wt/rev-48b removed ( |
C3-1b, the inventory read ADR 0006 7.2 states, held from C3-1 until C2-2 merged (ADR 0006 9.1). The read side only: no write path of
inventory/service.go, none of the C2-2b Qty functions, no cycle 2 module.What changes
GET /api/v1/inventoryis the levels list on the ADR 0001 envelope, keyset paged on(created_at, id)newest first:items,next_cursor,limit,totalunderinclude=total.available(quantity - allocated) anduombeside it;location_idandlocation_name(the location's path, else the row's legacy text) replace the deprecatedlocationfloat row; the product summary (id,sku,description,stock_uom) is embedded underinclude=productand only then (the expansion ADR 0001 section 1 names).product_idandlocation_idare optional filters that filter (noproduct_idis the whole levels list, where the base 400'd); unknown parameters, repeated filters, non-UUID filter values, bad limits, malformed or foreign cursors and unknown include names are 400s naming the field in the ADR 0001 error envelope (a non-UUIDproduct_idwas a 500 on the base).include=totalcount, and is pinned through serve's real wiring (TestBranchWall_InventoryListGrantsreads the envelope now).inventorythecreated_atits ordering keys on (backfilled fromupdated_at, NULLs filled, NOT NULL with a default) and the keyset index; the down drops both.InventoryServicereadsitems, the stock tab, yard lookup and transfer modal sum and display the decimal strings through the money helpers, the fulfilment spec helper readsavailable.inventoryandinventory_transferre-recorded; three CONTRACT-CHANGES rows. The integration and AI load management goldens are untouched.Tests
Failing first on the base commit b5151dc (bare array, floats, no envelope): the new wire tests and the serve wall test, shown failing in a throwaway worktree of the base. Then: wire tests (envelope, cursor walk, filters, 400s, include=product/total, empty page bytes), the migration test on a scratch database (backfill on rows that exist, down, idempotent re-up), the wall arms through serve's mounts, and Playwright on the real stack (25 passed).
No transaction is opened by this change (a read-only page and count), so the recipe's transaction proofs carry no write to prove; the wall test rides the real serve wiring as the brief requires.