Files
2026-06-28 21:34:58 -04:00

172 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff Report — Explorer 3, Milestone 2
## 1. Observation
Direct observations from codebase inspection:
1. **Prisma Models**:
File: `apps/backend/prisma/schema.prisma`, lines 638–658:
```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
}
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
}
```
2. **TypeScript Interfaces**:
File: `packages/types/index.ts`, lines 195–208:
```typescript
export interface MenuItem {
id: number
label: string
url: string
order: number
translations?: any[]
}
export interface Menu {
id: number
name: string
items: MenuItem[]
payload?: any
}
```
3. **Elysia Backend Routes**:
File: `apps/backend/src/routes/menus.ts`, lines 34–58:
```typescript
const { name, items } = body as { name: string; items?: { label: string; url: string; order: number }[] };
...
body: t.Object({
name: t.String(),
items: t.Optional(t.Array(t.Object({
label: t.String(),
url: t.String(),
order: t.Number()
})))
})
```
And lines 62–66:
```typescript
const { items, payload, isActive } = body as {
payload?: any;
isActive?: boolean;
items: { id?: number; label: string; url: string; order: number; translations?: { langCode: string; label: string }[] }[]
};
```
4. **MCP Validation Helper**:
File: `apps/mcp-server/menu-tools.ts`, lines 158–170:
```typescript
function validateMenuItems(items: any) {
const issues: string[] = [];
const warnings: string[] = [];
if (!Array.isArray(items)) {
issues.push("items must be an array");
return { issues, warnings };
}
items.forEach((item, index) => {
if (!isPlainObject(item)) {
issues.push(`items[${index}] must be a plain object`);
return;
}
```
5. **MCP Schema**:
File: `apps/mcp-server/menu-toolkit.ts`, lines 34–74, the definition of `upsert_menu`:
```typescript
{
name: "upsert_menu",
description: "Update or create a complete menu by replacing its items. Optional payload/isActive support covers tree-based menus and menu state. Uses proper diff & sync for translations.",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "Name of the menu (e.g. main, footer-explore)" },
dryRun: { type: "boolean", description: "Preview the mutation without saving it" },
payload: {
oneOf: [{ type: "object" }, { type: "array" }],
description: "Optional menu payload for tree-based menus such as main"
},
isActive: { type: "boolean", description: "Optional active state for the menu" },
items: {
type: "array",
description: "Array of menu items",
items: {
type: "object",
properties: {
id: { type: "number", description: "ID of existing item (optional)" },
label: { type: "string", description: "Label of the menu item" },
url: { type: "string", description: "URL of the menu item" },
order: { type: "number", description: "Order sequence" },
translations: {
```
---
## 2. Logic Chain
1. **Database Schema**: To store `rootImage` for Menu, and `columnImage`/`hoverImage` for MenuItem, we must add nullable string fields (`String?`) to these models in `schema.prisma`.
2. **TypeScript Declarations**: The TypeScript project imports standard types from `@homaroma/types` (`packages/types/index.ts`). These interfaces must match the database schemas by adding `rootImage?: string | null`, `columnImage?: string | null`, and `hoverImage?: string | null`.
3. **API Validation**: The backend validates POST/PUT requests using Elysia TypeBox (`t.Object`). Adding the new fields as optional nullable strings (`t.Optional(t.Nullable(t.String()))`) enables the backend to validate incoming values correctly while maintaining backward compatibility.
4. **API Mapping**: The database update transactions inside `menus.ts` map the validated payload to Prisma database queries. We must update the `create` and `update` queries to assign `rootImage` for Menu, and `columnImage`/`hoverImage` for MenuItem.
5. **MCP Schema & Helper**: The MCP toolkit contains utility validation for items before sending PUT requests. Adding validation rules in `validateMenuItems` prevents MCP validation blocks. Updating `MENU_TOOL_DEFINITIONS` exposes the new input parameters to AI clients interacting with `upsert_menu`.
---
## 3. Caveats
- **Seeding Script**: The seed file (`apps/backend/prisma/seed.cjs`) upserts default core menus. It does not contain image values, but since the new fields are fully optional, no updates are strictly required there.
- **Frontend Fallbacks**: Client code (SPA and Website) must handle null values safely. The actual layout rendering logic (DesktopMegaMenu) is a separate frontend concern that must be updated dynamically to read these fields.
- **Transpiled Route Artifacts**: There are transpiled `.js` and `.d.ts` files inside the routes folder, meaning a clean build step is required after modifications to typescript source files.
---
## 4. Conclusion
The strategy outlines a safe, fully backward-compatible database, route, and MCP tool update. The exact changes required in the four files have been mapped and documented in detail in `analysis.md`. The next step is to delegate the implementation tasks to the Implementer agent.
---
## 5. Verification Method
To independently verify the final implementation:
1. **Schema Check**:
Confirm that the prisma client generates successfully by running:
```bash
bunx prisma generate
```
2. **Database Migration Status**:
Run the following command to ensure migrations are applied cleanly without conflicts:
```bash
bunx prisma migrate status
```
3. **Route Integration & Tests**:
Execute the backend build script to verify there are no syntax or type mismatch errors:
```bash
npm run build --workspace apps/backend
```
Execute the workspace test command:
```bash
npm run test
```