api: Audit-Log verdrahtet (auditedProcedure an kritische Mutationen)
withAudit war als tRPC-Wrapper definiert, aber an keine Procedure gehaengt (audit_event blieb leer). Jetzt eine echte tRPC-v11-Middleware-Procedure (auditedProcedure), die nach erfolgreicher Mutation best-effort einen audit_event schreibt (Fehler beim Audit kippen die Mutation nicht). Verdrahtet an die folgenreichen Zustandsuebergaenge: - blocker.resolve - project.archive, project.setPhase, project.addPhaseGate Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
6e7f639013
commit
c98d27e70c
3 files changed
+32
-27
No files matched your search
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { eq, isNull, desc } from 'drizzle-orm';
|
||||
import { blocker, project, user } from '@cockpit/db';
|
||||
import { router, protectedProcedure } from '../trpc.js';
|
||||
import { router, protectedProcedure, auditedProcedure } from '../trpc.js';
|
||||
|
||||
export const blockerRouter = router({
|
||||
listOpen: protectedProcedure.query(async ({ ctx }) => {
|
||||
@@ -52,7 +52,7 @@ export const blockerRouter = router({
|
||||
return created;
|
||||
}),
|
||||
|
||||
resolve: protectedProcedure
|
||||
resolve: auditedProcedure('blocker.resolve')
|
||||
.input(
|
||||
z.object({
|
||||
blockerId: z.string().uuid(),
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
type Project,
|
||||
} from '@cockpit/db';
|
||||
import { ProjectSchemas } from '@cockpit/shared';
|
||||
import { router, protectedProcedure } from '../trpc.js';
|
||||
import { router, protectedProcedure, auditedProcedure } from '../trpc.js';
|
||||
|
||||
const PHASE_ORDER = ['definition', 'planung', 'umsetzung', 'abschluss'] as const;
|
||||
function nextPhase(p: (typeof PHASE_ORDER)[number]): (typeof PHASE_ORDER)[number] {
|
||||
@@ -116,7 +116,7 @@ export const projectRouter = router({
|
||||
return result;
|
||||
}),
|
||||
|
||||
archive: protectedProcedure
|
||||
archive: auditedProcedure('project.archive')
|
||||
.input(ProjectSchemas.archiveProjectInput)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const p = (
|
||||
@@ -145,7 +145,7 @@ export const projectRouter = router({
|
||||
}),
|
||||
|
||||
// Phase direkt setzen (Leitfaden Kap. 2).
|
||||
setPhase: protectedProcedure
|
||||
setPhase: auditedProcedure('project.setPhase')
|
||||
.input(ProjectSchemas.setPhaseInput)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const [updated] = await ctx.db
|
||||
@@ -158,7 +158,7 @@ export const projectRouter = router({
|
||||
}),
|
||||
|
||||
// Gate-Review am Phasenende (Leitfaden Kap. 5), optional Folgephase freigeben.
|
||||
addPhaseGate: protectedProcedure
|
||||
addPhaseGate: auditedProcedure('project.addPhaseGate')
|
||||
.input(ProjectSchemas.addPhaseGateInput)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const [gate] = await ctx.db
|
||||
|
||||
Reference in new issue
Block a user