Files
goodgo-platform/docs/audits/MCP_MODULE_EXPLORATION_2.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

7.8 KiB

Khám Phá Module MCP - Nền Tảng GoodGo

1. CẤU TRÚC MODULE VÀ TỆP NGUỒN

Cấu Trúc Thư Mục

apps/api/src/modules/mcp/
├── index.ts
├── mcp.module.ts
└── presentation/
    ├── mcp-transport.controller.ts
    └── __tests__/
        └── mcp-transport.controller.spec.ts

Tất Cả Tệp Nguồn (4 tệp)

1. apps/api/src/modules/mcp/index.ts

  • Loại: Điểm vào module (xuất khẩu)
  • Số dòng: 1
  • Mục đích: Xuất khẩu McpIntegrationModule
  • Xuất khẩu: { McpIntegrationModule }

2. apps/api/src/modules/mcp/mcp.module.ts

  • Loại: Cấu hình Module NestJS (22 dòng)
  • Lớp chính: McpIntegrationModule implements OnModuleInit
  • Trách nhiệm:
    • Thiết lập module MCP cốt lõi với cấu hình
    • Khởi tạo TypesenseClient cho registry MCP
    • Ghi nhật ký tên máy chủ đã khởi tạo khi module khởi động
  • Các phụ thuộc được tiêm:
    • TypesenseClientService (từ SearchModule)
    • McpRegistryService (từ @goodgo/mcp-servers)
    • LoggerService (từ SharedModule)
  • Nhập khẩu: SearchModule, AuthModule, McpCoreModule.forRoot()
  • Controllers: McpTransportController
  • Vòng đời: Triển khai onModuleInit()

3. apps/api/src/modules/mcp/presentation/mcp-transport.controller.ts

  • Loại: Controller NestJS (102 dòng)
  • Lớp chính: McpTransportController
  • Trách nhiệm: Lớp truyền tải HTTP cho các kết nối SSE của MCP
  • Decorator: @ApiTags, @ApiBearerAuth, @Controller, @UseGuards(JwtAuthGuard)
  • Thuộc tính: transports: Map<string, SSEServerTransport> (quản lý phiên)
  • Được tiêm: registry: McpRegistryService

Các endpoint:

  1. GET /mcp/servers - Liệt kê các máy chủ MCP khả dụng (Throttle: 30/60 giây)
  2. GET /mcp/:serverName/sse - Mở kết nối SSE (Throttle: 5/60 giây, giới hạn chặt hơn)
  3. POST /mcp/:serverName/messages - Gửi tin nhắn tới phiên (Throttle: 30/60 giây)

4. apps/api/src/modules/mcp/presentation/tests/mcp-transport.controller.spec.ts

  • Loại: Bộ kiểm thử đơn vị (174 dòng)
  • Framework: Vitest
  • Kiểm thử: 11 tổng cộng trong 4 khối describe
  • Phạm vi bao phủ: Decorator bảo mật, listServers, handleSse, handleMessage

2. TÓM TẮT CÁC TỆP KIỂM THỬ

Tổng cộng: 1 tệp kiểm thử (174 dòng)

Tệp: mcp-transport.controller.spec.ts

  • Bộ kiểm thử: 4 khối describe
  • Tổng số kiểm thử: 11
  • Trạng thái: Được kiểm thử đầy đủ
  • Phạm vi bao phủ: Các endpoint controller, bảo mật, xử lý lỗi

3. CẤU TRÚC LỚP DDD

Trạng thái hiện tại: ĐƠN GIẢN HÓA (chỉ có lớp Presentation)

Những gì TỒN TẠI:

  • Lớp Presentation
    • presentation/mcp-transport.controller.ts (102 dòng)
    • presentation/__tests__/mcp-transport.controller.spec.ts (174 dòng)

Những gì KHÔNG TỒN TẠI:

  • Lớp Domain - Không có entity, value object, event
  • Lớp Application - Không có handler, command, query
  • Lớp Infrastructure - Không có repository, adapter

Ghi chú kiến trúc:

  • Hoạt động như lớp bọc tích hợp cho @goodgo/mcp-servers
  • Cầu nối HTTP-to-SSE đơn giản
  • Theo dõi phiên trong bộ nhớ thông qua Map
  • Không có logic nghiệp vụ hay lưu trữ dữ liệu

4. CÁC LỚP/HANDLER CHÍNH

McpIntegrationModule

  • Trạng thái: ⚠️ Được kiểm thử một phần
  • Phương thức: constructor, onModuleInit()
  • Kiểm thử cần thêm: Khởi tạo module, tích hợp service

McpTransportController

  • Trạng thái: Được kiểm thử đầy đủ
  • Phương thức: listServers(), handleSse(), handleMessage()
  • Kiểm thử: 11 bài kiểm thử toàn diện bao phủ tất cả phương thức

5. MẪU KIỂM THỬ TỪ CÁC MODULE KHÁC

Mẫu 1: Module Auth (Handler đơn giản)

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);
  });
});

Mẫu 2: Module Payments (Handler phức tạp)

describe('CreatePaymentHandler', () => {
  let handler: CreatePaymentHandler;
  let mockPaymentRepo: { [K in keyof IPaymentRepository]: ReturnType<typeof vi.fn> };
  let mockGatewayFactory: { getGateway: ReturnType<typeof vi.fn> };
  
  beforeEach(() => {
    mockPaymentRepo = {
      findById: vi.fn(),
      save: vi.fn().mockResolvedValue(undefined),
    };
    handler = new CreatePaymentHandler(mockPaymentRepo as any, mockGatewayFactory as any);
  });
  
  it('creates payment successfully', async () => {
    const result = await handler.execute(command);
    expect(result.paymentId).toBeDefined();
    expect(mockPaymentRepo.save).toHaveBeenCalledTimes(1);
  });
});

Mẫu 3: Kiểm thử Domain Entity

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);
  });
});

Mẫu 4: Kiểm thử Service Infrastructure

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);
  });
});

6. TÓM TẮT QUY ƯỚC KIỂM THỬ

Framework và Thiết lập

  • Framework: Vitest
  • Môi trường: Node.js
  • Globals: Được bật
  • Mẫu tệp: *.spec.ts
  • Tổ chức kiểm thử: Thư mục con __tests__/

Mẫu Mock

  1. Service Mock: mockService = { method: vi.fn().mockResolvedValue(value) }
  2. Module Mock: vi.mock('@goodgo/mcp-servers', () => ({ ... }))
  3. Configuration Mock: get: vi.fn((key) => env[key])

Cấu Trúc Kiểm Thử

describe('ClassName', () => {
  let instance: ClassName;
  let mockDep1: Mock;
  
  beforeEach(() => {
    mockDep1 = { method: vi.fn() };
    instance = new ClassName(mockDep1 as any);
  });
  
  describe('methodName', () => {
    it('happy path', async () => {
      mockDep1.method.mockResolvedValue(expected);
      const result = await instance.method();
      expect(result).toEqual(expected);
    });
  });
});

Lệnh Kiểm Thử

# Chạy kiểm thử MCP
pnpm test -- src/modules/mcp

# Chế độ theo dõi
pnpm test -- --watch src/modules/mcp

# Với độ bao phủ
pnpm test -- --coverage src/modules/mcp

7. KHUYẾN NGHỊ

Tức thì

  • Duy trì độ bao phủ kiểm thử controller
  • 📝 Thêm kiểm thử cho McpIntegrationModule.onModuleInit()
  • 📝 Kiểm thử tiêm phụ thuộc module

Tương lai

  • 🏗️ Thêm kiểm thử tích hợp cho vòng đời SSE đầy đủ
  • 🏗️ Nếu thêm logic domain, tuân theo mẫu module payments
  • 🏗️ Nếu thêm handler, sử dụng mẫu CQRS từ các module auth/payments