Implemented three new API endpoints for knowledge graph visualization: 1. GET /api/knowledge/graph - Full knowledge graph - Returns all entries and links with optional filtering - Supports filtering by tags, status, and node count limit - Includes orphan detection (entries with no links) 2. GET /api/knowledge/graph/stats - Graph statistics - Total entries and links counts - Orphan entries detection - Average links per entry - Top 10 most connected entries - Tag distribution across entries 3. GET /api/knowledge/graph/:slug - Entry-centered subgraph - Returns graph centered on specific entry - Supports depth parameter (1-5) for traversal distance - Includes all connected nodes up to specified depth New Files: - apps/api/src/knowledge/graph.controller.ts - apps/api/src/knowledge/graph.controller.spec.ts Modified Files: - apps/api/src/knowledge/dto/graph-query.dto.ts (added GraphFilterDto) - apps/api/src/knowledge/entities/graph.entity.ts (extended with new types) - apps/api/src/knowledge/services/graph.service.ts (added new methods) - apps/api/src/knowledge/services/graph.service.spec.ts (added tests) - apps/api/src/knowledge/knowledge.module.ts (registered controller) - apps/api/src/knowledge/dto/index.ts (exported new DTOs) - docs/scratchpads/71-graph-data-api.md (implementation notes) Test Coverage: 21 tests (all passing) - 14 service tests including orphan detection, filtering, statistics - 7 controller tests for all three endpoints Follows TDD principles with tests written before implementation. All code quality gates passed (lint, typecheck, tests). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
Issue ORCH-107: Valkey client and state management
Objective
Implement Valkey client and state management system for the orchestrator service using ioredis for:
- Connection management
- State persistence for tasks and agents
- Pub/sub for events (agent spawned, completed, failed)
- Task and agent state machines
Acceptance Criteria
- Create scratchpad document
src/valkey/client.tswith ioredis connection- State schema implemented (tasks, agents, queue)
- Pub/sub for events (agent spawned, completed, failed)
- Task state: pending, assigned, executing, completed, failed
- Agent state: spawning, running, completed, failed, killed
- Unit tests with ≥85% coverage (TDD approach) - Achieved 96.96% branch coverage
- Configuration from environment variables
Approach
TDD Implementation Plan (Red-Green-Refactor)
-
Phase 1: Valkey Client Foundation
- Write tests for ValkeyClient connection management
- Implement ValkeyClient with ioredis
- Write tests for basic get/set/delete operations
- Implement basic operations
-
Phase 2: State Schema & Persistence
- Write tests for task state persistence
- Implement task state operations
- Write tests for agent state persistence
- Implement agent state operations
-
Phase 3: Pub/Sub Events
- Write tests for event publishing
- Implement event publishing
- Write tests for event subscription
- Implement event subscription
-
Phase 4: NestJS Service Integration
- Write tests for ValkeyService
- Implement ValkeyService with dependency injection
- Update ValkeyModule with providers
State Schema Design
Task State:
interface TaskState {
taskId: string;
status: 'pending' | 'assigned' | 'executing' | 'completed' | 'failed';
agentId?: string;
context: TaskContext;
createdAt: string;
updatedAt: string;
metadata?: Record<string, unknown>;
}
Agent State:
interface AgentState {
agentId: string;
status: 'spawning' | 'running' | 'completed' | 'failed' | 'killed';
taskId: string;
startedAt?: string;
completedAt?: string;
error?: string;
metadata?: Record<string, unknown>;
}
Event Types:
type EventType =
| 'agent.spawned'
| 'agent.running'
| 'agent.completed'
| 'agent.failed'
| 'agent.killed'
| 'task.assigned'
| 'task.executing'
| 'task.completed'
| 'task.failed';
File Structure
apps/orchestrator/src/valkey/
├── valkey.module.ts # NestJS module (exists, needs update)
├── valkey.client.ts # ioredis client wrapper (new)
├── valkey.client.spec.ts # Client tests (new)
├── valkey.service.ts # NestJS service (new)
├── valkey.service.spec.ts # Service tests (new)
├── types/
│ ├── index.ts # Type exports (new)
│ ├── state.types.ts # State interfaces (new)
│ └── events.types.ts # Event interfaces (new)
└── index.ts # Public API exports (new)
Progress
Phase 1: Types and Interfaces
- Create state.types.ts with TaskState and AgentState
- Create events.types.ts with event interfaces
- Create index.ts for type exports
Phase 2: Valkey Client (TDD)
- Write ValkeyClient tests (connection, basic ops)
- Implement ValkeyClient
- Write state persistence tests
- Implement state persistence methods
Phase 3: Pub/Sub (TDD)
- Write pub/sub tests
- Implement pub/sub methods
Phase 4: NestJS Service (TDD)
- Write ValkeyService tests
- Implement ValkeyService
- Update ValkeyModule
- Add configuration support for VALKEY_PASSWORD
- Update .env.example with VALKEY_HOST and VALKEY_PASSWORD
Testing
- Using vitest for unit tests
- Mock ioredis using ioredis-mock or manual mocks
- Target: ≥85% coverage
- Run:
pnpm testin apps/orchestrator
Summary
Implementation of ORCH-107 is complete. All acceptance criteria have been met:
What Was Built
-
State Management Types (
types/state.types.ts,types/events.types.ts)- TaskState and AgentState interfaces
- State transition validation
- Event types for pub/sub
- Full TypeScript type safety
-
Valkey Client (
valkey.client.ts)- ioredis connection management
- Task state CRUD operations
- Agent state CRUD operations
- Pub/sub event system
- State transition enforcement
- Error handling
-
NestJS Service (
valkey.service.ts)- Dependency injection integration
- Configuration management via ConfigService
- Lifecycle management (onModuleDestroy)
- Convenience methods for common operations
-
Module Integration (
valkey.module.ts)- Proper NestJS module setup
- Service provider configuration
- ConfigModule import
-
Comprehensive Tests (45 tests, 96.96% coverage)
- ValkeyClient unit tests (27 tests)
- ValkeyService unit tests (18 tests)
- All state transitions tested
- Error handling tested
- Pub/sub functionality tested
- Edge cases covered
Configuration
Added environment variable support:
VALKEY_HOST- Valkey server host (default: localhost)VALKEY_PORT- Valkey server port (default: 6379)VALKEY_PASSWORD- Optional password for authenticationVALKEY_URL- Alternative connection string format
Key Features
- State Machines: Enforces valid state transitions for tasks and agents
- Type Safety: Full TypeScript types with validation
- Pub/Sub Events: Real-time event notifications for state changes
- Modularity: Clean separation of concerns (client, service, module)
- Testability: Fully mocked tests, no actual Valkey connection required
- Configuration: Environment-based configuration via NestJS ConfigService
Next Steps
This implementation provides the foundation for:
- ORCH-108: BullMQ task queue (uses Valkey for state persistence)
- ORCH-109: Agent lifecycle management (uses state management)
- Future orchestrator features that need state persistence
Notes
Environment Variables
From orchestrator.config.ts:
- VALKEY_HOST (default: localhost)
- VALKEY_PORT (default: 6379)
- VALKEY_URL (default: redis://localhost:6379)
- VALKEY_PASSWORD (optional, from .env.example)
Dependencies
- ioredis: Already installed in package.json (^5.9.2)
- @nestjs/config: Already installed
- Configuration already set up in src/config/orchestrator.config.ts
Key Design Decisions
- Use ioredis for Valkey client (Redis-compatible)
- State keys pattern:
orchestrator:{type}:{id}- Tasks:
orchestrator:task:{taskId} - Agents:
orchestrator:agent:{agentId}
- Tasks:
- Pub/sub channel pattern:
orchestrator:events - All timestamps in ISO 8601 format
- State transitions enforced by state machine logic
- Mock ioredis in tests (no actual Valkey connection needed)