HTTP-Endpunkte und Anwendungsaufbau

Eingaben werden mit zod validiert, jede aendernde Aktion schreibt ins
Audit-Log. Beim ersten Start entsteht ein Administrator samt Startwerten fuer
die Produkterkennung; solange ein Erstpasswort gilt, bleiben schreibende Wege
bis auf den Passwortwechsel gesperrt.

Nicht-API-Pfade fallen auf die SPA zurueck, damit Deep-Links funktionieren.
This commit is contained in:
2026-09-18 11:37:31 +02:00
parent f3e31cdd17
commit a7228e63d1
10 changed files with 1209 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
import type { FastifyRequest } from 'fastify';
import { z } from 'zod';
import { badRequest, unauthorized } from '../errors.js';
import type { ActionContext } from '../services/audit.js';
// z.output statt z.input: nur so zaehlen .default()-Werte als gesetzt.
export function parseWith<S extends z.ZodTypeAny>(schema: S, input: unknown): z.output<S> {
const result = schema.safeParse(input);
if (!result.success) {
const message = result.error.issues
.map((issue) => {
const path = issue.path.join('.');
return path ? `${path}: ${issue.message}` : issue.message;
})
.join('; ');
throw badRequest('VALIDATION_FAILED', message);
}
return result.data;
}
export function contextOf(request: FastifyRequest): ActionContext {
if (!request.user) throw unauthorized();
return {
actorId: request.user.id,
actorName: request.user.username,
ip: request.ip,
};
}
export const idParam = z.object({ id: z.coerce.number().int().positive() });
export const optionalNote = z.string().trim().max(500).optional();