Goal: Inventory v00
Add two new nullable fields to the Item entity — a dimensioned quantity
totalInventoryCount and a timestamp lastCountDate — and surface them for
viewing and editing across the frontend Items List View and the Item Detail
panel. This is the first inventory-count increment (v00): it establishes the
data model and end-to-end read/edit path, without inventory-movement history,
audit, or automated counting.
Status
Section titled “Status”Implemented — in review. Backend merged and released as operations 6.6.0
(PR #230); frontend PR
#984 open with all
checks green, awaiting review. Tracked as PDEV-1173.
Linear Tickets
Section titled “Linear Tickets”- PDEV-1173 — Inventory count on Item:
totalInventoryCount+lastCountDate(In Review); to be closed by arda-frontend-app #984 on merge.
Repositories
Section titled “Repositories”| Repository | Role | Planned Changes |
|---|---|---|
operations | Backend (Kotlin/Ktor/Exposed) | Add totalInventoryCount: Quantity.Value? and lastCountDate: DateTime? to the Item entity, serializer, ItemInput DTO, persistence (ITEM_TABLE/ItemRecord), and a new Flyway migration V022. Extend unit tests. |
arda-frontend-app | Frontend (Next.js/React) | Add both fields to the domain/API types and mappers; hidden-by-default grid columns (count amount + unit, and date), all inline-editable via the existing grid-edit machinery; a new “Inventory Count” group (View + Edit) in the Item Detail panel with editable, clearable inputs. |
documentation | Project + reference docs | This goal and project artifacts; update the Item current-system functional reference for the new fields. |
api-test (Bruno) is out of scope for v00 (see Out of Scope).
Success Criteria
Section titled “Success Criteria”- An Item can be created and updated with
totalInventoryCount(amount + unit) andlastCountDate(date + time) via the operations API, and both round-trip correctly through read. - Either field can be set to a value and later cleared back to null — the count via the Detail Edit panel (both amount and unit cleared), the date via either the Edit panel or inline — and the null persists on reload.
- Both fields appear in the Items List View — the count as an amount column plus a unit column (mirroring Min Qty / Min Unit), the date as a single column — all hidden by default and available via the column-visibility menu, formatted per existing conventions (en-US; empty renders as the existing placeholder).
- Both fields are inline-editable in the List View using the existing grid
editing machinery (count amount via the default editor, count unit via
UnitCellEditor, date via a date cell editor), persisting through the same PUT flow as the current editable columns. - The Item Detail View panel shows both fields under an “Inventory Count” group at the end of the panel; empty values render as the existing placeholder.
- The Item Detail Edit panel exposes both fields under an “Inventory Count” group at the end (added to the panel’s table of contents), with a number + unit input for the count and a clearable datetime input for the date.
- Backend and frontend baseline gates pass (operations
make build; arda-frontend-app lint/typecheck/tests/build); the Item current-system reference documents the two new fields.
Context
Section titled “Context”The Item entity lives in operations under
reference/item/ and is bitemporal. Two near-exact precedents guide the design:
totalInventoryCountmirrors the existingminQuantityfield — a nullable domainQuantity({ amount: Double, unit: String }), persisted as a two-column value-object component (*_amount+*_unit).lastCountDatemirrors theOrderentity’sdeliverBy— a nullableDateTime(timestamp+time_zone), the platform’s standard persisted date type (there is no date-only stored type).
The most recent comparable change is the manufacturer-field project
(migration V021), which added a nullable reference to Item; this project
follows the same shape and is the newest migration baseline (new migration =
V022).
On the frontend, the Items List View is an AG Grid whose columns are assembled
by preset builders and gated through a column-visibility menu. The grid already
supports inline editing of dimensioned quantities: Min Qty/Min Unit and
Order Qty/Order Unit are amount+unit column pairs made editable by
gridColumnEnhancers (amount via the default editor, unit via UnitCellEditor),
with edits persisted through handleCellValueChanged and the PUT flow. This is
the direct precedent for totalInventoryCount’s inline editing. The Item Detail
panel has two forms: a read-only View panel (ItemDetailsPanel, a flat
field list with no titled sections today) and an Edit panel
(ItemFormPanel, which does have titled sections + a table of contents). The
Item update path is a PUT full-document replace: a field omitted from the
request is written as null, and the edit flow already relies on this to clear
fields — so “settable back to null” needs no new mechanism.
In Scope
Section titled “In Scope”- Backend: two new nullable Item fields (
totalInventoryCountasQuantity.Value?,lastCountDateasDateTime?), including entity, hand-written serializer descriptor,ItemInputDTO +toItem, persistence (table columns, record delegates, insert,fromEntity,fillPayload), FlywayV022, and unit-test updates (DDL, model round-trip, universe fixtures, service/endpoint). - Frontend: domain
Itemtype, ARDA DTO types, and mappers (read + create + update, including clear-to-null); grid columns (hidden by default, registered in the column config + visibility menu) — an amount + unit column pair for the count (mirroring Min Qty / Min Unit) and one date column; inline editing of all three via the existing grid-edit machinery (gridColumnEnhancers+getEditableCellValue/applyEditableCellValue,UnitCellEditorfor the unit, a date cell editor for the date); “Inventory Count” group in both View and Edit detail panels with an editable number+unit input and a clearable datetime input; component tests, MSW fixtures, and Playwright specs. - Documentation: this project’s artifacts and an update to the Item current-system functional reference.
Out of Scope
Section titled “Out of Scope”- Inventory movement/transaction history, audit trail, or count reconciliation.
- Server-side sorting or filtering on the new columns (they follow the existing columns’ client-side behavior; no new backend query support in v00).
api-test(Bruno) coverage for the new fields — deferred to a follow-up.- Any new shared
ux-prototype/design-system component (the Edit inputs use existing/native controls). - Validation constraints beyond nullability (no non-negative or no-future-date guards unless added later).
Field Semantics & Defaults
Section titled “Field Semantics & Defaults”Normalization rules applied on input/save so a valid value is always persisted:
totalInventoryCount(Quantity):- amount provided, unit empty → unit defaults to “each”.
- unit provided, amount empty → amount defaults to 0.
- both empty → the field is null and renders the placeholder.
- Inline in the grid, amount and unit are separate cells edited one at a time, so clearing the field entirely to null is done in the Detail Edit panel (clear both); a single inline edit cannot null both at once. This is accepted.
lastCountDate(DateTime): a null value is still a valid, displayable state (renders the placeholder) and remains user-clearable both inline and in the Detail Edit panel. When the stored value is null, the date/time edit control pre-seeds to “now” for convenience; the user may accept it, change it, or clear it back to null.
Constraints
Section titled “Constraints”- No breaking API changes — both fields are additive and nullable; existing Item create/read/update payloads remain valid without them.
- Follow the established value-object patterns:
totalInventoryCountmirrorsminQuantity(Quantity component),lastCountDatemirrorsOrder.deliverBy(DateTime component). New migration isV022. - The Quantity component’s DB-level all-or-nothing rule (both columns null or both set) is satisfied by the normalization defaults in Field Semantics & Defaults (fill the missing half rather than reject); only both-empty is null.
- Clearing a field to null must persist through the PUT full-document-replace update path already used by the Edit panel.
- Grid columns default to hidden and are opt-in via the column-visibility menu; once shown, they follow the existing columns’ inline-edit behavior.
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved