This commit is contained in:
Your Name committed 2026-06-28 21:34:58 -04:00
1 parent 3965f4f4da
commit 70877882b0
82 files changed
+4353 -186

No files matched your search

+171
View File
@@ -0,0 +1,171 @@
# 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
```