Skip to content

Project Plan: Connect Item.Supply to Business Affiliate References

Implements the design in design.md: replace the ad-hoc supplier link on ItemSupply with a canonical SupplierReference targeting the VENDOR BusinessRole, react to supplier removal with a stale marker (PDEV-808 pattern), extract a dedicated ItemSupplyService, and add canonical reference-data routes. Decisions are tracked in decision-log.md. DQ-001..DQ-006 and DQ-008..DQ-010 are decided; the one deferred question — DQ-007 (event source, resolved at T-08) — is settled within the phase it gates, before the work it affects is written.

RepositoryRoleBranch
operationsupstream (code + unit/integration tests)jmpicnic/connect-supply-to-supplier
api-testdownstream (Bruno API tests)jmpicnic/connect-supply-to-supplier
documentationdocs (design + current-system + url-naming)jmpicnic/connect-supply-to-supplier
workbooksresearch/design notes (not a PR deliverable)jmpicnic/connect-supply-to-supplier

No cross-repo composite build (includeBuild) is used for this work, so there are no local path-override revert tasks; the standard push guards still apply.

Worktrees, branch jmpicnic/connect-supply-to-supplier, baseline operations build (green), and goal.md are complete.

Phase 1: Information model & persistence (operations)

Section titled “Phase 1: Information model & persistence (operations)”

Entry criteria: DQ-006 (resolution shape) and DQ-008 (lazy re-link) decided.

#TaskRepositoryDepends OnAcceptance Criteria
T-01Add SupplierReference value object (eId, affiliateEId?, rId, name, retired, provenance)operationsCompiles; validate() per smart-constructor convention
T-02Add SupplierReferenceComponent (flattened SUPPLIER_REFERENCE_* columns)operationsT-01Component maps all fields
T-03Replace supplierEId+supplier in ItemSupply / ItemSupplyReference / Item with SupplierReferenceoperationsT-01Types updated; serialization intact
T-04Flyway migration: add SUPPLIER_REFERENCE_* columns, drop legacy supplier_eid/supplier columns (lazy re-link, no backfill — DQ-008)operationsT-02,T-03Migration applies on ContainerizedPostgres; legacy rows read as unlinked/floating

Exit criteria: ./gradlew build passes; migration + persistence integration tests green.

Phase 2: Service extraction & supplier resolution (operations)

Section titled “Phase 2: Service extraction & supplier resolution (operations)”

Entry criteria: Phase 1 exit; DQ-006 decided.

#TaskRepositoryDepends OnAcceptance Criteria
T-05Extract ItemSupplyService from inner SupplyServiceoperationsT-03ItemService delegates; behavior parity unit tests pass
T-06Retarget ItemVendorResolver to VENDOR role; emit SupplierReference; reduce qualifiers to STRICT + create-on-the-fly (drop LAX, DQ-011); reject retired suppliers (DQ-012)operationsT-05STRICT + create-on-the-fly covered; LAX removed; retired-supplier creation rejected
T-07Add BA-side role resolution capability if DQ-006=Option BoperationsT-06Resolves VENDOR role; respects cross-Universe rule

Exit criteria: Supplier create/link/resolve unit tests green for all qualifier modes.

Phase 3: UC5 stale-marker reaction (operations)

Section titled “Phase 3: UC5 stale-marker reaction (operations)”

Entry criteria: Phase 2 exit; DQ-010 decided. DQ-007 (event source) is resolved within this phase at T-08, before the subscription is wired.

#TaskRepositoryDepends OnAcceptance Criteria
T-08Subscribe ItemSupplyService to VENDOR role (and/or BA) deletion per DQ-007operationsT-05Handler receives delete events
T-09On removal, mark affected supplies stale (retired+pinned rId+provenance), keep dataoperationsT-08Supplies not deleted; flag set; parent Item refs updated
T-10Retired-reference resolution path (tombstone read)operationsT-09Stale supply resolves with last-known supplier state

Exit criteria: UC5 unit + integration tests green; name-change propagation regression intact.

Phase 4: Canonical reference-data routes (operations)

Section titled “Phase 4: Canonical reference-data routes (operations)”

Entry criteria: Phase 2 exit; DQ-009 decided.

#TaskRepositoryDepends OnAcceptance Criteria
T-11Add canonical 5-segment routes (all singular): Item /v1/reference-data/item/item/item/..., ItemSupply (own endpoint) /v1/reference-data/item/item-supply/supply/{item-eId}/..., BA .../business-affiliate/business-affiliate/business-affiliate/.... Kotlin/Ktor routes only (no Helm/Cfn).operationsT-05Canonical routes serve ops; legacy aliased
T-12Retain/deprecate legacy routes per DQ-009operationsT-11Legacy aliases behave per decision

Exit criteria: ./gradlew build passes; route tests green.

Entry criteria: Phases 3–4 exit (routes + behavior available).

#TaskRepositoryDepends OnAcceptance Criteria
T-13Bruno requests for UC1–UC4 against canonical routes, chaining supplier eIdsapi-testT-11Requests pass against local cluster
T-14Bruno scenario for UC5 (remove supplier → supply shows retired=true)api-testT-09Assertion on stale flag passes

Exit criteria: check-api-test-results green for the new collections.

Entry criteria: Design stable (Phases 1–4 substantially landed).

#TaskRepositoryDepends OnAcceptance Criteria
T-15current-system design page for Item↔BusinessAffiliate supply linkagedocumentationT-09Page builds; PlantUML renders
T-16Align assets/items.md + assets/business-affiliates.md to the new modeldocumentationvendorEId/supplierEId reconciled to SupplierReference→VENDOR role
T-17Document reference-data route convention in url-naming.mddocumentationT-11Convention documented

Exit criteria: make pr-checks passes in the documentation worktree.

Entry criteria: All prior phases’ exit criteria met; all DQs Decided/Deferred.

#TaskRepositoryDepends OnAcceptance Criteria
T-18operations CHANGELOG.md entry (direct-edit model)operationsT-12make clqLint passes
T-19api-test CHANGELOG entry (per repo model)api-testT-14CI changelog gate passes
T-20documentation PR-body ## CHANGELOG sectiondocumentationT-17changelog-check passes
T-21Open PRs; run pr-steward on eachallT-18..T-20CI green; threads resolved
T-22Move project docs in-progresscompleteddocumentationT-21Docs relocated on completion

Merge ordering: operations first (provides routes/behavior), then api-test (exercises them), documentation independently. No inter-repo build dependency forces ordering; ordering is for coherent review/verification.

Phases are largely sequential within operations; Phases 3 and 4 can proceed in parallel once Phase 2 lands. api-test and documentation follow.

PlantUML diagram

Single-agent project; the implementing engineer works all repositories on one branch. Should it be parallelized later, a back-end-engineer owns operations, an acceptance-test-engineer owns api-test, and a technical-writer owns documentation.

PersonaWorking DirectoryAgent Name Pattern
back-end-engineerprojects/connect-supply-to-supplier-worktrees/operationsbe-supply-link
acceptance-test-engineerprojects/connect-supply-to-supplier-worktrees/api-testat-supply-link
technical-writerprojects/connect-supply-to-supplier-worktrees/documentationtw-supply-link
  • Branch jmpicnic/connect-supply-to-supplier across all four worktrees under projects/connect-supply-to-supplier-worktrees/.
  • Single-agent: no integration branch; each repo’s branch becomes its PR.
  • Run lint/typecheck/tests (and make pr-checks for documentation) before any push. Push guard: never push workbooks design notes into a code PR.
  • On completion: verify no uncommitted changes, push all branches, then remove worktrees and local branches.


Copyright: (c) Arda Systems 2025-2026, All rights reserved