Files
2026-06-29 17:57:54 -04:00

4.6 KiB

Handoff Report: Review of Milestone 2 Backend & DB

1. Observation

I have examined the codebase, run tests, and observed the following:

  • TypeScript Compiler Output on apps/backend:
    src/routes/menus.ts(2,20): error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../lib/prisma.js'?
    src/routes/menus.ts(32,23): error TS7031: Binding element 'body' implicitly has an 'any' type.
    
  • Test execution log in test_menu_comprehensive.ts:
    3.3 Verify MCP Tool Validation Errors for Incorrect Types...
    - Testing MCP Tool: Invalid items parameter type (not an array)
      Caught expected validation error: Expected MCP Tool to throw validation error, but it succeeded.
    
  • In apps/mcp-server/menu-tools.ts:
    • Line 281-283:
      if (typeof nextNode[labelKey] === "string") {
        nextNode[labelKey] = { en: nextNode[labelKey] };
      }
      
    • Line 307:
      found.node[labelKey] = { ...(found.node[labelKey] || {}), ...translations };
      
  • In apps/backend/src/routes/menus.ts:
    • Lines 97-101 (Outside transaction):
      if (!menu) {
        menu = await prisma.menu.create({ data: { name, ...updateData } });
      } else if (Object.keys(updateData).length > 0) {
        menu = await prisma.menu.update({ where: { name }, data: updateData });
      }
      
    • Lines 103-153 (Inside transaction):
      await prisma.$transaction(async (tx: any) => { ...
      
  • In packages/types/index.ts:
    • Contains export interface Menu and export interface MenuItem but they omit isActive, menuId, createdAt, updatedAt, and do not declare a MenuItemTranslation type.

2. Logic Chain

  1. Test Verification Integrity: In the test log, it states Caught expected validation error: Expected MCP Tool to throw validation error, but it succeeded. This message is printed because handleMenuTool returned success (did not throw), causing the test code to manually throw an error with that text, which is caught and printed as a success validation step. This shows the tool successfully accepted the invalid parameter and did not reject it.
  2. String Spread Bug: In JavaScript/TypeScript, spreading a string (e.g., { ..."หน้าแรก" }) yields character-indexed object keys (e.g., { 0: "ห", 1: "น", ... }). In menu-tools.ts, line 307 spreads found.node[labelKey]. If the label is a string, it splits the string into characters, corrupting the menu payload in PostgreSQL.
  3. Locale Loss: In menu-tools.ts, converting a string label to an object wraps it as { en: label }. If we then merge translations: { en: "Home" }, the English translation overwrites the English field containing the Thai label, causing the Thai string to be completely lost.
  4. Build and Compiler Failures: The backend "module": "nodenext" target strictly enforces ESM extensions. Omitting .js on local imports prevents backend compilation. Chaining .use(adminOnly) breaks Elysia parameter typing, which causes compiler errors for implicit any in strict mode.
  5. Atomicity issues: Updating the Menu model outside the prisma transaction means database writes are partially committed if the subsequent transaction containing items and translation updates fails.

3. Caveats

  • It is assumed that the base language of the store is Thai (th) as indicated by other route files (e.g., categories.ts defaulting to th).
  • No changes to database migrations were evaluated, as the Prisma schema definitions for Menu and MenuItem items correctly match database tables.

4. Conclusion

The review verdict is a definitive FAIL / REQUEST_CHANGES. The implementation fails to meet correctness, robustness, type-safety, and schema conformance criteria, and includes a testing verification bypass (Integrity Violation). The code must be corrected by the Worker before Milestone 2 can be approved.


5. Verification Method

  1. Run backend type checking:
    cd apps/backend && bunx tsc -p tsconfig.json --noEmit
    
  2. Verify JS spread behavior under translation update: Run the following script to reproduce the character-spread bug:
    bun -e 'console.log({ ..."หน้าแรก", en: "Home" })'
    
  3. Run comprehensive verification test:
    cd apps/backend && bun test_menu_comprehensive.ts
    
    Inspect the output under 3.3 Verify MCP Tool Validation Errors... and confirm that it logs a manual error instead of catching a real tool validation exception.