--- phase: 25-catalog-enrichment-agent-tools plan: 02 subsystem: api,mcp,client tags: [hono, zod, mcp, catalog, upsert, attribution, react] # Dependency graph requires: - 25-01 (upsertGlobalItem, bulkUpsertGlobalItems, Zod schemas) provides: - POST /api/global-items endpoint (single upsert) - POST /api/global-items/bulk endpoint (batch upsert, max 100) - upsert_catalog_item MCP tool with attribution fields - bulk_upsert_catalog MCP tool with batch processing - Catalog detail page attribution display (imageCredit, imageSourceUrl, sourceUrl) affects: - MCP agents can now seed the global catalog via upsert_catalog_item and bulk_upsert_catalog - Catalog detail page now shows image credit and source link when present # Tech tracking tech-stack: added: [] patterns: - zValidator middleware pattern for Hono routes (upsertGlobalItemSchema, bulkUpsertGlobalItemsSchema) - registerCatalogTools(db) factory pattern — no userId needed for shared catalog - Attribution display: conditional inline text below image with credit + source link key-files: created: - src/server/mcp/tools/catalog.ts modified: - src/server/routes/global-items.ts - src/server/mcp/index.ts - src/client/hooks/useGlobalItems.ts - src/client/routes/global-items/$globalItemId.tsx - tests/routes/global-items.test.ts - tests/mcp/tools.test.ts key-decisions: - "Catalog MCP tools use registerCatalogTools(db) without userId — shared catalog needs no user scoping" - "Attribution spacing: image div removes mb-6, attribution paragraph adds mb-6 so spacing is consistent whether or not attribution exists" - "Bulk route handler uses zValidator middleware which returns 400 on any validation failure before DB access" requirements-completed: [CATL-03, CATL-04, SEED-01, SEED-02, SEED-03] # Metrics duration: 5min completed: 2026-04-10 --- # Phase 25 Plan 02: HTTP Routes, MCP Catalog Tools, and Attribution Display Summary **POST /api/global-items, POST /api/global-items/bulk, upsert_catalog_item and bulk_upsert_catalog MCP tools, and catalog detail page attribution display — 61 tests passing, lint clean, build succeeds** ## Performance - **Duration:** ~5 min - **Started:** 2026-04-10T09:01:57Z - **Completed:** 2026-04-10T09:06:28Z - **Tasks:** 3 - **Files modified:** 7 ## Accomplishments - Added POST /api/global-items with Zod validation via zValidator — returns { item, created } - Added POST /api/global-items/bulk with up to 100 items in atomic transaction — returns { created, updated, items } - Created src/server/mcp/tools/catalog.ts with catalogToolDefinitions and registerCatalogTools factory - Registered catalog tools in createMcpServer after image tools (no userId needed — catalog is global) - Extended GlobalItem interface with sourceUrl, imageCredit, imageSourceUrl fields - Added attribution display on catalog detail page: Photo credit + source link inline below image - Added product page link (sourceUrl) at bottom of detail page - All 61 affected tests pass (16 route tests + 24 MCP tool tests + 21 service tests) ## Task Commits 1. **Task 1 TDD RED — failing route tests** - `25f5902` (test) 2. **Task 1 TDD GREEN — POST routes implementation** - `6491615` (feat) 3. **Task 2 — MCP catalog tools + registration + tests** - `df6c75f` (feat) 4. **Task 3 — Client attribution display + GlobalItem interface** - `e4a6531` (feat) 5. **Biome formatting cleanup** - `fc9a913` (chore) ## Files Created/Modified - `src/server/routes/global-items.ts` — Added app.post("/") and app.post("/bulk") with Zod validation - `src/server/mcp/tools/catalog.ts` — New file: catalogToolDefinitions, registerCatalogTools with attribution fields - `src/server/mcp/index.ts` — Registered catalog tools in createMcpServer - `src/client/hooks/useGlobalItems.ts` — GlobalItem interface extended with sourceUrl, imageCredit, imageSourceUrl - `src/client/routes/global-items/$globalItemId.tsx` — Attribution block below image, product page link - `tests/routes/global-items.test.ts` — 9 new tests for POST single and bulk routes - `tests/mcp/tools.test.ts` — 6 new tests for catalog MCP tools ## Decisions Made - **Catalog tools without userId**: `registerCatalogTools(db)` matches the `registerImageTools()` pattern — shared global catalog has no user scoping concern. - **Attribution spacing**: The image `div` drops `mb-6` and the attribution `
` takes `mb-6`. A fallback `
` ensures consistent header spacing when no attribution is present. - **Validation-first bulk rejection**: `zValidator` middleware rejects the entire bulk request before any DB call if any item fails validation. This matches the plan requirement for batch-wide rejection on validation failure. ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 3 - Blocking] Merged Plan 01 changes into worktree** - **Found during:** Task 1 setup - **Issue:** The worktree branch `worktree-agent-a9d30e61` was created from an older commit and did not have Plan 01's service functions, schema changes, or migration. Attempting to import `upsertGlobalItem` would have failed. - **Fix:** Ran `git merge feature/catalog-enrichment-upsert --no-verify` to fast-forward the worktree to include all Plan 01 commits. - **Impact:** Required merge before starting any task, but was non-destructive (fast-forward). - **Commit:** Resolved by merge (no separate commit — fast-forward) **2. [Rule 3 - Blocking] Biome formatter required re-formatting multiple files** - **Found during:** Task 3 lint verification - **Issue:** Initial implementations of catalog.ts, global-items.ts (routes), and tests had lines exceeding biome's print width, causing `bun run lint` to fail. - **Fix:** Ran `bunx @biomejs/biome format --write` on affected files. Committed formatting changes as separate chore commit. - **Commit:** `fc9a913` --- **Total deviations:** 2 auto-fixed (Rule 3 - blocking issues) **Impact on plan:** Both fixes were necessary for correctness and lint compliance. No scope creep. ## Known Stubs None — all attribution fields are wired end-to-end from the database through the API to the UI. ## User Setup Required None — no new external services required. The MCP tools are available immediately after restart with an authenticated session. --- *Phase: 25-catalog-enrichment-agent-tools* *Completed: 2026-04-10*