Externalize audit pipeline services

This commit is contained in:
2026-06-07 23:06:31 +02:00
parent 470fb0f348
commit a45b92ea0a
42 changed files with 3141 additions and 247 deletions

View File

@@ -6,13 +6,53 @@ import {
RUN_TYPES,
normalizeListLimit,
} from "./domain";
import { mutation, query } from "./_generated/server";
import type { Id } from "./_generated/dataModel";
import { internalMutation, mutation, query } from "./_generated/server";
import type { MutationCtx, QueryCtx } from "./_generated/server";
const runType = v.union(...RUN_TYPES.map((type) => v.literal(type)));
const runStatus = v.union(...RUN_STATUSES.map((status) => v.literal(status)));
const eventLevel = v.union(
...RUN_EVENT_LEVELS.map((level) => v.literal(level)),
);
const appendEventArgs = {
runId: v.id("agentRuns"),
level: eventLevel,
message: v.string(),
details: v.optional(
v.array(
v.object({
label: v.string(),
value: v.string(),
source: v.optional(v.string()),
}),
),
),
};
type AppendEventArgs = {
runId: Id<"agentRuns">;
level: (typeof RUN_EVENT_LEVELS)[number];
message: string;
details?: { label: string; value: string; source?: string }[];
};
const requireOperator = async (ctx: MutationCtx | QueryCtx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error("Nicht autorisiert.");
}
};
async function appendRunEvent(
ctx: MutationCtx,
args: AppendEventArgs,
) {
return await ctx.db.insert("agentRunEvents", {
...args,
createdAt: Date.now(),
});
}
export const create = mutation({
args: {
@@ -24,6 +64,7 @@ export const create = mutation({
currentStep: v.optional(v.string()),
},
handler: async (ctx, args) => {
await requireOperator(ctx);
const now = Date.now();
return await ctx.db.insert("agentRuns", {
@@ -50,6 +91,7 @@ export const updateStatus = mutation({
errorSummary: v.optional(v.string()),
},
handler: async (ctx, args) => {
await requireOperator(ctx);
const now = Date.now();
const patch: {
status: typeof args.status;
@@ -92,6 +134,7 @@ export const list = query({
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
await requireOperator(ctx);
const limit = normalizeListLimit(args.limit);
if (args.type && args.status) {
@@ -132,25 +175,17 @@ export const list = query({
});
export const appendEvent = mutation({
args: {
runId: v.id("agentRuns"),
level: eventLevel,
message: v.string(),
details: v.optional(
v.array(
v.object({
label: v.string(),
value: v.string(),
source: v.optional(v.string()),
}),
),
),
},
args: appendEventArgs,
handler: async (ctx, args) => {
return await ctx.db.insert("agentRunEvents", {
...args,
createdAt: Date.now(),
});
await requireOperator(ctx);
return await appendRunEvent(ctx, args);
},
});
export const appendEventInternal = internalMutation({
args: appendEventArgs,
handler: async (ctx, args) => {
return await appendRunEvent(ctx, args);
},
});
@@ -160,6 +195,7 @@ export const listEvents = query({
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
await requireOperator(ctx);
const limit = normalizeListLimit(args.limit);
return await ctx.db