# Handoff: update_category_image Feature Request Analysis ## 1. Observation From inspecting the codebase, the following files and lines were analyzed: * **Prisma Schema (`apps/backend/prisma/schema.prisma` lines 33-42):** ```prisma model Category { id Int @id @default(autoincrement()) name String @unique imageUrl String? products Product[] attributes AttributeDefinition[] translations CategoryTranslation[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` *Observation:* The database schema model `Category` already contains a nullable `imageUrl` field. * **Shared Types (`packages/types/index.ts` lines 9-17):** ```typescript export interface Category { id: number name: TranslatableString imageUrl?: string | null _count?: { products: number } translations?: { langCode: string; name: string }[] createdAt?: string updatedAt?: string } ``` *Observation:* The shared TypeScript types for `Category` already declare `imageUrl` as optional/nullable (`imageUrl?: string | null`). * **Backend Category Routes (`apps/backend/src/routes/categories.ts` lines 190-218):** The existing PUT route performs full/partial category updates: ```typescript .put("/:id", async ({ params, body, status }) => { const id = parseInt(params.id); if (isNaN(id)) return status(400, { message: "Invalid category ID" }); try { const category = await prisma.category.update({ where: { id }, data: { name: body.name, imageUrl: body.imageUrl, }, }); return category; ... }, { body: t.Object({ name: t.Optional(t.String()), imageUrl: t.Optional(t.Union([t.String(), t.Null()])), }) }) ``` * **MCP Server Schema and Handler (`apps/mcp-server/index.ts` lines 121-132, 862-870):** Exposed categories tools like `update_category_translation` define and route requests via a custom axios `api` instance: ```typescript // Tool definition { name: "update_category_translation", description: "Add or update translations for a specific category. Do NOT use this tool for products.", inputSchema: { type: "object", properties: { id: { type: "number", description: "Category ID" }, lang: { type: "string", description: "Language code (th, en, ja, zh, vi, ko)" }, name: { type: "string", description: "Translated category name" } }, required: ["id", "lang", "name"] } } // Tool handler case "update_category_translation": { const { id, lang, name } = params as any; const res = await api.patch(`/categories/${id}/translations`, { name: { [lang]: name } }); return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] }; } ``` ## 2. Logic Chain 1. Since the Category model in the database (`prisma/schema.prisma`) and the `Category` type interface in `packages/types/index.ts` already support the `imageUrl` field, no modifications to database structures, Prisma migrations, or the types package are needed. 2. In `apps/backend/src/routes/categories.ts`, we need to implement `PATCH /categories/:id/image`. It should accept a body with `imageUrl: t.Union([t.String(), t.Null()])` to update/clear the category image. 3. In `apps/mcp-server/index.ts`, we need to define the `update_category_image` tool schema under `ListToolsRequestSchema` and map its invocation under `CallToolRequestSchema`'s switch-case block, forwarding the payload to the new backend PATCH endpoint. ## 3. Caveats * **In-place backend compilation:** The backend TypeScript config includes `"declaration": true` without `"outDir"`, meaning transpiled files (`.js`, `.d.ts`, and `.js.map`) are produced directly inside the `src/` directory. If these transpiled files are checked into the repository, they should be regenerated after modifying `.ts` files by running `npm run build` or similar. * **JSON Schema type support:** The MCP tool definition schema uses `type: ["string", "null"]` for `imageUrl` to explicitly support clearing images. If an MCP client doesn't support array types, passing an empty string `""` is also a valid fallback. ## 4. Conclusion To implement the `update_category_image` feature: 1. Implement the following route in `apps/backend/src/routes/categories.ts` (e.g. before the `.post("/")` route): ```typescript .patch("/:id/image", async ({ params, body, status }) => { const id = parseInt(params.id); if (isNaN(id)) return status(400, { message: "Invalid category ID" }); try { const category = await prisma.category.update({ where: { id }, data: { imageUrl: body.imageUrl, }, }); return category; } catch (err: any) { if (err.code === "P2025") { return status(404, { message: "Category not found" }); } console.error("Update category image error:", err); return status(500, { message: "Failed to update category image" }); } }, { body: t.Object({ imageUrl: t.Union([t.String(), t.Null()]), }) }) ``` 2. Register the tool in `apps/mcp-server/index.ts` under `ListToolsRequestSchema` tools list: ```typescript { name: "update_category_image", description: "Update the image URL for a specific category.", inputSchema: { type: "object", properties: { id: { type: "number", description: "Category ID" }, imageUrl: { type: ["string", "null"], description: "New image URL, or null/empty string to remove the image" } }, required: ["id", "imageUrl"] } }, ``` 3. Implement the handler in `apps/mcp-server/index.ts` under `CallToolRequestSchema`'s `switch (request.params.name)` block: ```typescript case "update_category_image": { const { id, imageUrl } = params as any; const res = await api.patch(`/categories/${id}/image`, { imageUrl: imageUrl || null }); return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] }; } ``` ## 5. Verification Method * **Endpoint Verification:** Start the backend server (`bun run dev` in `apps/backend`). Call the new endpoint using `curl`: ```bash curl -X PATCH http://localhost:3051/api/categories/1/image \ -H "Content-Type: application/json" \ -d '{"imageUrl": "https://example.com/test-image.png"}' ``` Verify that the response returns the updated category object with `imageUrl` matching the provided URL. * **MCP Tool Verification:** Start the MCP server and run the tool `update_category_image` via an MCP client: ```json { "name": "update_category_image", "arguments": { "id": 1, "imageUrl": "https://example.com/test-image.png" } } ``` Verify that the tool succeeds and returns the JSON representation of the updated category.