# Handoff Report — Explorer 1 (Milestone 2: Backend & DB) ## 1. Observation I observed the following files and code blocks: - **`apps/backend/prisma/schema.prisma`**: - The `Menu` model is defined at lines 638-646: ```prisma model Menu { id Int @id @default(autoincrement()) name String @unique // e.g., "header", "footer" payload Json? isActive Boolean @default(true) items MenuItem[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` - The `MenuItem` model is defined at lines 648-658: ```prisma model MenuItem { id Int @id @default(autoincrement()) menuId Int menu Menu @relation(fields: [menuId], references: [id], onDelete: Cascade) label String url String order Int @default(0) translations MenuItemTranslation[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` - **`packages/types/index.ts`**: - The `MenuItem` type interface is defined at lines 195-201: ```typescript export interface MenuItem { id: number label: string url: string order: number translations?: any[] } ``` - The `Menu` type interface is defined at lines 203-208: ```typescript export interface Menu { id: number name: string items: MenuItem[] payload?: any } ``` - **`apps/backend/src/routes/menus.ts`**: - Contains endpoints `POST /` (line 32), `PUT /:name` (line 60) for handling and validating menus, utilizing TypeBox `t` schema builders. For instance, the `PUT /:name` validator at line 133: ```typescript body: t.Object({ payload: t.Optional(t.Any()), isActive: t.Optional(t.Boolean()), items: t.Array(t.Object({ id: t.Optional(t.Number()), label: t.String(), url: t.String(), order: t.Number(), translations: t.Optional(t.Array(t.Object({ langCode: t.String(), label: t.String() }))) })) }) ``` - **`apps/mcp-server/menu-tools.ts`**: - Contains `validateMenuItems` helper function (line 158) verifying URL and order values. - **`apps/mcp-server/menu-toolkit.ts`**: - Defines MCP tools input schemas, such as `upsert_menu` (line 34) and executes the actual HTTP endpoint mutations inside `handleMenuTool` (line 196). - MCP tools register dynamically from `MENU_TOOL_DEFINITIONS` in `apps/mcp-server/index.ts` at line 78: `...MENU_TOOL_DEFINITIONS,`. --- ## 2. Logic Chain 1. **Schema Update Strategy:** Based on the requirements to add `rootImage` to `Menu` and `columnImage`/`hoverImage` to `MenuItem`, adding these as optional fields (`String?` in Prisma, and optional mapping to properties `?: string | null` in TypeScript types) ensures they are backward-compatible. 2. **Database Migration Logic:** Running `bunx prisma migrate dev` compiles the changes into SQL, writes the schema updates, and triggers the Prisma client generation automatically. 3. **Route Request/Response Integration:** Since route request payloads are validated using TypeBox `t.Object`, the body validators in `POST /` and `PUT /:name` must be updated to accept `t.Optional(t.Nullable(t.String()))` for the new properties. Destructuring, transaction update blocks, and transaction create blocks must maps these fields to Prisma's API parameter targets. 4. **MCP Validation Alignment:** Since MCP tools use `validateMenuItems` internally to check lists of items before putting request payloads, `validateMenuItems` must be updated to inspect the validity of `columnImage` and `hoverImage` strings. The input schemas of MCP tools (like `upsert_menu`) must also expose the properties for AI context discovery. --- ## 3. Caveats No caveats. The proposed changes are localized, backwards-compatible, and standard for Elysia/Typebox and Prisma. --- ## 4. Conclusion The database, shared types, API routes, and MCP tools can be modified to safely support optional image properties on menus and menu items. --- ## 5. Verification Method 1. **Prisma Typecheck & Compile:** Run: ```bash cd apps/backend && bunx prisma migrate dev --name add_menu_image_fields ``` Check that typecheck compiles successfully via `bunx tsc -p tsconfig.json --noEmit` inside `apps/backend` and `apps/mcp-server`. 2. **Type checks on workspace packages:** ```bash npm run build ``` Ensures `@homaroma/types` type changes sync across all monorepo modules cleanly. 3. **Run local manual integration checks:** Call `get_menu` and `upsert_menu` using MCP server commands or directly through curl/POSTMAN towards `POST /menus` and `PUT /menus/:name` to ensure images are persisted and returned correctly.