Project Plan: Connect Item.Supply to Business Affiliate References
Overview
Section titled “Overview”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.
Repositories
Section titled “Repositories”| Repository | Role | Branch |
|---|---|---|
operations | upstream (code + unit/integration tests) | jmpicnic/connect-supply-to-supplier |
api-test | downstream (Bruno API tests) | jmpicnic/connect-supply-to-supplier |
documentation | docs (design + current-system + url-naming) | jmpicnic/connect-supply-to-supplier |
workbooks | research/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.
Phases
Section titled “Phases”Phase 0: Setup — DONE
Section titled “Phase 0: Setup — DONE”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.
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-01 | Add SupplierReference value object (eId, affiliateEId?, rId, name, retired, provenance) | operations | — | Compiles; validate() per smart-constructor convention |
| T-02 | Add SupplierReferenceComponent (flattened SUPPLIER_REFERENCE_* columns) | operations | T-01 | Component maps all fields |
| T-03 | Replace supplierEId+supplier in ItemSupply / ItemSupplyReference / Item with SupplierReference | operations | T-01 | Types updated; serialization intact |
| T-04 | Flyway migration: add SUPPLIER_REFERENCE_* columns, drop legacy supplier_eid/supplier columns (lazy re-link, no backfill — DQ-008) | operations | T-02,T-03 | Migration 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.
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-05 | Extract ItemSupplyService from inner SupplyService | operations | T-03 | ItemService delegates; behavior parity unit tests pass |
| T-06 | Retarget ItemVendorResolver to VENDOR role; emit SupplierReference; reduce qualifiers to STRICT + create-on-the-fly (drop LAX, DQ-011); reject retired suppliers (DQ-012) | operations | T-05 | STRICT + create-on-the-fly covered; LAX removed; retired-supplier creation rejected |
| T-07 | Add BA-side role resolution capability if DQ-006=Option B | operations | T-06 | Resolves 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.
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-08 | Subscribe ItemSupplyService to VENDOR role (and/or BA) deletion per DQ-007 | operations | T-05 | Handler receives delete events |
| T-09 | On removal, mark affected supplies stale (retired+pinned rId+provenance), keep data | operations | T-08 | Supplies not deleted; flag set; parent Item refs updated |
| T-10 | Retired-reference resolution path (tombstone read) | operations | T-09 | Stale 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.
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-11 | Add 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). | operations | T-05 | Canonical routes serve ops; legacy aliased |
| T-12 | Retain/deprecate legacy routes per DQ-009 | operations | T-11 | Legacy aliases behave per decision |
Exit criteria: ./gradlew build passes; route tests green.
Phase 5: API tests (api-test)
Section titled “Phase 5: API tests (api-test)”Entry criteria: Phases 3–4 exit (routes + behavior available).
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-13 | Bruno requests for UC1–UC4 against canonical routes, chaining supplier eIds | api-test | T-11 | Requests pass against local cluster |
| T-14 | Bruno scenario for UC5 (remove supplier → supply shows retired=true) | api-test | T-09 | Assertion on stale flag passes |
Exit criteria: check-api-test-results green for the new collections.
Phase 6: Documentation (documentation)
Section titled “Phase 6: Documentation (documentation)”Entry criteria: Design stable (Phases 1–4 substantially landed).
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-15 | current-system design page for Item↔BusinessAffiliate supply linkage | documentation | T-09 | Page builds; PlantUML renders |
| T-16 | Align assets/items.md + assets/business-affiliates.md to the new model | documentation | — | vendorEId/supplierEId reconciled to SupplierReference→VENDOR role |
| T-17 | Document reference-data route convention in url-naming.md | documentation | T-11 | Convention documented |
Exit criteria: make pr-checks passes in the documentation worktree.
Phase 7: Release
Section titled “Phase 7: Release”Entry criteria: All prior phases’ exit criteria met; all DQs Decided/Deferred.
| # | Task | Repository | Depends On | Acceptance Criteria |
|---|---|---|---|---|
| T-18 | operations CHANGELOG.md entry (direct-edit model) | operations | T-12 | make clqLint passes |
| T-19 | api-test CHANGELOG entry (per repo model) | api-test | T-14 | CI changelog gate passes |
| T-20 | documentation PR-body ## CHANGELOG section | documentation | T-17 | changelog-check passes |
| T-21 | Open PRs; run pr-steward on each | all | T-18..T-20 | CI green; threads resolved |
| T-22 | Move project docs in-progress → completed | documentation | T-21 | Docs 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.
Dependency Graph
Section titled “Dependency Graph”Phases are largely sequential within operations; Phases 3 and 4 can proceed in
parallel once Phase 2 lands. api-test and documentation follow.
Personas
Section titled “Personas”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.
| Persona | Working Directory | Agent Name Pattern |
|---|---|---|
| back-end-engineer | projects/connect-supply-to-supplier-worktrees/operations | be-supply-link |
| acceptance-test-engineer | projects/connect-supply-to-supplier-worktrees/api-test | at-supply-link |
| technical-writer | projects/connect-supply-to-supplier-worktrees/documentation | tw-supply-link |
Worktree Strategy
Section titled “Worktree Strategy”- Branch
jmpicnic/connect-supply-to-supplieracross all four worktrees underprojects/connect-supply-to-supplier-worktrees/. - Single-agent: no integration branch; each repo’s branch becomes its PR.
- Run lint/typecheck/tests (and
make pr-checksfor documentation) before any push. Push guard: never pushworkbooksdesign 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
Copyright: © Arda Systems 2025-2026, All rights reserved