# Phase 25: Catalog Enrichment & Agent Tools - Context **Gathered:** 2026-04-10 **Status:** Ready for planning ## Phase Boundary Add attribution metadata fields to global items, enforce uniqueness on (brand, model) to prevent duplicates, create a bulk import API endpoint with upsert semantics, and add MCP tools (`upsert_catalog_item`, `bulk_upsert_catalog`) for agent-powered catalog seeding. Display attribution info on catalog detail pages. ## Implementation Decisions ### Attribution Data Model - **D-01:** Add three new columns to `globalItems`: `sourceUrl` (text, nullable — product page URL), `imageCredit` (text, nullable — photographer or source name), `imageSourceUrl` (text, nullable — original image URL). These align with the existing `imageSourceUrl` pattern on `items` and `threadCandidates` tables. - **D-02:** No separate `manufacturer` column — the existing `brand` field already serves this purpose. Requirements reference to "manufacturer" maps to `brand`. - **D-03:** Attribution display on catalog detail page: image credit and source link shown inline below the image, not in a collapsible section. Simple and transparent. ### Uniqueness Constraint - **D-04:** Add a unique constraint on `(brand, model)` to `globalItems`. Same physical product shouldn't exist twice regardless of category. Category is a classification, not identity. - **D-05:** Upsert semantics on conflict: `ON CONFLICT (brand, model) DO UPDATE` — update all non-key fields (category, weight, price, image, description, attribution fields). ### Bulk Import API - **D-06:** `POST /api/global-items/bulk` — accepts an array of items, upserts all in a single transaction. Requires API key auth (existing auth model). - **D-07:** All-or-nothing transaction — if any item fails validation, reject the entire batch with detailed error response listing which items failed and why. - **D-08:** Maximum 100 items per request. Return count of created vs updated items in the response. - **D-09:** Request body shape: `{ items: [{ brand, model, category?, weightGrams?, priceCents?, imageUrl?, description?, sourceUrl?, imageCredit?, imageSourceUrl?, tags?: string[] }] }`. ### Single Item Upsert API - **D-10:** `POST /api/global-items` — upsert a single catalog item with the same conflict handling as bulk. Also requires auth. ### MCP Tools - **D-11:** Add `upsert_catalog_item` MCP tool — writes directly to `globalItems` (not user-scoped). Parameters include all `globalItem` fields plus attribution fields plus optional `tags` array. - **D-12:** Add `bulk_upsert_catalog` MCP tool — accepts an array of items, calls the bulk import service. Same field set as single upsert. - **D-13:** MCP catalog tools require authenticated session (API key or OAuth bearer), same as all existing MCP tools. No special admin role. - **D-14:** Register new MCP tools in `src/server/mcp/index.ts` following the existing pattern (definitions array + handler registration). ### Claude's Discretion - Drizzle migration approach for new columns and unique constraint - Exact Zod validation schemas for bulk import payload - MCP tool descriptions and parameter documentation - Tag handling in upsert (create-if-not-exists vs require existing tags) - Response shape details for bulk import (created/updated counts, item IDs) ## Canonical References **Downstream agents MUST read these before planning or implementing.** ### Schema & Database - `src/db/schema.ts` — Current `globalItems` table definition (lines 136-146), `globalItemTags` junction (lines 158-169), and `items`/`threadCandidates` tables with existing `imageSourceUrl` column pattern ### Services - `src/server/services/global-item.service.ts` — Current read-only service (searchGlobalItems, getGlobalItemWithOwnerCount). Needs create/upsert functions. ### Routes - `src/server/routes/global-items.ts` — Current read-only routes (GET search, GET by ID). Needs POST endpoints. ### MCP - `src/server/mcp/index.ts` — MCP server setup and tool registration pattern - `src/server/mcp/tools/items.ts` — Example of existing tool definitions + handler pattern to follow - `src/server/mcp/tools/` — All existing tool files for reference on naming and structure ### Client - Catalog detail page component (wherever `globalItems/:id` route renders) — needs attribution display additions ### Requirements - `.planning/REQUIREMENTS.md` — CATL-01 through CATL-05, SEED-01 through SEED-03 ## Existing Code Insights ### Reusable Assets - `global-item.service.ts` — existing search and getById pattern to extend with create/upsert - `imageSourceUrl` column pattern on `items` (line 56) and `threadCandidates` (line 98) — same pattern for globalItems attribution - MCP tool registration pattern — definitions array + register function per domain (see `tools/items.ts`) - Zod validation schemas in `src/shared/schemas.ts` — extend with globalItem create/upsert schemas - Tag service (`tag.service.ts`) — likely has create-if-not-exists logic for tag handling ### Established Patterns - Service DI: functions take `(db, ...)` — global item services don't need userId (catalog is shared) - Drizzle ORM migrations via `bun run db:generate` and `bun run db:push` - Hono route handlers with `@hono/zod-validator` for request validation - Prices as cents (integer), weights as grams (doublePrecision) ### Integration Points - `src/db/schema.ts` — add columns to globalItems, add unique constraint - `src/server/index.ts` — no new route group needed (global-items route already registered) - `src/server/mcp/index.ts` — register new catalog tool group - Catalog detail page — add attribution display below image ## Specific Ideas - Manufacturer images with attribution and source link — honor takedown requests (from PROJECT.md decisions) - Agent seeding uses manufacturer-provided images — no scraping (from Out of Scope in REQUIREMENTS.md) ## Deferred Ideas - SEED-04 (actual seeding run with 100+ items) — tracked in future requirements, not part of this phase's infrastructure work - Admin role for catalog management — current auth model sufficient for v2.1 - Catalog item edit UI — this phase focuses on API/MCP tools, not a web editor --- *Phase: 25-catalog-enrichment-agent-tools* *Context gathered: 2026-04-10*