---
phase: 19-reference-item-model-tags-schema
plan: 01
subsystem: database
tags: [drizzle, postgres, schema, migration, tags, reference-items]

requires:
  - phase: 18-global-items-public-profiles
    provides: globalItems table and itemGlobalLinks junction table
provides:
  - items.globalItemId direct FK replacing itemGlobalLinks junction table
  - items.purchasePriceCents for user-specific purchase price tracking
  - threadCandidates.globalItemId for catalog-linked candidates
  - tags and globalItemTags tables for tag-based discovery
  - Zod schemas with globalItemId and purchasePriceCents fields
  - Tag and GlobalItemTag TypeScript types
  - 30 curated seed tags for outdoor/adventure gear
affects: [19-02, 19-03, global-item-service, item-service, thread-service]

tech-stack:
  added: []
  patterns:
    - "Reference item model: nullable globalItemId FK on items replaces junction table"
    - "Tag system: flat tags table with many-to-many via globalItemTags"

key-files:
  created:
    - drizzle-pg/0002_wakeful_vermin.sql
  modified:
    - src/db/schema.ts
    - src/shared/schemas.ts
    - src/shared/types.ts
    - src/db/seed-global-items.ts

key-decisions:
  - "Data migration in SQL: UPDATE items SET global_item_id before DROP TABLE item_global_links"
  - "Seed tags as flat list without type categorization per D-16"

patterns-established:
  - "Reference items: globalItemId nullable FK on items table, when set base data comes from global item"
  - "Tag seeding: idempotent async seedTags function alongside seedGlobalItems"

requirements-completed: [CATFLOW-03, TAG-01, TAG-02]

duration: 4min
completed: 2026-04-05
---

# Phase 19 Plan 01: Reference Item Model & Tags Schema Summary

**Database schema updated with direct globalItemId FK on items/candidates, tags system tables, and data migration from itemGlobalLinks**

## Performance

- **Duration:** 4 min
- **Started:** 2026-04-05T18:23:49Z
- **Completed:** 2026-04-05T18:28:00Z
- **Tasks:** 2
- **Files modified:** 5

## Accomplishments
- Added globalItemId and purchasePriceCents columns to items table, globalItemId to threadCandidates
- Created tags and globalItemTags tables for tag-based global item discovery
- Removed itemGlobalLinks junction table with safe data migration in SQL
- Updated Zod schemas with new fields, removed linkItemSchema
- Converted seed script to async with 30 curated outdoor/adventure tags

## Task Commits

Each task was committed atomically:

1. **Task 1: Update schema.ts, generate migration with data migration step** - `5df513c` (feat)
2. **Task 2: Update Zod schemas, types, test helpers, and seed script** - `e9baa8d` (feat)

## Files Created/Modified
- `src/db/schema.ts` - Added globalItemId/purchasePriceCents to items, globalItemId to threadCandidates, tags + globalItemTags tables, removed itemGlobalLinks
- `src/shared/schemas.ts` - Added globalItemId/purchasePriceCents to createItemSchema, globalItemId to createCandidateSchema, tags to searchGlobalItemsSchema, removed linkItemSchema
- `src/shared/types.ts` - Added Tag and GlobalItemTag types, removed ItemGlobalLink and LinkItem
- `src/db/seed-global-items.ts` - Converted to async, added seedTags with 30 curated tags
- `drizzle-pg/0002_wakeful_vermin.sql` - Migration with ADD COLUMN, data migration UPDATE, DROP TABLE

## Decisions Made
- Reordered generated migration SQL to ensure data migration (UPDATE items SET global_item_id) runs before DROP TABLE item_global_links
- Kept seed tags as flat list per D-16 (no type categorization)

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] drizzle-kit generate interactive prompt**
- **Found during:** Task 1 (migration generation)
- **Issue:** drizzle-kit detected table rename ambiguity between itemGlobalLinks and globalItemTags, prompting interactively
- **Fix:** Used Bun.spawn with piped stdin to programmatically select "create table" option
- **Files modified:** None (tooling workaround)
- **Verification:** Migration file generated correctly
- **Committed in:** 5df513c (Task 1 commit)

---

**Total deviations:** 1 auto-fixed (1 blocking)
**Impact on plan:** Tooling workaround only, no code impact.

## Issues Encountered
None beyond the drizzle-kit interactive prompt handled above.

## User Setup Required
None - no external service configuration required.

## Next Phase Readiness
- Schema foundation ready for service layer updates (plan 19-02)
- Services referencing itemGlobalLinks, linkItemToGlobal, unlinkItemFromGlobal need updating
- Test files referencing removed schema entities need updating
- Client code referencing LinkToGlobalItem component needs updating

---
*Phase: 19-reference-item-model-tags-schema*
*Completed: 2026-04-05*
