docs(19-02): complete item and thread service COALESCE merge plan

- SUMMARY.md with task commits, decisions, and verification results
- STATE.md updated with position, progress, and decisions
- ROADMAP.md updated with plan progress
This commit is contained in:
2026-04-05 20:51:26 +02:00
parent 8a5ee731d0
commit 59deaea95a
3 changed files with 117 additions and 15 deletions

View File

@@ -0,0 +1,101 @@
---
phase: 19-reference-item-model-tags-schema
plan: 02
subsystem: services
tags: [item-service, thread-service, coalesce, reference-items, catalog-link]
requires:
- phase: 19-reference-item-model-tags-schema
plan: 01
provides: globalItemId FK on items and threadCandidates, tags tables
provides:
- COALESCE merge pattern in item service for transparent reference item data
- Branched thread resolution (reference vs standalone items)
- Catalog-linked candidates with merged global item display data
- Cleaned items route without link/unlink endpoints
affects: [19-03, client-hooks, mcp-tools]
tech-stack:
added: []
patterns:
- "COALESCE merge: LEFT JOIN globalItems with CASE WHEN for name, weight, price, image"
- "Branched resolution: candidate.globalItemId determines reference vs standalone item creation"
key-files:
created: []
modified:
- src/server/services/item.service.ts
- src/server/services/thread.service.ts
- src/server/routes/items.ts
- tests/services/item.service.test.ts
- tests/services/thread.service.test.ts
key-decisions:
- "COALESCE with CASE WHEN pattern ensures standalone items are unaffected by globalItems JOIN"
- "Reference item resolution omits weight/price/productUrl - those come from global item via COALESCE on read"
- "Image fallback: item's own imageFilename takes precedence, global imageUrl used as fallback"
patterns-established:
- "Reference items: service layer transparently merges global data via SQL COALESCE, clients see unified shape"
- "Branched resolution: resolveThread checks candidate.globalItemId to determine item creation strategy"
requirements-completed: [CATFLOW-03, CATFLOW-04, CATFLOW-05, CATFLOW-06]
duration: 8min
completed: 2026-04-05
---
# Phase 19 Plan 02: Item & Thread Service COALESCE Merge Summary
**COALESCE merge pattern in item/thread services for transparent reference item data, branched thread resolution, and link/unlink endpoint removal**
## Performance
- **Duration:** 8 min
- **Started:** 2026-04-05T18:31:23Z
- **Completed:** 2026-04-05T18:39:00Z
- **Tasks:** 2
- **Files modified:** 5
## Accomplishments
- Item service getAllItems and getItemById use LEFT JOIN + COALESCE to transparently merge global item data for reference items
- createItem accepts globalItemId, looks up global item for brand+model fallback name (items.name is NOT NULL)
- duplicateItem preserves globalItemId and purchasePriceCents from source
- Thread service getThreadWithCandidates merges global item data for catalog-linked candidates
- createCandidate stores globalItemId on candidate row
- resolveThread branches: reference items get globalItemId set with no weight/price copy; standalone items get full data copy
- Removed link/unlink endpoints from items route (replaced by direct globalItemId FK)
## Task Commits
Each task was committed atomically:
1. **Task 1: Item service COALESCE merge + reference item creation + tests** - `d1ffd79` (feat)
2. **Task 2: Thread service candidate globalItemId + branched resolution + route cleanup + tests** - `8a5ee73` (feat)
## Files Created/Modified
- `src/server/services/item.service.ts` - LEFT JOIN globalItems with COALESCE in getAllItems/getItemById, globalItemId in createItem/duplicateItem/updateItem
- `src/server/services/thread.service.ts` - LEFT JOIN globalItems in getThreadWithCandidates, globalItemId in createCandidate, branched resolveThread
- `src/server/routes/items.ts` - Removed link/unlink endpoints and imports of linkItemToGlobal, unlinkItemFromGlobal, linkItemSchema
- `tests/services/item.service.test.ts` - 10 new tests for reference item creation, merged data retrieval, purchasePriceCents
- `tests/services/thread.service.test.ts` - 6 new tests for catalog-linked candidates and branched resolution
## Decisions Made
- Used COALESCE with CASE WHEN pattern (not simple COALESCE) to ensure standalone items are completely unaffected by the LEFT JOIN
- Reference item resolution intentionally omits weight, price, and productUrl from the insert - those come from the global item via COALESCE on read
- Image fallback order: item's own imageFilename first, global item's imageUrl second (user uploads override catalog images)
## Deviations from Plan
None - plan executed exactly as written.
## Known Stubs
None - all data paths are fully wired.
---
*Phase: 19-reference-item-model-tags-schema*
*Completed: 2026-04-05*