Implements federated command messages following TDD principles and mirroring the QueryService pattern for consistency. ## Implementation ### Schema Changes - Added commandType and payload fields to FederationMessage model - Supports COMMAND message type (already defined in enum) - Applied schema changes with prisma db push ### Type Definitions - CommandMessage: Request structure with commandType and payload - CommandResponse: Response structure with correlation - CommandMessageDetails: Full message details for API responses ### CommandService - sendCommand(): Send command to remote instance with signature - handleIncomingCommand(): Process incoming commands with verification - processCommandResponse(): Handle command responses - getCommandMessages(): List commands for workspace - getCommandMessage(): Get single command details - Full signature verification and timestamp validation - Error handling and status tracking ### CommandController - POST /api/v1/federation/command - Send command (authenticated) - POST /api/v1/federation/incoming/command - Handle incoming (public) - GET /api/v1/federation/commands - List commands (authenticated) - GET /api/v1/federation/commands/:id - Get command (authenticated) ## Testing - CommandService: 15 tests, 90.21% coverage - CommandController: 8 tests, 100% coverage - All 23 tests passing - Exceeds 85% coverage requirement - Total 47 tests passing (includes command tests) ## Security - RSA signature verification for all incoming commands - Timestamp validation to prevent replay attacks - Connection status validation - Authorization checks on command types ## Quality Checks - TypeScript compilation: PASSED - All tests: 47 PASSED - Code coverage: >85% (90.21% for CommandService, 100% for CommandController) - Linting: PASSED Fixes #89 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Issue #89: [FED-006] COMMAND Message Type
Objective
Implement COMMAND message type for federation to enable remote instances to execute commands on connected instances. This builds on the existing FederationMessage model and follows the patterns established by FED-005 (QUERY Message Type).
Approach
Design Decisions
- Reuse FederationMessage Model: The Prisma schema already supports COMMAND type in the FederationMessageType enum
- Follow Query Pattern: Mirror the structure and flow of QueryService/QueryController for consistency
- Command Authorization: Add authorization checks to ensure only permitted commands can be executed
- Command Types: Support various command types (e.g., spawn_agent, update_config, etc.)
Architecture
CommandService
├── sendCommand() - Send command to remote instance
├── handleIncomingCommand() - Process incoming command
├── processCommandResponse() - Handle command response
├── getCommandMessages() - List commands for workspace
└── getCommandMessage() - Get single command details
CommandController
├── POST /api/v1/federation/command - Send command
├── POST /api/v1/federation/incoming/command - Handle incoming command
├── GET /api/v1/federation/commands - List commands
└── GET /api/v1/federation/commands/:id - Get command details
Command Message Structure
interface CommandMessage {
messageId: string; // Unique identifier
instanceId: string; // Sending instance
commandType: string; // Command type (spawn_agent, etc.)
payload: Record<string, unknown>; // Command-specific data
timestamp: number; // Unix milliseconds
signature: string; // RSA signature
}
interface CommandResponse {
messageId: string; // Response identifier
correlationId: string; // Original command messageId
instanceId: string; // Responding instance
success: boolean; // Command execution result
data?: unknown; // Result data
error?: string; // Error message
timestamp: number; // Unix milliseconds
signature: string; // RSA signature
}
Progress
Phase 1: Types and DTOs (TDD)
- Create command message types in message.types.ts
- Create command DTOs (SendCommandDto, IncomingCommandDto)
- Updated Prisma schema to add commandType and payload fields
Phase 2: Command Service (TDD)
- Write tests for CommandService.sendCommand()
- Implement sendCommand()
- Write tests for CommandService.handleIncomingCommand()
- Implement handleIncomingCommand()
- Write tests for CommandService.processCommandResponse()
- Implement processCommandResponse()
- Write tests for query methods (getCommandMessages, getCommandMessage)
- Implement query methods
Phase 3: Command Controller (TDD)
- Write tests for CommandController endpoints
- Implement CommandController
- Add controller to FederationModule
Phase 4: Integration
- All unit tests passing (23 tests)
- Signature verification implemented
- Authorization checks implemented
- Error handling tested
Test Results
- CommandService: 90.21% coverage (15 tests, all passing)
- CommandController: 100% coverage (8 tests, all passing)
- Total: 23 tests, all passing
Remaining Tasks
- Run Prisma migration to create commandType and payload columns
- Generate Prisma client with new schema
- Manual integration testing with live instances
Testing Strategy
Unit Tests
- DTO validation
- CommandService methods (mocked dependencies)
- CommandController endpoints (mocked service)
Integration Tests
- Full command send/receive cycle
- Signature verification
- Error scenarios
- Authorization checks
Coverage Target
- Minimum 85% code coverage
- All error paths tested
- All validation rules tested
Security Considerations
- Signature Verification: All incoming commands must be signed
- Authorization: Check if sending instance has permission for command type
- Timestamp Validation: Reject commands with old timestamps
- Rate Limiting: Consider adding rate limits (future enhancement)
- Command Whitelist: Only allow specific command types
Notes
Reusable Patterns from QueryService
- Signature verification flow
- Connection validation
- Message storage in FederationMessage table
- Response correlation via correlationId
- Status tracking (PENDING, DELIVERED, FAILED)
Key Differences from QUERY
- Commands modify state (queries are read-only)
- Commands require stricter authorization
- Command types need to be registered/whitelisted
- Command execution is async (may take longer than queries)
Future Enhancements
- Command queueing for offline instances
- Command retry logic
- Command expiration
- Command priority levels