feat(#176): Integrate M4.2 infrastructure with M4.1 coordinator
Add CoordinatorIntegrationModule providing REST API endpoints for the Python coordinator to communicate with the NestJS API infrastructure: - POST /coordinator/jobs - Create job from coordinator webhook events - PATCH /coordinator/jobs/:id/status - Update job status (PENDING -> RUNNING) - PATCH /coordinator/jobs/:id/progress - Update job progress percentage - POST /coordinator/jobs/:id/complete - Mark job complete with results - POST /coordinator/jobs/:id/fail - Mark job failed with gate results - GET /coordinator/jobs/:id - Get job details with events and steps - GET /coordinator/health - Integration health check Integration features: - Job creation dispatches to BullMQ queues - Status updates emit JobEvents for audit logging - Completion/failure events broadcast via Herald to Discord - Status transition validation (PENDING -> QUEUED -> RUNNING -> COMPLETED/FAILED) - Health check includes BullMQ connection status and queue counts Also adds JOB_PROGRESS event type to event-types.ts for progress tracking. Fixes #176 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
20
apps/api/src/coordinator-integration/dto/complete-job.dto.ts
Normal file
20
apps/api/src/coordinator-integration/dto/complete-job.dto.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { IsOptional, IsObject, IsNumber, Min } from "class-validator";
|
||||
|
||||
/**
|
||||
* DTO for completing a job from the coordinator
|
||||
*/
|
||||
export class CompleteJobDto {
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
result?: Record<string, unknown>;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
tokensUsed?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
durationSeconds?: number;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { IsString, IsOptional, IsNumber, IsObject, Min, Max, IsUUID } from "class-validator";
|
||||
|
||||
/**
|
||||
* DTO for creating a job from the coordinator
|
||||
*/
|
||||
export class CreateCoordinatorJobDto {
|
||||
@IsUUID("4")
|
||||
workspaceId!: string;
|
||||
|
||||
@IsString()
|
||||
type!: string; // 'code-task', 'git-status', 'priority-calc'
|
||||
|
||||
@IsNumber()
|
||||
issueNumber!: number;
|
||||
|
||||
@IsString()
|
||||
repository!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@Max(100)
|
||||
priority?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
22
apps/api/src/coordinator-integration/dto/fail-job.dto.ts
Normal file
22
apps/api/src/coordinator-integration/dto/fail-job.dto.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { IsString, IsOptional, IsObject } from "class-validator";
|
||||
import type { QualityGateResult } from "../interfaces";
|
||||
|
||||
/**
|
||||
* DTO for failing a job from the coordinator
|
||||
*/
|
||||
export class FailJobDto {
|
||||
@IsString()
|
||||
error!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
gateResults?: QualityGateResult;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
failedStep?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
continuationPrompt?: string;
|
||||
}
|
||||
5
apps/api/src/coordinator-integration/dto/index.ts
Normal file
5
apps/api/src/coordinator-integration/dto/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from "./create-coordinator-job.dto";
|
||||
export * from "./update-job-status.dto";
|
||||
export * from "./update-job-progress.dto";
|
||||
export * from "./complete-job.dto";
|
||||
export * from "./fail-job.dto";
|
||||
@@ -0,0 +1,19 @@
|
||||
import { IsNumber, IsOptional, IsString, Min, Max } from "class-validator";
|
||||
|
||||
/**
|
||||
* DTO for updating job progress from the coordinator
|
||||
*/
|
||||
export class UpdateJobProgressDto {
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@Max(100)
|
||||
progressPercent!: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
currentStep?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
tokensUsed?: number;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { IsString, IsOptional, IsEnum } from "class-validator";
|
||||
|
||||
/**
|
||||
* Valid status values for coordinator status updates
|
||||
*/
|
||||
export enum CoordinatorJobStatus {
|
||||
RUNNING = "RUNNING",
|
||||
PENDING = "PENDING",
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for updating job status from the coordinator
|
||||
*/
|
||||
export class UpdateJobStatusDto {
|
||||
@IsEnum(CoordinatorJobStatus)
|
||||
status!: CoordinatorJobStatus;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
agentId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
agentType?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user