Phase 01.1: Hexagonal Architecture - 6 plans in 3 waves - Wave 1: Event bus + tRPC foundation (parallel) - Wave 2: Process, logging, server module refactors (parallel) - Wave 3: CLI tRPC integration - Ready for execution
5.2 KiB
5.2 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01.1-hexagonal-architecture | 01 | execute | 1 |
|
true |
Purpose: Establish extensible event infrastructure that can be swapped for external systems (RabbitMQ, WebSocket forwarding) later. All modules will communicate through this event bus. Output: Working event bus with typed domain events and full test coverage.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
@src/index.ts @src/process/types.ts @src/logging/types.ts @src/server/types.ts @package.json
Task 1: Install and configure Vitest test framework package.json, vitest.config.ts Install vitest as dev dependency: `npm install -D vitest`Create vitest.config.ts with:
- TypeScript support (uses tsconfig.json automatically)
- Test globals enabled (describe, it, expect without imports)
- Coverage reporter (optional, for future use)
- Test file pattern: **/*.test.ts
Add npm scripts to package.json:
- "test": "vitest run"
- "test:watch": "vitest"
- "test:coverage": "vitest run --coverage"
npm test runs successfully (0 tests found is fine at this stage)
Vitest configured, npm test works, test:watch works
Task 2: Create EventBus port interface and EventEmitter adapter
src/events/types.ts, src/events/bus.ts, src/events/index.ts
Create src/events/types.ts:
- Define EventBus interface (the PORT):
```typescript
export interface EventBus {
emit(event: T): void;
on(eventType: T['type'], handler: (event: T) => void): void;
off(eventType: T['type'], handler: (event: T) => void): void;
once(eventType: T['type'], handler: (event: T) => void): void;
}
```
- Define base DomainEvent interface:
```typescript
export interface DomainEvent {
type: string;
timestamp: Date;
payload: unknown;
}
```
Create src/events/bus.ts:
- Implement EventEmitterBus class that implements EventBus interface
- Use Node.js EventEmitter internally
- Wrap EventEmitter methods to match EventBus interface
- Add type safety for event emission
Create src/events/index.ts:
- Export EventBus interface
- Export EventEmitterBus class
- Export DomainEvent type
- Export convenience function: createEventBus() that returns EventEmitterBus instance
Key design: EventBus interface is the PORT. EventEmitterBus is the ADAPTER.
This allows swapping to RabbitMQ/Kafka/WebSocket later without changing consumers.
TypeScript compiles: npm run build
EventBus interface defined, EventEmitterBus implemented, exports working
Task 3: Define domain events with typed payloads and write tests
src/events/types.ts, src/events/bus.test.ts
Add domain event types to src/events/types.ts:
Process events:
- ProcessSpawned: { processId: string, pid: number, command: string }
- ProcessStopped: { processId: string, pid: number, exitCode: number | null }
- ProcessCrashed: { processId: string, pid: number, signal: string | null }
Server events:
- ServerStarted: { port: number, host: string, pid: number }
- ServerStopped: { uptime: number }
Log events:
- LogEntry: { processId: string, stream: 'stdout' | 'stderr', data: string }
Create union type: DomainEventMap that maps event type strings to payload types.
This enables type-safe event handling.
Create src/events/bus.test.ts:
- Test emit/on pattern works
- Test once fires only once
- Test off removes handler
- Test multiple handlers for same event
- Test typed event payloads (TypeScript compilation = passing)
- Test events include timestamp automatically
npm test passes with all event bus tests green
Domain events defined, all tests pass, type safety verified
Before declaring plan complete:
- [ ] npm run build succeeds
- [ ] npm test passes (event bus tests)
- [ ] EventBus interface is exported from src/events/index.ts
- [ ] EventEmitterBus implements EventBus correctly
- [ ] All domain events have typed payloads
<success_criteria>
- All tasks completed
- All verification checks pass
- Event bus is extensible (interface-based)
- Tests prove the pattern works </success_criteria>