98 lines
2.5 KiB
TypeScript
98 lines
2.5 KiB
TypeScript
import type { AppDatabase } from "@main/database";
|
|
import type { ProjectionOutcome } from "./artifact-types";
|
|
|
|
export type ArtifactProjectionPhase = "completion_reconcile";
|
|
|
|
export interface ArtifactProjectionEventInput {
|
|
companyId: string;
|
|
runId: string;
|
|
agentId: string;
|
|
phase: ArtifactProjectionPhase;
|
|
workspaceId: string | null;
|
|
workspaceMode: "exclusive" | "shared" | "none";
|
|
outcomes: ProjectionOutcome[];
|
|
}
|
|
|
|
export interface ArtifactProjectionFailureInput {
|
|
companyId: string;
|
|
runId: string;
|
|
agentId: string;
|
|
phase: ArtifactProjectionPhase;
|
|
workspaceId: string | null;
|
|
workspaceMode: "exclusive" | "shared" | "none";
|
|
errorMessage: string;
|
|
}
|
|
|
|
interface ProjectionCounts {
|
|
inserted: number;
|
|
updated: number;
|
|
retired: number;
|
|
skipped: number;
|
|
}
|
|
|
|
function countOutcomes(outcomes: ProjectionOutcome[]): ProjectionCounts {
|
|
const counts: ProjectionCounts = {
|
|
inserted: 0,
|
|
updated: 0,
|
|
retired: 0,
|
|
skipped: 0,
|
|
};
|
|
for (const outcome of outcomes) {
|
|
counts[outcome.kind] += 1;
|
|
}
|
|
return counts;
|
|
}
|
|
|
|
function summarizeOutcomes(phase: ArtifactProjectionPhase, counts: ProjectionCounts): string {
|
|
return [
|
|
`Artifact projection ${phase} acknowledged`,
|
|
`${counts.inserted} inserted`,
|
|
`${counts.updated} updated`,
|
|
`${counts.retired} retired`,
|
|
`${counts.skipped} skipped`,
|
|
].join("; ");
|
|
}
|
|
|
|
export function appendArtifactProjectionEvent(
|
|
db: AppDatabase,
|
|
input: ArtifactProjectionEventInput,
|
|
): ProjectionCounts {
|
|
const counts = countOutcomes(input.outcomes);
|
|
db.core.runs.appendRunEvent({
|
|
companyId: input.companyId,
|
|
runId: input.runId,
|
|
agentId: input.agentId,
|
|
eventType: "artifact_projection",
|
|
level: "info",
|
|
message: summarizeOutcomes(input.phase, counts),
|
|
payload: {
|
|
phase: input.phase,
|
|
workspaceId: input.workspaceId,
|
|
workspaceMode: input.workspaceMode,
|
|
counts,
|
|
outcomes: input.outcomes,
|
|
},
|
|
});
|
|
return counts;
|
|
}
|
|
|
|
export function appendArtifactProjectionFailureEvent(
|
|
db: AppDatabase,
|
|
input: ArtifactProjectionFailureInput,
|
|
): void {
|
|
db.core.runs.appendRunEvent({
|
|
companyId: input.companyId,
|
|
runId: input.runId,
|
|
agentId: input.agentId,
|
|
eventType: "artifact_projection",
|
|
level: "error",
|
|
message: `Artifact projection ${input.phase} failed: ${input.errorMessage}`,
|
|
payload: {
|
|
phase: input.phase,
|
|
workspaceId: input.workspaceId,
|
|
workspaceMode: input.workspaceMode,
|
|
errorMessage: input.errorMessage,
|
|
},
|
|
});
|
|
}
|