# Handoff Report - Codebase Exploration This report synthesizes the exploration of the HomAroma codebase regarding its backend, storefront, database models, testing structure, and MCP server setup. ## 1. Observation ### Elysia Backend Server - **File path**: `apps/backend/src/index.ts` - **Port definition**: - `apps/backend/src/index.ts` (lines 31): ```typescript const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3051; ``` - `apps/backend/src/index.ts` (line 140): ```typescript .listen({ port: PORT, hostname: "0.0.0.0" }); ``` - **Scripts/Commands**: - `apps/backend/package.json` (lines 7-11): ```json "scripts": { "dev": "bun --watch src/index.ts", "build": "prisma generate", "start": "bun src/index.ts" } ``` - PM2 configuration in `ecosystem.config.js` (lines 4-7): ```javascript name: 'homaroma-backend', script: './src/index.ts', cwd: '/home/ti/projects/homaroma-api/apps/backend', interpreter: '/home/ti/.bun/bin/bun', ``` ### Next.js Storefront Server - **File path**: `apps/website` - **Output Mode**: `apps/website/next.config.ts` (lines 3-6) ```typescript const nextConfig: NextConfig = { output: "standalone", }; ``` - **Port definition**: - Development port in `apps/website/package.json` (line 6): ```json "dev": "next dev -p 3001", ``` - Production port in `ecosystem.config.js` (lines 20-24): ```javascript max_memory_restart: '1G', env_production: { NODE_ENV: 'production', PORT: 3002 } ``` - **Scripts/Commands**: - `apps/website/package.json` (lines 5-10): ```json "scripts": { "dev": "next dev -p 3001", "build": "next build", "start": "next start", "lint": "eslint" } ``` ### Prisma Menu Models - **File path**: `apps/backend/prisma/schema.prisma` - **Model definitions** (lines 638-670): ```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 } model MenuItemTranslation { id Int @id @default(autoincrement()) menuItemId Int menuItem MenuItem @relation(fields: [menuItemId], references: [id], onDelete: Cascade) langCode String label String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([menuItemId, langCode]) } ``` ### Existing Tests and Configurations - **Workspace scripts**: - Root `package.json` contains: ```json "test": "npm run test --workspaces --if-present" ``` - No workspace package has a specific test command (such as running `jest` or `vitest`). - **Scratch test scripts**: - `apps/backend/scratch_test.ts` - `apps/backend/scratch_test_langs.ts` - `apps/backend/scratch_test_menus.ts` - `apps/backend/scratch_test_page.ts` - `apps/backend/scratch_test_page2.ts` - `apps/backend/test_category_image.ts` - `apps/mcp-server/test_mcp_category_image.ts` - **MCP server integration test**: - `apps/mcp-server/test_mcp_category_image.ts` spawns both the backend server and MCP server, sends jsonrpc requests (`initialize`, `notifications/initialized`, and a `tools/call` for `update_category_image`), waits for responses, terminates the servers, and verifies results. ### MCP Tools configuration - **File path**: `apps/mcp-server/index.ts` - **Main dependencies**: `@modelcontextprotocol/sdk` (version `^1.29.0`) - **Transport configuration**: Runs over standard input/output (`StdioServerTransport`). - **State and configuration variables** (`apps/mcp-server/index.ts` lines 11-16): ```typescript const LOCAL_BACKEND_URL = process.env.MCP_BACKEND_URL_LOCAL || "http://localhost:3051/api"; const PRODUCTION_BACKEND_URL = process.env.MCP_BACKEND_URL_PRODUCTION || "https://api.homaroma.shop/api"; let BACKEND_URL = process.env.MCP_BACKEND_URL || LOCAL_BACKEND_URL; const ADMIN_USERNAME = process.env.MCP_ADMIN_USERNAME || process.env.ADMIN_USERNAME || "admin"; const ADMIN_PASSWORD = process.env.MCP_ADMIN_PASSWORD || process.env.ADMIN_PASSWORD || "homaroma123"; ``` - **Login / Authentication Interception** (lines 26-50): Outbound requests are intercepted; if there is no active token, it logs in via `POST /auth/login` to retrieve a JWT Bearer token. - **Capabilities & Tool Registry**: - Initialized with tool capabilities. - Registers tools from: 1. Main tool definitions (`apps/mcp-server/index.ts` list) 2. Menu tool definitions (`MENU_TOOL_DEFINITIONS` imported from `./menu-toolkit`) 3. Layout section block tool definitions (`SECTION_TOOL_DEFINITIONS` imported from `./section-toolkit`) - List of registered tools: - *Utility*: `set_target_environment`, `ping_backend` - *Products/Brands/Categories*: `list_product_brands`, `list_categories`, `search_products`, `get_product_detail`, `update_category_translation`, `update_category_image`, `update_product_brand_translation`, `create_product`, `bulk_create_products`, `sync_product_variants`, `update_product_content`, `update_product_translation`, `list_attribute_definitions`, `get_attribute_definition_detail`, `create_attribute_definition`, `update_attribute_definition`, `update_attribute_definition_translation`, `list_product_attributes`, `set_product_attribute`, `update_product_attribute_translation`, `upload_product_image_from_url`, `generate_mock_review` - *Orders/Customers*: `get_order_status`, `list_pending_orders`, `update_order_tracking`, `search_customer` - *Dynamic Pages & Layout Block Sections*: `list_dynamic_pages`, `list_dynamic_pages_metadata`, `get_dynamic_page_detail`, `create_dynamic_page`, `update_footer_content`, `get_page_section`, `add_page_section`, `update_page_section`, `delete_page_section`, and the block-specific updater tools: `update_hero_article`, `update_editorial_tile`, `update_rich_text`, `update_scent_notes_breakdown`, `update_quote_callout`, `update_product_carousel`, `update_accordion`, `update_contact_info`, `update_contact_form`, `update_editorial_carousel`, `add_accordion_category`, `update_accordion_category`, `add_accordion_question`, `update_accordion_question` - *Menus*: `get_menu`, `upsert_menu`, `audit_missing_pages`, `get_mega_menu_tree`, `capture_menu_snapshot`, `restore_menu_snapshot`, `bulk_menu_operations`, `add_menu_node`, `update_menu_translation`, `move_menu_node`, `remove_menu_node` --- ## 2. Logic Chain 1. **Elysia Backend Server**: - Locating files via `list_dir` and scanning `apps/backend/package.json` confirms dependencies (`elysia`, `@elysiajs/cors`, `prisma`) and the `dev`/`start` scripts targeting `src/index.ts`. - Inspection of `apps/backend/src/index.ts` shows the server listens to `process.env.PORT` defaulting to `3051`. - Inspection of `ecosystem.config.js` shows that in PM2 environment, it runs as `homaroma-backend`. 2. **Next.js Storefront Server**: - Scanning `apps/website/package.json` identifies the Next.js dependency (`next`, `react`, `react-dom`). - The script `"dev": "next dev -p 3001"` specifies port `3001` for development. - `ecosystem.config.js` configures the website PM2 process `homaroma-website` running on port `3002` in production. - `apps/website/next.config.ts` confirms standalone output mode which builds `server.js` used by PM2. 3. **Prisma Models for Menu/Mega Menu**: - Location verified at `apps/backend/prisma/schema.prisma`. - Models `Menu`, `MenuItem`, and `MenuItemTranslation` structure the menu hierarchy, including references, ordering, JSON payloads (for tree-based navigation), and localized values. 4. **Existing Tests and Runner**: - Searching files for `*.test.ts`, `*.spec.ts`, and checking scripts in workspace package.jsons reveals that no formal testing framework (such as Jest, Vitest, Cypress, or Bun test suite) is integrated. - Instead, the project uses manual scratch runner scripts (e.g., `scratch_test_menus.ts`). - An MCP integration test `apps/mcp-server/test_mcp_category_image.ts` runs on Bun to verify MCP jsonrpc request/response handlers. 5. **MCP Tools Configuration**: - `apps/mcp-server/package.json` indicates dependency on `@modelcontextprotocol/sdk`. - `apps/mcp-server/index.ts` creates the stdio Server and registers capabilities. - Analysis of `index.ts`, `menu-toolkit.ts`, and `section-toolkit.ts` outlines a comprehensive list of tools (utility, products, orders, dynamic pages, menus) and environmental variables supporting target switcher and automatic API authentication login. --- ## 3. Caveats - No active test runner is configured, so we cannot run standard test command validations. We assume the codebase relies on manual verification run scripts. - The `server.js` used in PM2 production is generated dynamically by Next.js standalone build and is not committed to the source control. --- ## 4. Conclusion The Monorepo codebase is split into Elysia (port 3051), React SPA, and Next.js Storefront (dev: 3001, production: 3002). Database interactions are driven by Prisma, with menu systems mapped to `Menu`, `MenuItem`, and `MenuItemTranslation`. Testing is done through standalone manual scripts. The MCP server integrates with the backend via authentication interception and exposes the tools defined in the toolkit modules. --- ## 5. Verification Method To verify these findings: 1. **Elysia Backend Server Port/Startup**: - Run `PORT=3055 bun apps/backend/src/index.ts` and inspect log outputs. 2. **Next.js Storefront Dev Port**: - Run `bun --cwd apps/website dev` and check terminal log output to verify it opens at `http://localhost:3001`. 3. **Prisma Menu Schema Validation**: - Run `npx prisma validate --schema=apps/backend/prisma/schema.prisma` to confirm syntax correctness of models. 4. **Manual Test Run**: - Run `bun apps/backend/scratch_test_menus.ts` (assuming database is running locally) or `bun apps/mcp-server/test_mcp_category_image.ts` to test MCP tool execution.