Goal: Item Manufacturer Field
Add an optional Item Manufacturer field to the parts catalog. It captures who makes a part —
distinct from the supplier you buy it from (e.g. a part bought from Uline but made by 3M). Rather
than a plain string, the manufacturer is modeled as a BusinessAffiliate carrying a BusinessRole
of type MANUFACTURER, mirroring the recently-shipped Item → ItemSupply → Supplier(VENDOR)
linkage — and reusing it, by generalizing SupplierReference into a role-agnostic
BusinessRoleReference (PDEV-875). The value is surfaced in the item form (Ordering Details), in the
catalog filter and column, and threaded into the card / Kanban / label / breadcrumb print payloads.
Linear Tickets
Section titled “Linear Tickets”- PDEV-664 — Add Manufacturer field to parts catalog: Customer request (AVI-SPL, Pylon #404) to associate a manufacturer with each part. Primary ticket.
- PDEV-875 — Generalize SupplierReference → BusinessRoleReference:
Rename + generalize the supplier reference so it can point at any
BusinessRoleType. Executed inline as the first backend task of this project (it is the mechanism by which manufacturer reuses the supplier machinery); this project closes it.
Repositories
Section titled “Repositories”| Repository | Role | Planned Changes |
|---|---|---|
operations | Upstream (backend) | MANUFACTURER role type; PDEV-875 BusinessRoleReference generalization; manufacturer field on Item + migration; role-parameterized resolver with STRICT/PROPAGATE mode; listener + item-side cross-role query; print-payload threading (card/Kanban/label/breadcrumb). |
arda-frontend-app | Downstream (frontend) | BusinessRoleReference DTO; mapper (always-reference); generic manufacturer lookup adapter; Ordering-Details typeahead; catalog filter + column. |
documentation | Project docs | This goal, design, decision log, project plan under roadmap/reference-data/item/manufacturer-field/; promotion on completion. |
workbooks | Analysis source | The notebooks/manufacturer-field/ analysis (ba-manufacturer-changes-analysis.md) that this plan derives from. |
Success Criteria
Section titled “Success Criteria”- An item can be created/edited with an optional manufacturer via an Ordering-Details typeahead that behaves like the existing Type/Supplier typeaheads; the value persists and round-trips.
- The manufacturer is stored as a
BusinessRoleReference(roleMANUFACTURER) linked to a realBusinessAffiliate+BusinessRole, with the same find-or-create and retirement semantics as the supplier/VENDOR path. - The item create/update API accepts an optional resolution mode (
STRICT|PROPAGATE) that defaults toPROPAGATEwhen the caller omits it (a hard requirement is deferred to PDEV-1107). - Renaming or retiring a manufacturer
BusinessRolekeeps every linked item’s stored manufacturer consistent (via the listener), unless the item itself is deleted/retired. - The catalog can be filtered by manufacturer and shows an optional sortable Manufacturer column.
- The manufacturer name is present in the card, Kanban card, label, and breadcrumb print payloads (empty when unset).
SupplierReferenceis fully generalized toBusinessRoleReference(PDEV-875) with the supplier wire shape and behavior preserved (no regression to the VENDOR path).- All work follows the per-task TDD protocol (see Constraints) with self-contained, reviewable commits.
Context
Section titled “Context”This builds directly on the supplier/vendor work (PDEV-731, PDEV-928): the businessaffiliates
module in operations, the SupplierReference value object and its resolver
(ItemVendorResolver, PROPAGATE-only), the ItemSupplyRoleListener reverse-sync, and the frontend
supplier typeahead / lookup machinery. The full end-to-end analysis of the required changes — backend
and frontend — is in the workbook:
ba-manufacturer-changes-analysis.md (notebooks/manufacturer-field/).
The design and all its decisions are captured in the sibling design, decision log, and project plan.
In Scope
Section titled “In Scope”- Backend:
MANUFACTURERrole type; PDEV-875 generalization;Item.manufacturerfield + migration + persistence component; role-parameterized resolver with optionalSTRICT/PROPAGATEmode (defaults toPROPAGATE); listener keeping linked items consistent on role rename/retire; item-sidefindItemsByManufacturerRolequery. - Backend: reuse the generic role-filtered business-affiliate lookup for manufacturer suggestions.
- Backend: thread the manufacturer name into the card, Kanban card, label, and breadcrumb print payload builders.
- Frontend: always-reference
BusinessRoleReferenceDTO + mapper; generic manufacturer lookup client- adapter + Redux cache; Ordering-Details typeahead (“Item Manufacturer”); catalog filter + optional sortable column; mocks + unit + mock-mode E2E.
Out of Scope
Section titled “Out of Scope”- Manufacturer management screens (list/create/edit/merge of manufacturers as first-class entities) — a deliberate follow-up. The denormalized reference fields are added now to support it.
- Print-template layout/
testData.jsonchanges in the printing-templates repo — deferred to a follow-up ticket (this project only guarantees the data is present in the payloads). - Bulk-import round-trip of
item.manufacturer— deferred to a follow-up ticket, created after the backend is complete so it can carry concrete specifics.
Constraints
Section titled “Constraints”- Coding standards adherence is mandatory and strict. Before implementing in each repo, read and
follow the relevant skills:
kotlin-coding,unit-tests-backend,unit-tests-infra(backend);typescript-coding,react-best-practices,ui-component,unit-tests-frontend(frontend); plusgeneral-conventions. Honor the monadic error channel (Result/AppError, smart constructors,.unitify()), single-exit style, and config-driven test assertions. - Per-task TDD protocol. Each incremental task: (a) write unit tests that compile — production
types/signatures defined (stubbed with
TODO()for Kotlin) — and fail because the behavior is absent; (b) implement until unit tests pass; (c) add integration/E2E tests as needed; (d) land a single self-contained, reviewable commit. Exception: the PDEV-875 rename (Phase 1, T-01) is a refactor — the existing suite must stay green throughout; tests-first applies only to the newrole/MANUFACTURERbehavior. - Backend e2e = ContainerizedPostgres integration tests inside
operations(resolver both modes, listener, retired guard, item round-trip). Noapi-test/Bruno worktree. - No
common-modulechange —SupplierReferencelives inoperations. - Wire compatibility — PDEV-875 preserves the supplier JSON shape; the VENDOR path must not regress.
- Single-agent, sequential execution across the existing worktrees; no integration branch.
- Push guards — narrow staging; never
git add -A(guard against sweeping a compositeincludeBuildintosettings.gradle.kts); run the local gate before every push.
Deliverables
Section titled “Deliverables”| # | Deliverable | Location |
|---|---|---|
| 1 | Design document | design.md |
| 2 | Decision log | decision-log.md |
| 3 | Project plan (phased, TDD tasks) | project-plan.md |
| 4 | operations changes + PR | branch jmpicnic/pdev-664-manufacturer-field |
| 5 | arda-frontend-app changes + PR | branch jmpicnic/pdev-664-manufacturer-field |
Reference Documents
Section titled “Reference Documents”- Design Document — architecture, diagrams, API contract, testing strategy.
- Decision Log — the resolved design questions (DQ-001…).
- Project Plan — phased, TDD-structured task list and sequencing.
- Workbook analysis —
workbooks/notebooks/manufacturer-field/ba-manufacturer-changes-analysis.md. - PDEV-664 spec — Spec — Item Manufacturer field.
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved