Files
goodgo-platform/docs/audits/MCP_QUICK_REFERENCE.md
Ho Ngoc Hai 11f2bf26e6
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
chore: update project documentation, audit reports, and initialize IDE configuration files
2026-04-19 03:12:54 +07:00

11 KiB

Module MCP - Hướng Dẫn Tham Khảo Nhanh & Kiểm Thử

📋 Tổng Quan Module

Khía cạnh Chi tiết
Vị trí apps/api/src/modules/mcp/
Tổng số tệp 4 tệp nguồn (2 TypeScript + 1 cấu hình module + 1 xuất)
Tệp kiểm thử 1 tệp kiểm thử (174 dòng)
Kiến trúc Chỉ có tầng trình bày (đơn giản hóa)
Framework kiểm thử Vitest với Globals được bật
Độ phủ kiểm thử Controller được kiểm thử kỹ, Module/Infrastructure chưa được kiểm thử

📁 Danh Sách Tệp (Đầy Đủ)

✅ TESTED              ✅ SOURCE               ❌ NOT TESTED
─────────────────────────────────────────────────────────────
MCP module/           mcp/
├── mcp.module.ts          [Module config - 22 lines]
├── index.ts                [Re-export - 1 line]
└── presentation/
    ├── mcp-transport.controller.ts    [Controller - 102 lines]
    └── __tests__/
        └── mcp-transport.controller.spec.ts  ✅ [174 lines]

Chi Tiết Tệp

Tệp Loại Dòng Trạng thái Mục đích
index.ts Xuất 1 Điểm vào module
mcp.module.ts Cấu hình 22 ⚠️ Thiết lập module NestJS
mcp-transport.controller.ts Controller 102 Vận chuyển HTTP/SSE
mcp-transport.controller.spec.ts Kiểm thử 174 Kiểm thử controller

🏗️ Sơ Đồ Kiến Trúc

Cấu Trúc DDD Hiện Tại (Đơn Giản Hóa)

┌─────────────────────────────────────────────────┐
│       Presentation Layer (Only)             ✅ │
├─────────────────────────────────────────────────┤
│  • McpTransportController                       │
│    - GET /mcp/servers (list)                    │
│    - GET /mcp/:serverName/sse (connect)         │
│    - POST /mcp/:serverName/messages (send)      │
├─────────────────────────────────────────────────┤
│  Dependencies:                                  │
│  • McpRegistryService (external)                │
│  • JwtAuthGuard (auth layer)                    │
│  • SSEServerTransport (external)                │
└─────────────────────────────────────────────────┘

Các Tầng Còn Thiếu (Chưa Được Triển Khai)

❌ Domain Layer
   - No entities, value objects, events
   - No business logic abstractions

❌ Application Layer  
   - No CQRS handlers
   - No command/query objects
   - No use case orchestration

❌ Infrastructure Layer
   - No repositories
   - No external service adapters
   - No persistence logic

🧪 Tổng Quan Kiểm Thử

Thống Kê Tệp Kiểm Thử

File: mcp-transport.controller.spec.ts
├── Total Tests: 11
├── Test Suites: 4 describe blocks
├── Total Lines: 174
└── Coverage Areas:
    ├── Security Decorators: 4 tests
    ├── listServers(): 2 tests
    ├── handleSse(): 3 tests
    └── handleMessage(): 2 tests

Phân Tích Kiểm Thử Theo Bộ

1. Security Decorators (4 tests)
   ├── JwtAuthGuard applied
   ├── listServers throttle (30 req/60s)
   ├── handleSse throttle (5 req/60s) ⚡ stricter
   └── handleMessage throttle (30 req/60s)

2. listServers (2 tests)
   ├── Returns server list
   └── Handles empty list

3. handleSse (3 tests)
   ├── Throws NOT_FOUND for missing server
   ├── Creates transport & connects
   └── Cleans up on connection close

4. handleMessage (2 tests)
   ├── Throws BAD_REQUEST for missing sessionId
   └── Throws NOT_FOUND for expired session

🎯 Các Lớp & Phương Thức Chính

McpIntegrationModule

class McpIntegrationModule implements OnModuleInit {
  constructor(
    typesenseClient: TypesenseClientService,
    mcpRegistry: McpRegistryService,
    logger: LoggerService,
  ) {}
  
  async onModuleInit(): Promise<void> {
    // 1. Set typesense client on registry
    // 2. Re-initialize servers
    // 3. Log initialized servers
  }
}

McpTransportController

@Controller('mcp')
@UseGuards(JwtAuthGuard)
class McpTransportController {
  private transports: Map<string, SSEServerTransport>
  
  constructor(registry: McpRegistryService) {}
  
  @Get('servers')
  @Throttle(30/60s)
  listServers(): { servers: string[] }
  
  @Get(':serverName/sse')
  @Throttle(5/60s)  // Stricter limit for SSE
  async handleSse(serverName, user, req, res): Promise<void>
  
  @Post(':serverName/messages')
  @Throttle(30/60s)
  async handleMessage(serverName, user, req, res): Promise<void>
}

🔧 Các Mẫu Kiểm Thử Được Sử Dụng

1. Mẫu Mock (Vitest)

// Mocking external module classes
vi.mock('@goodgo/mcp-servers', () => ({
  SSEServerTransport: class MockSSEServerTransport {
    sessionId = 'mock-session-id';
    handlePostMessage = vi.fn().mockResolvedValue(undefined);
    constructor(path: string, res: unknown) {}
  },
}));

2. Mẫu Mock Dịch Vụ

const mockRegistry = {
  getServerNames: vi.fn(),
  getServer: vi.fn(),
};

3. Mẫu Xác Minh Decorator

// Using Reflect API for NestJS decorators
const guards = Reflect.getMetadata('__guards__', McpTransportController);
const throttleLimit = Reflect.getMetadata(
  'THROTTLER:LIMITdefault',
  McpTransportController.prototype.listServers,
);

4. Mẫu Kiểm Thử Lỗi

// Testing HTTP errors
await expect(
  controller.handleSse('nonexistent', user, req, res)
).rejects.toThrow(HttpException);

// Checking status code
try {
  await controller.handleSse(...);
} catch (error) {
  expect((error as HttpException).getStatus()).toBe(HttpStatus.NOT_FOUND);
}

📚 Các Mẫu Kiểm Thử Từ Các Module Khác

Module Auth - Mẫu Handler Đơn Giản

// Minimal dependencies, focused testing
describe('LoginUserHandler', () => {
  let handler: LoginUserHandler;
  let mockTokenService = { generateTokenPair: vi.fn() };
  
  beforeEach(() => {
    handler = new LoginUserHandler(mockTokenService as any);
  });
  
  it('generates token pair', async () => {
    mockTokenService.generateTokenPair.mockResolvedValue(tokenPair);
    const result = await handler.execute(command);
    expect(result).toEqual(tokenPair);
  });
});

Module Payments - Mẫu Handler Phức Tạp

// Multiple dependencies, rich testing scenarios
describe('CreatePaymentHandler', () => {
  let handler: CreatePaymentHandler;
  let mockPaymentRepo: { [K in keyof IPaymentRepository]: ReturnType<typeof vi.fn> };
  let mockGatewayFactory: { getGateway: ReturnType<typeof vi.fn> };
  let mockEventBus: { publish: ReturnType<typeof vi.fn> };
  
  beforeEach(() => {
    mockPaymentRepo = {
      findById: vi.fn(),
      save: vi.fn().mockResolvedValue(undefined),
      // ... more methods
    };
    handler = new CreatePaymentHandler(mockPaymentRepo as any, ...);
  });
  
  it('creates payment successfully', async () => {
    // Rich test scenario with multiple assertions
    expect(result.paymentId).toBeDefined();
    expect(mockPaymentRepo.save).toHaveBeenCalledTimes(1);
    expect(mockEventBus.publish).toHaveBeenCalled();
  });
});

Domain Payments - Mẫu DDD

// Explicit imports, entity behavior testing
import { describe, it, expect } from 'vitest';

describe('PaymentEntity', () => {
  it('should create payment with events', () => {
    const payment = PaymentEntity.createNew(...);
    
    expect(payment.status).toBe('PENDING');
    expect(payment.domainEvents).toHaveLength(1);
    expect(payment.domainEvents[0]).toBeInstanceOf(PaymentCreatedEvent);
  });
  
  it('should not refund non-completed payment', () => {
    const payment = createPayment(); // helper
    const result = payment.markRefunded();
    expect(result.isErr).toBe(true);
  });
});

Dịch Vụ Infrastructure - Mẫu Crypto

// Complex external service testing
describe('ZalopayService', () => {
  let service: ZalopayService;
  
  beforeEach(() => {
    const mockConfig = {
      get: vi.fn((key) => env[key]),
      getOrThrow: vi.fn((key) => env[key] || throw),
    };
    service = new ZalopayService(mockConfig as any);
  });
  
  it('should verify valid callback', () => {
    const mac = crypto.createHmac('sha256', key2).update(dataStr).digest('hex');
    const result = service.verifyCallback({ data: dataStr, mac });
    
    expect(result.isValid).toBe(true);
    expect(result.orderId).toBe('expected-order-id');
  });
});

🚀 Chạy Kiểm Thử

Lệnh Kiểm Thử

# Run all MCP tests
pnpm test -- src/modules/mcp

# Run with watch mode
pnpm test -- --watch src/modules/mcp

# Run with coverage
pnpm test -- --coverage src/modules/mcp

# Run specific test file
pnpm test -- src/modules/mcp/presentation/__tests__/mcp-transport.controller.spec.ts

Cấu Hình Vitest

// apps/api/vitest.config.ts
{
  test: {
    globals: true,              // vi, describe, it, expect available globally
    environment: 'node',
    include: ['src/**/*.spec.ts'], // Matches *.spec.ts pattern
    exclude: ['**/*.integration.spec.ts', 'node_modules'],
  }
}

💡 Khuyến Nghị

Ngay Lập Tức (Ưu Tiên Cao)

  • Controller được kiểm thử kỹ - duy trì điều này
  • 📝 Thêm kiểm thử cho McpIntegrationModule.onModuleInit()
  • 📝 Kiểm thử dependency injection của module

Tương Lai (Ưu Tiên Thấp Hơn)

  • 🏗️ Nếu logic domain được thêm vào, tạo kiểm thử domain
  • 🏗️ Nếu application handler được thêm vào, theo mẫu module payments
  • 🏗️ Thêm kiểm thử tích hợp cho toàn bộ vòng đời SSE

Các Phương Pháp Tốt Nhất Cần Tuân Theo

  1. Sử dụng mẫu globals cho các kiểm thử đơn giản (như kiểm thử controller hiện có)
  2. Sử dụng import tường minh cho các kiểm thử domain phức tạp
  3. Sử dụng helper factory cho thiết lập entity phức tạp
  4. Sử dụng Reflect API để xác minh decorator
  5. Kiểm thử cả happy path VÀ các trường hợp lỗi
  6. Sử dụng khớp regex cho các xác nhận thông báo lỗi
  7. Xác minh lời gọi dịch vụ với toHaveBeenCalledWith()

📖 Tham Chiếu Vị Trí Tệp

GoodGo Platform Root
├── apps/api/src/modules/mcp/              ← MCP Module
│   ├── index.ts
│   ├── mcp.module.ts
│   └── presentation/
│       ├── mcp-transport.controller.ts
│       └── __tests__/
│           └── mcp-transport.controller.spec.ts
│
├── apps/api/vitest.config.ts              ← Test config
├── apps/api/package.json                  ← Test scripts
│
└── MCP_MODULE_EXPLORATION.md              ← Full documentation

Được tạo: ngày 11 tháng 4 năm 2026