docs: move remaining analysis docs to docs/audits/
Move MCP module exploration, quick reference, and inquiries exploration documents to the centralized audit directory. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
386
docs/audits/MCP_QUICK_REFERENCE.md
Normal file
386
docs/audits/MCP_QUICK_REFERENCE.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# MCP Module - Quick Reference & Testing Guide
|
||||
|
||||
## 📋 Module at a Glance
|
||||
|
||||
| Aspect | Details |
|
||||
|--------|---------|
|
||||
| **Location** | `apps/api/src/modules/mcp/` |
|
||||
| **Total Files** | 4 source files (2 TypeScript + 1 module config + 1 export) |
|
||||
| **Test Files** | 1 test file (174 lines) |
|
||||
| **Architecture** | Presentation layer only (simplified) |
|
||||
| **Testing Framework** | Vitest with Globals enabled |
|
||||
| **Test Coverage** | Controller well tested, Module/Infrastructure untested |
|
||||
|
||||
---
|
||||
|
||||
## 📁 File Listing (Complete)
|
||||
|
||||
```
|
||||
✅ 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]
|
||||
```
|
||||
|
||||
### File Details
|
||||
|
||||
| File | Type | Lines | Status | Purpose |
|
||||
|------|------|-------|--------|---------|
|
||||
| `index.ts` | Export | 1 | ✅ | Module entry point |
|
||||
| `mcp.module.ts` | Config | 22 | ⚠️ | NestJS module setup |
|
||||
| `mcp-transport.controller.ts` | Controller | 102 | ✅ | HTTP/SSE transport |
|
||||
| `mcp-transport.controller.spec.ts` | Test | 174 | ✅ | Controller tests |
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture Diagram
|
||||
|
||||
### Current DDD Structure (Simplified)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 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) │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Missing Layers (Not Implemented)
|
||||
|
||||
```
|
||||
❌ 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Overview
|
||||
|
||||
### Test File Stats
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
### Test Breakdown by Suite
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Key Classes & Methods
|
||||
|
||||
### McpIntegrationModule
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
@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>
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Testing Patterns Used
|
||||
|
||||
### 1. Mock Pattern (Vitest)
|
||||
```typescript
|
||||
// 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. Service Mock Pattern
|
||||
```typescript
|
||||
const mockRegistry = {
|
||||
getServerNames: vi.fn(),
|
||||
getServer: vi.fn(),
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Decorator Verification Pattern
|
||||
```typescript
|
||||
// Using Reflect API for NestJS decorators
|
||||
const guards = Reflect.getMetadata('__guards__', McpTransportController);
|
||||
const throttleLimit = Reflect.getMetadata(
|
||||
'THROTTLER:LIMITdefault',
|
||||
McpTransportController.prototype.listServers,
|
||||
);
|
||||
```
|
||||
|
||||
### 4. Error Testing Pattern
|
||||
```typescript
|
||||
// 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);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Testing Patterns from Other Modules
|
||||
|
||||
### Auth Module - Simple Handler Pattern
|
||||
```typescript
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Payments Module - Complex Handler Pattern
|
||||
```typescript
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Payments Domain - DDD Pattern
|
||||
```typescript
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Infrastructure Service - Crypto Pattern
|
||||
```typescript
|
||||
// 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');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Running Tests
|
||||
|
||||
### Test Commands
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
|
||||
### Vitest Configuration
|
||||
```typescript
|
||||
// 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'],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Recommendations
|
||||
|
||||
### Immediate (High Priority)
|
||||
- ✅ Controller is well tested - maintain this
|
||||
- 📝 Add tests for `McpIntegrationModule.onModuleInit()`
|
||||
- 📝 Test module dependency injection
|
||||
|
||||
### Future (Lower Priority)
|
||||
- 🏗️ If domain logic is added, create domain tests
|
||||
- 🏗️ If application handlers are added, follow payments module pattern
|
||||
- 🏗️ Add integration tests for full SSE lifecycle
|
||||
|
||||
### Best Practices to Follow
|
||||
1. **Use globals pattern** for simple tests (like existing controller tests)
|
||||
2. **Use explicit imports** for complex domain tests
|
||||
3. **Use helper factories** for complex entity setup
|
||||
4. **Use Reflect API** for decorator verification
|
||||
5. **Test both happy path AND error cases**
|
||||
6. **Use regex matching** for error message assertions
|
||||
7. **Verify service calls** with `toHaveBeenCalledWith()`
|
||||
|
||||
---
|
||||
|
||||
## 📖 File Location Reference
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Generated: April 11, 2026
|
||||
Reference in New Issue
Block a user