Skip to content

Inventory traceability register: OPAL# page in family, kitting shows provenance#66

Merged
CST-100 merged 1 commit into
features/issues-exec-parts-r2from
claude/inventory-traceability-register
Jul 6, 2026
Merged

Inventory traceability register: OPAL# page in family, kitting shows provenance#66
CST-100 merged 1 commit into
features/issues-exec-parts-r2from
claude/inventory-traceability-register

Conversation

@CST-100

@CST-100 CST-100 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Live-rehearsal feedback (Mojave Sphinx): two entangled display problems around physical-inventory traceability. Scope: the OPAL # detail page and the execution KITTING/BOM tabs plus their contexts. Deliberately does not touch the PR #65 files (db-id purge elsewhere).

Item 1 — OPAL # detail page rebuilt in the part-page grammar

Before: a loose auto-fit strip of label/value pairs; TRACEABILITY HISTORY as prose sentences ("Quantity: 8.0 in Execution #1") with a database id where the work-order number belongs; the source PO rendered twice (header strip + a "Source:" box that also leaked a purchase-line db id); a TESTS panel that narrated its own emptiness twice ("No tests recorded" / "No test results recorded"); a separate SOURCE PRODUCTION panel duplicating the source fact.

After (src/opal/web/templates/inventory/opal_detail.html, route context in src/opal/web/routes.py):

  • Panel header OPAL ITEM carries RECORD CALIBRATION / PRINT LABEL / ADJUST QTY / SCRAP; QR block kept.
  • Facts are detail rows (data-table part-identity): PART is the internal PN linked to the part (name alongside), EXTERNAL PN, LOCATION, QUANTITY with UoM, LOT, SOURCE, SERIAL (produced items), EXPIRATION, calibration rows (tooling only), RECEIVED — ISO-8601 throughout, absence is a muted dash.
  • One fact, one home: the source PO/WO renders exactly once, in the SOURCE row (linked PO-… or the work-order number); the duplicate strip and the SOURCE PRODUCTION panel are deleted, serial folds into the fact table.
  • TRACEABILITY HISTORY is a headed table: TIMESTAMP · EVENT state-word (RECEIVED/CONSUMED/SCRAPPED/TOOLING in state colors, plain words not badges) · signed QTY · CONTEXT link. Consumptions link /executions/{id} labeled by the work-order number (carried into the history via the consumption's procedure_instance), never "Execution #N".
  • TESTS follows the empty-state rule: recorded results render as a headed table (with the pass/fail summary and + RUN); a part with declared test templates but no results is one line — TESTS — none · N REQUIRED · + ADD; no templates and no results → the section is absent. Both narration strings are gone, including the JS-injected one.
  • Record query eager-loads part and consumptions→procedure_instance (no N+1).

Item 2 — KITTING consumption rows are traceable

Before: consumed rows showed part name only + qty/location/lot/step — no internal PN, no OPAL #; the CONSUME FROM options read STORE-A2 (5.0000).

After:

  • Consumed table (executions/tabs/kitting.html): PART (internal PN linked) · NAME · OPAL # (linked to /inventory/opal/{n}) · QTY · LOT · LOCATION · STEP (step number, never an id).

  • Consume-from option label — one home (invSourceLabel in src/opal/web/static/js/execdoc.js, used by both the KITTING tab and the document step-kit selects):

    OPAL-00164 · STORE-A2 · 5 EA · LOT-2026-03
    

    OPAL # first (omitted only if the record has none), then location, quantity with the part's UoM (%g-style, no trailing zeros), lot only when present.

  • Feeding data: /api/procedure-instances/{id}/kit-availability locations now carry opal_number (+ item-level uom); /api/inventory responses now carry part_uom (additive fields).

  • tabs/bom.html PART column: internal PN linked + name (also for unplanned consumptions); kit / production / output tables on the kitting tab name parts by PN the same way.

  • Kit, consumption, and production queries in _execution_detail_context eager-load their part traversals.

Tests

  • test_inventory.py: 3 new render tests — facts as detail rows with linked PN and zero narration; consumption history links the WO number (asserts Execution #<id> absent); TESTS empty-state ladder (absent → declared empty line with 1 REQUIRED → results table).
  • test_execution_document_web.py: 2 new — consumed rows carry PN + OPAL # links; pre-consume kit table and BOM tab name the PN.
  • test_execution.py::test_kit_availability extended for the new opal_number/uom fields.

uv run pytest --no-cov -q: 821 passed, 1 skipped. ruff check src/: clean.

🤖 Generated with Claude Code

…provenance

ITEM 1 — /inventory/opal/{n} rebuilt in the part-page grammar: panel header
carries the actions, facts render as detail rows (part linked by internal PN,
location, quantity+UoM, lot, source, received ISO-8601), the source PO/WO
fact folds into the SOURCE row (one fact, one home — the duplicate strip and
SOURCE PRODUCTION panel are gone). TRACEABILITY HISTORY is a headed table
(TIMESTAMP / EVENT state-word / QTY / CONTEXT) where consumptions link the
execution labeled by its work-order number, never "Execution #<db id>".
TESTS follows the empty-state rule: results render as a table, a declared
template with no results is one empty line, undeclared+empty is absent —
both narration strings are gone.

ITEM 2 — Execution KITTING consumed rows carry the physical-item identity:
internal PN linked to the part and OPAL # linked to /inventory/opal/{n},
plus lot/location/step. The CONSUME FROM options get one label home
(invSourceLabel in execdoc.js): "OPAL-00164 · STORE-A2 · 5 EA · LOT-…",
fed by opal_number/uom now exposed on /kit-availability and part_uom on
/api/inventory — the document step-kit selects share the pipeline. BOM tab
and kit/production/output tables name parts by internal PN.

Kit/consumption/production part traversals are eager-loaded (no N+1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant