Implement JobStepsModule for granular step tracking within runner jobs. Features: - Create and track job steps (SETUP, EXECUTION, VALIDATION, CLEANUP) - Track step status transitions (PENDING → RUNNING → COMPLETED/FAILED) - Record token usage for AI_ACTION steps - Calculate step duration automatically - GET endpoints for listing and retrieving steps Implementation: - JobStepsService: CRUD operations, status tracking, duration calculation - JobStepsController: GET /runner-jobs/:jobId/steps endpoints - DTOs: CreateStepDto, UpdateStepDto with validation - Full unit test coverage (16 tests) Quality gates: - Build: ✅ Passed - Lint: ✅ Passed - Tests: ✅ 16/16 passed - Coverage: ✅ 100% statements, 100% functions, 100% lines, 83.33% branches Also fixed pre-existing TypeScript strict mode issue in job-events DTO. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
110 lines
3.5 KiB
Markdown
110 lines
3.5 KiB
Markdown
# Issue #169: Job events and audit logging
|
|
|
|
## Objective
|
|
|
|
Implement job-events module for immutable audit logging using event sourcing pattern.
|
|
|
|
## Approach
|
|
|
|
1. Create module structure (module, service, controller, DTOs)
|
|
2. Define event type constants
|
|
3. Implement event emission and persistence (PostgreSQL)
|
|
4. Add API endpoints for querying events
|
|
5. Follow TDD: Write tests first, then implementation
|
|
|
|
## Event Types
|
|
|
|
- Job lifecycle: job.created, job.queued, job.started, job.completed, job.failed
|
|
- Step lifecycle: step.started, step.progress, step.output, step.completed
|
|
- AI events: ai.tool_called, ai.tokens_used, ai.artifact_created
|
|
- Gate events: gate.started, gate.passed, gate.failed
|
|
|
|
## Storage Strategy
|
|
|
|
- PostgreSQL: Immutable audit log (permanent)
|
|
- Valkey Streams: Deferred to future issue
|
|
- Valkey Pub/Sub: Deferred to future issue
|
|
|
|
## API Endpoints
|
|
|
|
- GET /runner-jobs/:jobId/events - List events for a job
|
|
- GET /runner-jobs/:jobId/events/stream - SSE stream (Phase 4, deferred)
|
|
|
|
## Progress
|
|
|
|
- [x] Create scratchpad
|
|
- [x] Review existing schema (JobEvent model)
|
|
- [x] Define event type constants
|
|
- [x] Write tests for JobEventsService
|
|
- [x] Implement JobEventsService
|
|
- [x] Write tests for JobEventsController
|
|
- [x] Implement JobEventsController
|
|
- [x] Create JobEventsModule
|
|
- [x] Register modules in app.module.ts
|
|
- [x] Run quality gates (typecheck, lint, build, test)
|
|
- [x] Commit changes
|
|
|
|
## Testing
|
|
|
|
- Unit tests for service (event emission, persistence, querying)
|
|
- Unit tests for controller (endpoint behavior)
|
|
- Target: >85% coverage
|
|
|
|
Results:
|
|
|
|
- JobEventsService: 13 tests passed
|
|
- JobEventsController: 4 tests passed
|
|
- Total: 17 tests passed
|
|
- All quality gates passed (typecheck, lint, build, test)
|
|
|
|
## Notes
|
|
|
|
- Events are immutable once created
|
|
- JobEvent model already exists in Prisma schema (from #164)
|
|
- RunnerJobsModule available (from #167)
|
|
- SSE streaming deferred to Phase 4
|
|
|
|
## Implementation Details
|
|
|
|
Files Created:
|
|
|
|
- /apps/api/src/job-events/event-types.ts - Event type constants
|
|
- /apps/api/src/job-events/dto/create-event.dto.ts - DTO for creating events
|
|
- /apps/api/src/job-events/dto/query-events.dto.ts - DTO for querying events
|
|
- /apps/api/src/job-events/dto/index.ts - DTO exports
|
|
- /apps/api/src/job-events/job-events.service.ts - Event service implementation
|
|
- /apps/api/src/job-events/job-events.service.spec.ts - Service tests (13 tests)
|
|
- /apps/api/src/job-events/job-events.controller.ts - Event controller
|
|
- /apps/api/src/job-events/job-events.controller.spec.ts - Controller tests (4 tests)
|
|
- /apps/api/src/job-events/job-events.module.ts - Module definition
|
|
- /apps/api/src/job-events/index.ts - Module exports
|
|
|
|
Files Modified:
|
|
|
|
- /apps/api/src/app.module.ts - Registered JobEventsModule
|
|
|
|
Event Types Implemented:
|
|
|
|
- Job lifecycle: job.created, job.queued, job.started, job.completed, job.failed, job.cancelled
|
|
- Step lifecycle: step.started, step.progress, step.output, step.completed, step.failed
|
|
- AI events: ai.tool_called, ai.tokens_used, ai.artifact_created
|
|
- Gate events: gate.started, gate.passed, gate.failed
|
|
|
|
API Endpoints:
|
|
|
|
- GET /api/runner-jobs/:jobId/events - List events for a job (with pagination and filtering)
|
|
|
|
Service Methods:
|
|
|
|
- emitEvent() - Generic event emission
|
|
- getEventsByJobId() - Query events with filters
|
|
- Convenience methods: emitJobCreated(), emitJobStarted(), emitStepStarted(), emitAiTokensUsed(), etc.
|
|
|
|
Quality Gates:
|
|
|
|
- Typecheck: PASSED
|
|
- Lint: PASSED
|
|
- Build: PASSED
|
|
- Tests: PASSED (17/17 tests)
|
|
- Full test suite: PASSED (1327 tests)
|