Specification: Inventory v00
Driving specification for Inventory v00. It sequences the work for the implementing engineer and references the requirements, analysis, verification, and the precise implementation changes. Read the goal first for scope and the settled decisions.
Overview
Section titled “Overview”Add two nullable fields to Item — totalInventoryCount (a Quantity) and
lastCountDate (a DateTime) — and surface them for viewing and editing in the
Items List View (inline) and the Item Detail panel (View + Edit), grouped under
an “Inventory Count” group. The change is additive and backward compatible; both
fields reuse existing precedents (minQuantity, Order.deliverBy).
Quality guidelines
Section titled “Quality guidelines”- Backend follows
kotlin-codingconventions (monadic error channel, single exit, nogetOrNullcollapsing errors); frontend followsreact-best-practicesand the repo’s mapper/type discipline (never usearda-apitypes in UI — map throughardaClient). - Match surrounding style; surgical edits only — every changed line traces to a requirement.
- Each field’s four-place backend footprint (entity + serializer descriptor, DTO
toItem, persistence columns/record, migration) must stay in sync — a missed serializerelement(...)orfillPayloadline is the most likely defect.
- Do not edit
CHANGELOG.mdindocumentation(PR-body changelog);operationsandarda-frontend-appfollow their repos’ changelog models (see Phase D).
Worktree Strategy
Section titled “Worktree Strategy”Single agent, three repositories, one worktree each — already created under
projects/inventory-v00-worktrees/ on branch jmpicnic/inventory-v00:
operations/, arda-frontend-app/, documentation/. Different repositories and
a single writer, so no integration branch and no per-task worktrees are
needed. Each repository produces one PR from its jmpicnic/inventory-v00
branch to its main.
Phase A — operations (backend data contract)
Section titled “Phase A — operations (backend data contract)”Implements REQ-INV-001…008. Precise edits in implementation-changes.md.
- Add
totalInventoryCount: Quantity.Value?andlastCountDate: DateTime?to theIteminterface andEntity, and the matchingelement(...)lines toItemSerializer. - Add both to
ItemInputandtoItem(). - Add persistence:
quantityComponent("total_inventory_count")anddateTimeComponent("last_count_date"), plusvardelegates, insert lambda,fromEntity, andfillPayload. - Add Flyway migration
V022__inventory_count.sql(four nullable columns). - Encode the REQ-INV-006 normalization defaults (amount ⇒ unit
"each"; unit ⇒ amount0; both empty ⇒ null) at the input/mapping boundary. - Extend unit tests:
ItemDDLTest,ItemInputModelTest,ItemUniverseTestData- universe/service/endpoint tests.
- Gate:
make buildgreen (Gradle + coverage).
STOP — review Phase A (data contract, migration, normalization semantics) before starting the frontend, since the DateTime wire shape (Decision D3) is a dependency for the mappers.
Phase B — arda-frontend-app (views + editing)
Section titled “Phase B — arda-frontend-app (views + editing)”Implements REQ-INV-010…023. Precise edits in implementation-changes.md.
- Types: add both fields to the domain
Item(items.ts), the ARDA DTO types (arda-api.ts),ItemFormState, andItemCard(constants/types.ts). - Mappers (
ardaMappers.ts): read inmapArdaItemToItem; write inmapItemToArdaCreateRequestandmapItemToArdaUpdateRequest, omitting empties for clear-to-null. - Grid: add count amount + unit columns and a date column (
hide: true); register initemTableConfig.tsandColumnVisibilityMenu.tsx. - Inline edit (
gridColumnEnhancers.tsx): addgetEditableCellValue/applyEditableCellValuecases; attachUnitCellEditorto the count-unit path and a date cell editor to the date path (Decision D2). - Detail View (
ItemDetailsPanel.tsx+convertItemToItemCard): add the titled “Inventory Count” group at the end. - Detail Edit (
ItemFormPanel.tsx): add the “Inventory Count” section after the last section; register it intocSections; prefill; emit in the submit builder with empty ⇒ undefined; date pre-seeds to now when empty (REQ-INV-023). - Tests/mocks/e2e: extend
mockItems.ts, component tests, and Playwright specs. - Gate:
make ci-replicategreen (lint, typecheck, unit, e2e).
STOP — review Phase B (UX of the group, inline-edit behavior, clear-to-null) before documentation.
Phase C — documentation
Section titled “Phase C — documentation”Implements REQ-INV-030.
- Update the Item current-system functional reference
(
current-system/functional/operations/inventory/…/ the Item reference page) to document both fields, their nullability, and the normalization/default behavior. - Move this project’s docs from
drafttoward completion per the project lifecycle when the code lands. - Gate:
make pr-checksgreen (link check + smoke).
Phase D — release
Section titled “Phase D — release”- Each repository raises its own changelog entry and PR as soon as its work
is complete — the three PRs are independent; there is no cross-repo merge
ordering to enforce here.
operationsandarda-frontend-app: changelog per their repo models.documentation: changelog via the PR body## CHANGELOGsection.
- Merging to
mainand deployment to servers are coordinated by the user outside this project. Do not merge; usepr-stewardonly to monitor checks and resolve review threads on each PR after it is opened.
Open Questions and Decisions
Section titled “Open Questions and Decisions”| # | Question | Options | Recommendation | Decision |
|---|---|---|---|---|
| D1 | Grid representation of the count | (a) two columns amount+unit; (b) single composite column; (c) amount only | (a) — mirrors Min Qty/Min Unit and reuses inline-edit machinery | Decided (a) |
| D2 | Inline date editor granularity | (a) DS DateCellEditor (date only); (b) custom datetime-local editor | (a) | Decided (a) — inline captures the date and stores it as noon (12:00) in the hinted timezone (noon avoids off-by-one date shifts under tz/DST conversion); full date+time is editable in the Detail panel |
| D3 | DateTime wire representation on the frontend | (a) carry ISO string in domain, convert in the mapper; (b) carry raw shape in the domain | (a) | Decided (a) — DateTime JSON is { "timestamp": <epoch millis>, "tz": "<IANA name>" } (tz serializes via @SerialName, e.g. "America/New_York"); the frontend carries an ISO string and the mapper converts both ways |
| D4 | Amount default when unit set first | (a) 0 per REQ-INV-006; (b) 1 per the minQuantity precedent | (a) | Decided (a) — deliberate divergence from minQuantity |
| D5 | Timezone for lastCountDate | (a) browser default; (b) explicit UTC | (a) | Decided (a) — browser tz is the hint for noon-of-date; operational clock is UTC, so normalize on display |
| D6 | Grid column labels & placement | Labels “Total Inventory Count”, “Count Unit”, “Last Count Date”; in the meta/detail column group | As proposed | Decided |
All decisions are resolved; none remain open.
Acceptance Checklist
Section titled “Acceptance Checklist”All requirements verified per verification.md:
- REQ-INV-001…002 — both fields exist on
Itemwith correct types/nullability - REQ-INV-003…005 — create/read/update round-trip; omission clears to null and persists
- REQ-INV-006 — normalization defaults (each / 0 / null) hold
- REQ-INV-007…008 — no new validation; existing payloads unaffected
- REQ-INV-010…013 — three hidden-by-default, inline-editable, correctly formatted columns
- REQ-INV-014 — single inline edit cannot null the whole count
- REQ-INV-020…021 — “Inventory Count” group in View and Edit (in ToC), correct inputs
- REQ-INV-022…023 — clear-to-null persists; null date pre-seeds to now
- REQ-INV-030 — Item functional reference updated
-
operationsmake build,arda-frontend-appmake ci-replicate,documentationmake pr-checksall green - One PR per repo with a changelog entry, each raised independently as its work completes (no enforced cross-repo merge ordering — see Phase D)
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved