Workstream 7: Wehr-Bereich — Fuhrpark & Benutzer (Phase 4)
Implementiert den auf die eigene brigadeId beschränkten Wehr-Bereich: Profil (inkl. Inline-Geocoding via geocodeAddress), Fuhrpark (Fahrzeug per Vorlage oder frei, typisierter Merkmal-Editor), Geräte (Kategorie, Werte, Zuordnung Fahrzeug/„im Gerätehaus") und Benutzerkonten (wehr_admin/wehr_read). - Schema importiert (nicht neu definiert); ASCII-Property wehrfuehrer. - Default-deny dreifach: Layout-Guard requireWehrAdmin() + jede Server Action beginnt mit requireWehrAdmin(); fremde Entities -> notFound() (404). - Validierung an der Grenze (Zod): buildMerkmalValuesSchema validiert Werte typgerecht gegen die serverseitig aufgelösten Definitionen; Rolle auf wehr_admin|wehr_read beschränkt (platform_admin abgelehnt). - upsertMerkmalValues delete-then-insert mit typisierter Drizzle-Tx (kein any); boolean false/num 0 gelten als gesetzt. - argon2id-Einmalpasswort beim Benutzeranlegen; Selbst-Deaktivierung verhindert. - Audit vollständig: brigade.profile_update, vehicle.create/update/delete/status, equipment.create/update/delete/status, user.create/deactivate. - Vorgabewerte aus drei typisierten Spalten (vorgabewert_num/_text/_bool). - i18n via zentraler de.ts; loading/empty/error-konforme Listen. Tests: 22 neue Unit-Tests (vehicle/equipment/brigade-user-Validierung, upsertMerkmalValues) grün; Playwright-Specs verwaltung-fuhrpark + -scoping geschrieben (deferred: kein Server/DB in der Sandbox). Verifikation offline: tsc --noEmit clean, eslint clean, vitest 147 passed, next build exit 0 (alle /verwaltung/*-Routen), drizzle-kit check ohne Drift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
35
src/lib/validation/brigade-user.ts
Normal file
35
src/lib/validation/brigade-user.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { z } from "zod";
|
||||
import { uuidSchema } from "./common";
|
||||
|
||||
/**
|
||||
* Zod-Schemas für die Benutzerverwaltung im Wehr-Bereich (Workstream 7).
|
||||
*
|
||||
* WICHTIG (Sicherheit): Die Rolle ist auf `wehr_admin | wehr_read` beschränkt.
|
||||
* Ein Wehr-Admin darf NIEMALS `platform_admin` vergeben — Zod lehnt das an der
|
||||
* Grenze ab (Querschnittsstandard 4, Verteidigung in der Tiefe zusätzlich zum
|
||||
* serverseitigen Scope-Guard).
|
||||
*/
|
||||
|
||||
export const brigadeUserRoleSchema = z.enum(["wehr_admin", "wehr_read"], {
|
||||
errorMap: () => ({ message: "Unzulässige Rolle." }),
|
||||
});
|
||||
|
||||
export const brigadeUserCreateSchema = z.object({
|
||||
email: z
|
||||
.string()
|
||||
.trim()
|
||||
.email({ message: "Ungültige E-Mail." })
|
||||
.transform((v) => v.toLowerCase()),
|
||||
name: z.string().trim().min(1, { message: "Name ist Pflicht." }),
|
||||
rolle: brigadeUserRoleSchema,
|
||||
});
|
||||
|
||||
export type BrigadeUserCreateInput = z.infer<typeof brigadeUserCreateSchema>;
|
||||
|
||||
export const brigadeUserDeactivateSchema = z.object({
|
||||
userId: uuidSchema,
|
||||
});
|
||||
|
||||
export type BrigadeUserDeactivateInput = z.infer<
|
||||
typeof brigadeUserDeactivateSchema
|
||||
>;
|
||||
Reference in New Issue
Block a user