diff --git a/CLAUDE.md b/CLAUDE.md index ff471353..e2b3a11e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,7 @@ Monorepo platform với microservices architecture, phục vụ hệ sinh thái ## Project Structure ``` -services/ # 26 .NET microservices +services/ # 26 .NET microservices + 1 TypeScript MCP server iam-service-net/ # Identity & Access Management (JWT, RBAC, MFA, Sessions) merchant-service-net/ # Merchant & Shop management order-service-net/ # Order processing @@ -47,6 +47,7 @@ services/ # 26 .NET microservices mkt-zalo-service-net/ # Zalo integration _template_dot_net/ # Service template (REFERENCE for all new services) _template_nodejs/ # Node.js template + goodgo-mcp-server/ # MCP Server (TypeScript) — AI-assisted F&B operations (12 tools) apps/ # Frontend applications web-client-base-net/ # Blazor WASM enterprise portal (MudBlazor) diff --git a/CTO_REPORT_SHOP_DELETE.md b/CTO_REPORT_SHOP_DELETE.md index 484cc8be..86795329 100644 --- a/CTO_REPORT_SHOP_DELETE.md +++ b/CTO_REPORT_SHOP_DELETE.md @@ -3,7 +3,8 @@ > Date: 2026-03-14 > Reporter: QA Team (Automated Chrome Testing) > Priority: P1 (Functional Gap) -> Status: OPEN +> Status: RESOLVED +> Resolution: Implemented in commit 6263eeb (feat: add shop lifecycle management UI — deactivate & close shop) --- diff --git a/README.md b/README.md index 5c3c6144..a06d0640 100644 --- a/README.md +++ b/README.md @@ -1,290 +1,129 @@ -# GoodGo Microservices Platform +# GoodGo Platform -[![English](https://img.shields.io/badge/Language-English-blue.svg)](README.md) [![Tiếng Việt](https://img.shields.io/badge/Ngôn%20ngữ-Tiếng%20Việt-red.svg)](README.vi.md) +Monorepo platform with microservices architecture for the merchant/customer ecosystem — POS, F&B, retail, spa, karaoke, and more. -Enterprise-grade microservices monorepo built with modern technologies and best practices. +**Domain**: [goodgo.vn](https://goodgo.vn) | **Staging**: api.staging.goodgo.vn -## 🏗️ Architecture +## Tech Stack -This monorepo follows a microservices architecture pattern with: +| Layer | Technologies | +|-------|-------------| +| **Backend** | .NET 10.0 (C# 14), MediatR/CQRS, EF Core 10, FluentValidation, Serilog, Dapper, Polly | +| **Web** | Blazor WASM + MudBlazor 8.15 (Material Design) | +| **Mobile** | .NET MAUI (cross-platform), SwiftUI (iOS) | +| **Database** | PostgreSQL 16 (local) / Neon PostgreSQL (cloud), Redis 7 | +| **Messaging** | RabbitMQ 3 (AMQP) | +| **Storage** | MinIO (S3-compatible) | +| **Gateway** | Traefik v3 | +| **Infra** | Docker Compose (local), Kubernetes RKE2 (staging/prod) | +| **CI/CD** | GitHub Actions, Docker Hub | +| **Observability** | Prometheus + Grafana + Loki + Promtail | +| **Auth** | Duende IdentityServer, JWT Bearer, OAuth2 | +| **Monorepo** | pnpm 8 workspaces, Turborepo | -- **Apps**: Frontend applications (Web + Mobile) -- **Services**: Backend microservices (Node.js/TypeScript) -- **Packages**: Shared libraries and utilities -- **Infrastructure**: Traefik, Observability, Databases -- **Deployments**: Environment-specific configurations - -## 📁 Project Structure +## Project Structure ``` -├── apps/ # Frontend applications -│ ├── web-admin/ # Next.js admin web application -│ ├── web-client/ # Next.js client web application -│ ├── app-admin/ # Flutter admin mobile application -│ └── app-client/ # Flutter client mobile application -├── services/ # Backend microservices -│ ├── iam-service/ # Identity and Access Management service (Node.js) -│ └── _template/ # Service template for new services -├── packages/ # Shared libraries -│ ├── auth-sdk/ # Auth utilities and guards -│ ├── config/ # Shared configurations -│ ├── http-client/ # Standardized API client -│ ├── logger/ # Centralized logging (Winston) -│ ├── tracing/ # OpenTelemetry setup -│ └── types/ # Shared TypeScript types -├── infra/ # Infrastructure as Code -│ ├── databases/ # Database configs (PostgreSQL/Neon, Redis) -│ ├── docker/ # Docker compose files -│ ├── observability/ # Monitoring stack (Prometheus, Grafana, Loki) -│ ├── secrets/ # Secret management -│ └── traefik/ # API Gateway configuration -├── deployments/ # Environment configs -│ ├── local/ # Local development setup -│ ├── staging/ # Staging environment (Kubernetes) -│ └── production/ # Production environment (Kubernetes) -├── scripts/ # Automation scripts (Bilingual EN/VI) -│ ├── build/ # Build scripts -│ ├── db/ # Database management (backup, seed, migrate) -│ ├── deploy/ # Deployment scripts -│ ├── dev/ # Development helpers -│ ├── setup/ # Project initialization -│ └── utils/ # Utility scripts (cleanup, generators) -└── docs/ # Documentation +services/ # 26 .NET microservices (Clean Architecture + CQRS) +apps/ # Frontend applications +packages/ # Shared Node.js packages (@goodgo/*) +deployments/ # Environment configs (local, staging, production) +infra/ # Infrastructure (Traefik, databases, observability) +scripts/ # Automation scripts (dev, db, deploy, build) ``` -## ⚠️ Breaking Changes +## Services -### v1.0.0 - Module Format Migration (2026-01-07) +**Core Platform** +- `iam-service-net` — Identity & Access Management (JWT, RBAC, MFA, Sessions) +- `merchant-service-net` — Merchant & Shop management +- `catalog-service-net` — Product catalog +- `order-service-net` — Order processing +- `inventory-service-net` — Inventory management +- `wallet-service-net` — Wallet & payments +- `fnb-engine-net` — F&B engine +- `booking-service-net` — Booking & reservations -**BREAKING**: All shared packages now use ES modules instead of CommonJS. +**Engagement** +- `promotion-service-net` — Promotions & discounts +- `membership-service-net` — Membership & loyalty +- `chat-service-net` — Chat & messaging (SignalR + Redis) +- `social-service-net` — Social features +- `mission-service-net` — Gamification missions -**What Changed:** -- TypeScript compilation target changed from `commonjs` to `ES2020` -- All packages (`@goodgo/types`, `@goodgo/http-client`, `@goodgo/logger`, `@goodgo/auth-sdk`, `@goodgo/tracing`) now export ES modules -- `package.json` files already declared `"type": "module"`, now TypeScript output matches +**Advertising** +- `ads-manager-service-net` — Campaign management +- `ads-serving-service-net` — Ad delivery +- `ads-billing-service-net` — Ad billing +- `ads-tracking-service-net` — Event tracking +- `ads-analytics-service-net` — Analytics -**Migration Required:** -If you have existing code importing these packages: +**Marketing Integrations** +- `mkt-facebook-service-net` — Facebook +- `mkt-whatsapp-service-net` — WhatsApp +- `mkt-x-service-net` — X (Twitter) +- `mkt-zalo-service-net` — Zalo -```typescript -// ✅ This still works (no changes needed for most cases) -import { UserResponse } from '@goodgo/types'; -import { createHttpClient } from '@goodgo/http-client'; +**Utilities** +- `storage-service-net` — File storage (MinIO) +- `mining-service-net` — Data mining -// ⚠️ If you were using require() (CommonJS), you must update: -// ❌ OLD: const { UserResponse } = require('@goodgo/types'); -// ✅ NEW: import { UserResponse } from '@goodgo/types'; -``` +## Frontend Apps -**Action Required:** -1. Pull latest changes -2. Clean and rebuild: `pnpm -r --filter "./packages/*" run clean && pnpm build` -3. Update any CommonJS `require()` statements to ES `import` +| App | Stack | Description | +|-----|-------|-------------| +| `web-client-tpos-net` | Blazor WASM + MudBlazor | POS system (multi-vertical: karaoke, restaurant, cafe, spa, retail) | +| `web-client-base-net` | Blazor WASM + MudBlazor | Enterprise portal | +| `app-client-base-net` | .NET MAUI | Cross-platform mobile app | +| `app-client-base-swift` | SwiftUI | iOS app | +| `web-docs` | VitePress | Documentation site | -**Files Changed:** -- `packages/config/tsconfig/node.json` - Changed `"module": "commonjs"` → `"module": "ES2020"` -- `packages/types/tsconfig.json` - Added `"moduleResolution": "node"` - -For detailed information, see [Migration Walkthrough](docs/en/guides/module-format-migration.md). - -## 🚀 Getting Started +## Quick Start ### Prerequisites -- Node.js >= 20.0.0 -- pnpm >= 8.0.0 - Docker & Docker Compose -- Neon account (https://neon.tech) - for PostgreSQL database +- .NET 10.0 SDK +- Node.js 25+ +- pnpm 8+ -### Quick Start (One-Command Setup) - -We provide a comprehensive initialization script to get you up and running quickly: +### Run Locally ```bash -./scripts/setup/init-project.sh +# Start infrastructure (PostgreSQL, Redis, RabbitMQ, MinIO, Traefik) + all services +cd deployments/local +docker compose up -d + +# Run database migrations (per service) +./scripts/db/migrate.sh + +# Start a specific service for development +./scripts/dev/start-service.sh iam-service-net ``` -This script will: -1. Check prerequisites -2. Install dependencies -3. Generate Prisma clients -4. Create necessary `.env` files from examples +### Architecture -### Manual Installation +Each .NET service follows **Clean Architecture + CQRS**: -If you prefer to set up manually: - -```bash -# Install dependencies -pnpm install - -# Generate Prisma clients -pnpm prisma:generate - -# Start all services (development) -./scripts/dev/start-all.sh +``` +ServiceName/ + src/ + ServiceName.API/ # Controllers + MediatR Commands/Queries + ServiceName.Domain/ # Entities, aggregates, domain events (no dependencies) + ServiceName.Infrastructure/ # EF Core, repositories, migrations + tests/ + ServiceName.UnitTests/ # xUnit + FluentAssertions + ServiceName.FunctionalTests/ # WebApplicationFactory integration tests ``` -### Local Development Flow +## Documentation -1. **Database Setup**: - ```bash - ./scripts/db/setup-neon.sh - # Follow the interactive prompts to configure your Neon URL - ``` +- [ROADMAP.md](ROADMAP.md) — Development roadmap and phase tracking +- [CLAUDE.md](CLAUDE.md) — Full architecture reference and agent configuration -2. **Start Infrastructure**: - ```bash - # Starts Redis, Traefik, and Observability stack - cd deployments/local - docker-compose up -d - ``` +## Maintainer -3. **Run Migrations**: - ```bash - ./scripts/db/migrate.sh iam-service dev - ``` - -4. **Start Services**: - ```bash - ./scripts/dev/start-all.sh - # Or to start a specific service: - # ./scripts/dev/start-service.sh iam-service - ``` - -## 🛠️ Helper Scripts - -The `scripts/` directory contains bilingual (English/Vietnamese) automation scripts to streamline daily tasks: - -| Category | Script | Description | -|----------|--------|-------------| -| **Setup** | `init-project.sh` | Full project initialization | -| | `install-deps.sh` | Install dependencies | -| **Dev** | `start-all.sh` | Start infrastructure and all services | -| | `start-service.sh` | Start a specific service | -| | `logs.sh` | View logs for services or docker containers | -| | `setup-env.sh` | Helper to setup environment variables | -| **DB** | `migrate.sh` | Run Prisma migrations (dev/deploy) | -| | `seed.sh` | Seed database with initial data | -| | `backup.sh` | Backup database (supports Neon) | -| | `setup-neon.sh` | Wizard to configure Neon DB connection | -| **Utils** | `create-service.sh` | Scaffold a new microservice from template | -| | `cleanup.sh` | Clean build artifacts and caches | -| **Build** | `build-all.sh` | Build entire monorepo | -| | `build-service.sh` | Build specific service | -| **Deploy** | `deploy-staging.sh` | Deploy to staging cluster | -| | `deploy-prod.sh` | Deploy to production cluster | - -## 🛠️ Tech Stack - -**Frontend:** -- Web: Next.js 14+ (App Router) -- Mobile: Flutter 3.x -- Styling: Tailwind CSS -- State: Zustand / Provider - -**Backend:** -- Runtime: Node.js + TypeScript -- Framework: Express/NestJS (via service template) -- ORM: Prisma -- Database: PostgreSQL (Neon Serverless), Redis (Caching/Queues) - -**Infrastructure:** -- Gateway: Traefik -- Containerization: Docker -- Orchestration: Kubernetes -- Observability: Prometheus, Grafana, Loki, OpenTelemetry - -**DevOps:** -- Build System: Turborepo -- Package Manager: PNPM Workspaces -- CI/CD: GitHub Actions - -## 🌐 Coding Standards - -### Bilingual Comments -To support our diverse team, we follow a bilingual commenting standard (English & Vietnamese) for: -- Scripts -- Complex logic -- Public APIs -- Configuration files - -Example: -```bash -# EN: Verify Docker daemon is running -# VI: Xác minh Docker daemon đang chạy -``` - -### Monorepo Management -- We use **Turborepo** for build pipelines and caching. -- **PNPM Workspaces** manage dependencies across apps and services. - -## 📚 Documentation - -- [Architecture Overview](docs/en/architecture/system-design.md) -- [API Documentation](docs/en/api/openapi/) -- [Development Guide](docs/en/guides/development.md) -- [Deployment Guide](docs/en/guides/deployment.md) -- [Contributing Guide](CONTRIBUTING.md) - -## 🔐 Environment Variables - -**Important**: Never commit `.env` files. Use `.env.example` as templates. - -- **Dev**: `deployments/local/.env.local` (Shared), `services/*/.env.local` (Service specific) -- **Staging/Prod**: Managed via Kubernetes Secrets - -## 🧪 Testing - -```bash -# Run all tests -pnpm test - -# Run tests for specific package -pnpm --filter @goodgo/iam-service test - -# Run with coverage -pnpm --filter @goodgo/iam-service test:coverage -``` - -## 📦 Building - -```bash -# Build all packages and services -pnpm build - -# Build specific service -pnpm --filter @goodgo/iam-service build -``` - -## 🚢 Deployment - -See [Deployment Guide](docs/guides/deployment.md) for detailed instructions. - -### Quick Deploy - -```bash -# Local -cd deployments/local && docker-compose up -d - -# Staging (Kubernetes) -cd deployments/staging && kubectl apply -f kubernetes/ - -# Production -cd deployments/production && kubectl apply -f kubernetes/ -``` - -## 🤝 Contributing - -Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests. - -## 📄 License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. - -## 👥 Maintainer - -Built with ❤️ by **VelikHo** ([@hongochai10](https://github.com/hongochai10)) +Built by **VelikHo** ([@hongochai10](https://github.com/hongochai10)) - **Email**: hongochai10@icloud.com - **GitHub**: https://github.com/hongochai10 diff --git a/ROADMAP.md b/ROADMAP.md index 18ed2d2c..f9239b33 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # GoodGo Platform — Roadmap & Development Tracker -> Last updated: 2026-03-13 +> Last updated: 2026-03-20 > Maintained by: CTO & Agents Team > Status convention: `DONE` | `IN-PROGRESS` | `TODO` | `BLOCKED` | `SKIPPED` @@ -76,6 +76,12 @@ |---------|:----:|:------:|:-----------:|:-----:|-------| | fnb-engine-net | 5019 | PRODUCTION-READY | 6+ | 96 | KDS/Sessions/Tables/Recipes/Reservations/BaristaQueue, SignalR hub | +### MCP Server (AI Integration Layer) + +| Service | Stack | Status | Tools | Vertical | Notes | +|---------|:-----:|:------:|:-----:|:--------:|-------| +| goodgo-mcp-server | TypeScript | PRODUCTION-READY | 12 | Cafe | AI-assisted F&B ops: products CRUD, recipes, inventory, cost analysis, popular items. Routes through Traefik gateway. Audited & hardened (3c43ca5). | + --- ## III. Frontend Apps Status (Verified 2026-03-13) @@ -309,6 +315,7 @@ | Date | Decision | Rationale | Status | |------|----------|-----------|:------:| +| 2026-03-20 | MCP Server as external AI integration layer (TypeScript, not .NET) | Lightweight tooling for AI assistants, Cafe vertical first, routes through Traefik gateway | ACTIVE | | 2026-03-13 | Staff schedule via booking-service (not merchant-service) | Booking owns all scheduling/appointment logic | ACTIVE | | 2026-03-13 | Role enrichment on frontend (not BFF) | Staff role comes from merchant-service, schedule from booking-service — join on client | ACTIVE | | 2026-03-06 | IPaymentGateway in Domain, implementations in Infrastructure | Multiple gateways via same interface | ACTIVE | @@ -355,6 +362,16 @@ ## X. Recently Completed +### 2026-03-20 (MCP Server, Shop Lifecycle, Onboarding Redesign) + +| Task | Details | +|------|---------| +| GoodGo MCP Server — AI-assisted F&B operations | TypeScript MCP server with 12 tools (list/create/update/delete products, recipes, inventory check, low stock alerts, cost analysis, popular items). Cafe vertical. Commits: b7a194f, 20cf878, 3c43ca5 | +| MCP Server audit & fixes | Fixed 4 critical + 8 high severity issues: corrected API routing through Traefik gateway, input validation, error handling, auth token flow (3c43ca5) | +| Shop lifecycle management UI | Admin UI for deactivating & closing shops with confirmation dialogs and status transitions (6263eeb) | +| POS settings role-based navigation | Settings button now navigates by role — staff to /staff, admin to /admin (659e8e0) | +| Onboarding wizard redesign | Inline step progress indicator, improved layout and UX for 6-step onboarding flow (ca022de) | + ### 2026-03-13 (Schedule Module Fix) | Task | Details | @@ -456,3 +473,4 @@ CTO → Review → Move to "Recently Completed" *This file is the single source of truth for GoodGo Platform development progress.* *All agents should consult this file before starting work and update it after completing tasks.* *Last full audit: 2026-03-13 (4 parallel agents: backend, frontend, infrastructure, database)* +*Last incremental update: 2026-03-20 (MCP server, shop lifecycle, onboarding redesign, POS nav fix)* diff --git a/apps/web-client-tpos-net/README.md b/apps/web-client-tpos-net/README.md index acbba0c8..48ce8334 100644 --- a/apps/web-client-tpos-net/README.md +++ b/apps/web-client-tpos-net/README.md @@ -55,7 +55,7 @@ Base frontend web application cho GoodGo Platform được xây dựng với Bla ## Getting Started / Bắt đầu ```bash -cd apps/web-client-base-net +cd apps/web-client-tpos-net dotnet restore dotnet run --project src/WebClientTpos.Server @@ -65,7 +65,7 @@ dotnet run --project src/WebClientTpos.Server ## Project Structure / Cấu trúc ``` -web-client-base-net/ +web-client-tpos-net/ ├── src/ │ ├── WebClientTpos.Client/ # Blazor WebAssembly │ ├── WebClientTpos.Server/ # BFF with YARP Proxy diff --git a/apps/web-client-tpos-net/docs/en/README.md b/apps/web-client-tpos-net/docs/en/README.md index d61dbd3b..c4ca7c40 100644 --- a/apps/web-client-tpos-net/docs/en/README.md +++ b/apps/web-client-tpos-net/docs/en/README.md @@ -6,7 +6,7 @@ Base frontend application cho GoodGo Platform. ```bash # Navigate to project -cd apps/web-client-base-net +cd apps/web-client-tpos-net # Restore packages dotnet restore diff --git a/services/goodgo-mcp-server/SERVICE_DOCS.md b/services/goodgo-mcp-server/SERVICE_DOCS.md new file mode 100644 index 00000000..776f29c3 --- /dev/null +++ b/services/goodgo-mcp-server/SERVICE_DOCS.md @@ -0,0 +1,383 @@ +# GoodGo MCP Server - Service Documentation + +> Auto-generated from source code audit on 2026-03-20. + +## Overview + +**GoodGo MCP Server** is a TypeScript Model Context Protocol (MCP) server that enables AI assistants (Claude Code, Claude Desktop) to perform F&B shop operations -- catalog management, inventory tracking, recipe handling, and sales analytics -- by proxying requests through the Traefik API gateway to backend .NET microservices. + +- **Package**: `@goodgo/mcp-server` v1.0.0 +- **Runtime**: Node.js 25+ (ESM) +- **Language**: TypeScript 5.7+ +- **Transport**: stdio (local Claude Code integration) +- **SDK**: `@modelcontextprotocol/sdk` 1.12.1 +- **Validation**: Zod 3.24 +- **HTTP Client**: Axios 1.7 +- **Default Shop**: Cobic Coffee (`e1f392af-fe95-4c7f-8656-5b74ad5fd0a9`) +- **Auth**: JWT Bearer token (from IAM IdentityServer OAuth2 password grant) + +--- + +## Configuration + +Environment variables (`.env` file in service root): + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `API_GATEWAY_URL` | No | `http://localhost/api/v1` | Traefik gateway base URL. Docker local uses port 80. Staging: `https://api.staging.goodgo.vn/api/v1` | +| `DEFAULT_SHOP_ID` | No | `e1f392af-fe95-4c7f-8656-5b74ad5fd0a9` | Default shop UUID (Cobic Coffee). Used when tools omit `shopId`. | +| `API_TOKEN` | **Yes** | _(empty)_ | JWT Bearer token from IAM login. All API calls fail 401 without this. | + +--- + +## Architecture + +### Source Structure + +``` +goodgo-mcp-server/ + src/ + index.ts # Entry point: McpServer + StdioServerTransport, registers all tool groups + services/ + api-client.ts # Axios gateway client (single instance, Bearer interceptor, token-leak guard) + error-handler.ts # Shared errorResponse() + textResponse() helpers + tools/ + catalog-tools.ts # 4 tools: list_products, create_product, update_product, delete_product + inventory-tools.ts # 4 tools: check_inventory, record_intake, record_usage, low_stock_alerts + recipe-tools.ts # 2 tools: list_recipes, create_recipe + analytics-tools.ts # 2 tools: popular_items, cost_analysis + types/ # (reserved, currently empty) + dist/ # Compiled JS output (ESM) + .env # Local config (git-ignored) + .env.example # Template + package.json + tsconfig.json +``` + +### Gateway Routing + +All tools call a **single Axios client** pointed at `API_GATEWAY_URL` (default `http://localhost/api/v1`). Traefik routes by path prefix to the appropriate backend microservice: + +| Path Prefix | Backend Service | Tools Using It | +|-------------|----------------|----------------| +| `/products` | catalog-service-net (port 5016) | list_products, create_product, update_product, delete_product | +| `/inventory`, `/inventory/stock-in`, `/inventory/stock-out`, `/inventory/low-stock` | inventory-service-net (port 5020) | check_inventory, record_intake, record_usage, low_stock_alerts | +| `/kitchen/recipes` | fnb-engine-net (port 5018) | list_recipes, create_recipe | +| `/orders/dashboard` | order-service-net (port 5014) | popular_items, cost_analysis | + +### Error Handling + +`error-handler.ts` provides a centralized `errorResponse()` function that: + +1. Extracts structured error messages from backend `ApiResponse` format (`error.message`, `error`, `Message`, `title`) +2. Maps HTTP status codes to user-friendly messages (401 = token expired, 403 = insufficient permissions, 404 = not found, 400 = validation errors) +3. Handles network errors (ECONNREFUSED, ETIMEDOUT) with actionable guidance +4. **Strips `Authorization` headers** from error objects to prevent token leakage +5. Returns MCP-compliant `{ content: [{ type: "text", text }], isError: true }` format + +### Security + +- Bearer token injected via Axios request interceptor from `API_TOKEN` env var +- Authorization header stripped from error responses to prevent token leakage in MCP tool output +- Startup warning printed to stderr if `API_TOKEN` is not set + +--- + +## Tools (12 total) + +### Catalog Tools (4) + +#### `list_products` +List menu items/products for a shop. Returns name, price, category, stock status. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `categoryId` | string (UUID) | No | - | Filter by category | +| `isActive` | boolean | No | - | Filter by active status (omit to show all) | +| `page` | number | No | 1 | Page number | +| `pageSize` | number | No | 20 | Items per page (max 200) | + +**Backend**: `GET /products?shopId=&categoryId=&isActive=&page=&pageSize=` +**Output**: Formatted table with Name, Price (VND), Category, Active columns. + +--- + +#### `create_product` +Create a new product/menu item in the shop catalog. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `name` | string | **Yes** | - | Product name (1-200 chars) | +| `description` | string | No | - | Description (max 1000 chars) | +| `price` | number | **Yes** | - | Price in VND (positive) | +| `type` | string | No | `PreparedFood` | Product type: PreparedFood, Beverage, RetailItem | +| `categoryId` | string (UUID) | No | - | Category ID | +| `sku` | string | No | - | Stock-keeping unit code | +| `imageUrl` | string (URL) | No | - | Image URL | + +**Backend**: `POST /products` +**Output**: Created product ID, name, and formatted price. + +--- + +#### `update_product` +Update an existing product's name, price, description, or category. Fetches current values first to avoid overwriting unchanged fields (merge-patch semantics). + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `productId` | string (UUID) | **Yes** | - | Product ID to update | +| `name` | string | No | - | New name (1-200 chars) | +| `description` | string | No | - | New description (max 1000 chars) | +| `price` | number | No | - | New price in VND | +| `categoryId` | string (UUID) | No | - | New category ID | +| `imageUrl` | string (URL) | No | - | New image URL | + +**Backend**: `GET /products/{id}` (fetch current) then `PUT /products/{id}` (full update with merged fields) +**Output**: Updated fields summary. + +--- + +#### `delete_product` +Deactivate a product from the catalog (soft delete). + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `productId` | string (UUID) | **Yes** | - | Product ID to deactivate | + +**Backend**: `DELETE /products/{id}` +**Output**: Confirmation message. + +--- + +### Inventory Tools (4) + +#### `check_inventory` +Check current inventory/stock levels for a shop. Shows item name, quantity, unit, reorder level, and low stock warnings. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `skip` | number | No | 0 | Records to skip | +| `take` | number | No | 50 | Records to take (max 200) | + +**Backend**: `GET /inventory?shopId=&skip=&take=` +**Output**: Table with Name, Qty, Unit, Reorder Level, Status (OK/Low). + +--- + +#### `record_intake` +Record stock intake (nhap kho) -- when goods are received from suppliers. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `productId` | string (UUID) | **Yes** | - | Product ID to stock in | +| `amount` | number (int) | **Yes** | - | Quantity to add (positive integer) | +| `notes` | string | No | - | Notes for this intake | +| `unitCost` | number | No | - | Cost per unit | + +**Backend**: `POST /inventory/stock-in` +**Output**: Intake confirmation with product, amount, cost, and notes. + +--- + +#### `record_usage` +Record stock usage/outflow (xuat kho) -- when items are consumed, wasted, or adjusted. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `productId` | string (UUID) | **Yes** | - | Product ID to stock out | +| `amount` | number (int) | **Yes** | - | Quantity to remove (positive integer) | +| `notes` | string | No | - | Reason for usage | + +**Backend**: `POST /inventory/stock-out` +**Output**: Usage confirmation with product, amount, and notes. + +--- + +#### `low_stock_alerts` +Get items that are at or below their reorder level. Critical for preventing stockouts. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `skip` | number | No | 0 | Records to skip | +| `take` | number | No | 50 | Records to take (max 200) | + +**Backend**: `GET /inventory/low-stock?shopId=&skip=&take=` +**Output**: List of low-stock items with current quantity, reorder level, and deficit. + +--- + +### Recipe Tools (2) + +#### `list_recipes` +List all recipes for a shop. Shows recipe name, linked product, prep time, and ingredients. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | + +**Backend**: `GET /kitchen/recipes?shopId=` +**Output**: Numbered list with recipe details and ingredient breakdown (name, quantity, unit, cost). + +--- + +#### `create_recipe` +Create a new recipe with ingredients list. Links to a product in the catalog. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `productId` | string (UUID) | **Yes** | - | Catalog product this recipe is for | +| `name` | string | **Yes** | - | Recipe name (1-200 chars) | +| `instructions` | string | No | - | Preparation instructions (max 2000 chars) | +| `prepTimeMinutes` | number (int) | No | 5 | Prep time in minutes | +| `ingredients` | array | **Yes** | - | Ingredients list (min 1 item) | + +**Ingredient object schema**: + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `ingredientName` | string | **Yes** | - | Ingredient name | +| `quantity` | number | **Yes** | - | Quantity required | +| `unit` | string | **Yes** | - | Unit of measurement (g, ml, pcs, etc.) | +| `costPerUnit` | number | No | 0 | Cost per unit | +| `inventoryItemId` | string (UUID) | No | - | Linked inventory item ID | +| `quantityPerServing` | number | No | 0 | Quantity per serving for inventory deduction | + +**Backend**: `POST /kitchen/recipes` +**Output**: Created recipe ID, name, product link, prep time, and ingredient summary. + +--- + +### Analytics Tools (2) + +#### `popular_items` +Get top selling products by analyzing order data. Shows product name, quantity sold, and revenue. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | +| `period` | enum | No | `7d` | Time period: `today`, `7d`, `30d` | + +**Backend**: `GET /orders/dashboard?shopId=&period=` +**Output**: Rankings with total revenue, order count, items sold, avg order value, and per-product breakdown. + +--- + +#### `cost_analysis` +Analyze cost structure by comparing inventory costs with revenue. Shows inventory value and revenue breakdown. + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `shopId` | string (UUID) | No | `DEFAULT_SHOP_ID` | Shop ID | + +**Backend**: `GET /inventory?shopId=&take=200` + `GET /orders/dashboard?shopId=&period=30d` (parallel via `Promise.allSettled`) +**Output**: Cost analysis report with 30-day revenue, inventory value, order stats, and top cost items ranked by inventory value. + +--- + +## API Endpoints Consumed + +Summary of all backend API routes called by MCP tools: + +| Method | Route | Backend Service | Tool(s) | +|--------|-------|----------------|---------| +| GET | `/api/v1/products` | catalog-service | list_products | +| GET | `/api/v1/products/{id}` | catalog-service | update_product (fetch current) | +| POST | `/api/v1/products` | catalog-service | create_product | +| PUT | `/api/v1/products/{id}` | catalog-service | update_product | +| DELETE | `/api/v1/products/{id}` | catalog-service | delete_product | +| GET | `/api/v1/inventory` | inventory-service | check_inventory, cost_analysis | +| POST | `/api/v1/inventory/stock-in` | inventory-service | record_intake | +| POST | `/api/v1/inventory/stock-out` | inventory-service | record_usage | +| GET | `/api/v1/inventory/low-stock` | inventory-service | low_stock_alerts | +| GET | `/api/v1/kitchen/recipes` | fnb-engine | list_recipes | +| POST | `/api/v1/kitchen/recipes` | fnb-engine | create_recipe | +| GET | `/api/v1/orders/dashboard` | order-service | popular_items, cost_analysis | + +--- + +## Setup & Build + +### Prerequisites +- Node.js 25+ with ESM support +- Docker stack running (Traefik + backend services) +- Valid JWT token from IAM service + +### Install & Build +```bash +cd services/goodgo-mcp-server +npm install +npm run build # tsc -> dist/ +``` + +### Run (development) +```bash +npm run dev # tsx src/index.ts (hot reload) +``` + +### Run (production) +```bash +npm start # node dist/index.js +``` + +--- + +## Claude Code Integration + +### Register as MCP server +```bash +claude mcp add --transport stdio goodgo -- node /absolute/path/to/services/goodgo-mcp-server/dist/index.js +``` + +Or with environment variables inline: +```bash +claude mcp add --transport stdio goodgo -- \ + env API_TOKEN=eyJ... DEFAULT_SHOP_ID=e1f392af-... \ + node /absolute/path/to/services/goodgo-mcp-server/dist/index.js +``` + +### Verify registration +```bash +claude mcp list +``` + +--- + +## Token Acquisition + +The MCP server requires a valid JWT token from the IAM service (Duende IdentityServer password grant). + +### Get token via curl +```bash +curl -s http://localhost/connect/token \ + -d "grant_type=password" \ + -d "username=hongochai10@icloud.com" \ + -d "password=Velik@2026" \ + -d "client_id=password-client" \ + -d "client_secret=password-client-secret" \ + | jq -r '.access_token' +``` + +### Set token in .env +```bash +# Copy template +cp .env.example .env + +# Paste the access_token value +echo "API_TOKEN=eyJhbGciOiJSUzI1NiIs..." >> .env +``` + +### Token refresh +Tokens expire (typically 1 hour). Re-run the curl command above and update `API_TOKEN` in `.env`. The MCP server reads `.env` at startup via `dotenv`, so restart the server after updating. + +--- + +## Currency & Locale + +All prices are in **VND (Vietnamese Dong)**. The server formats prices using `Intl.NumberFormat("vi-VN")` (e.g., `45.000 VND`). When interacting with the AI assistant, prices display as `X.000d` format.