Iteration 2: Assets & BIA als gemeinsames Modul

- App-Shell mit Seitennavigation (alle 12 Module, kommende ausgegraut),
  shadcn/ui-Setup (Base-UI-Variante) mit hellem Theme
- Asset-Inventar: filterbare Liste (Suche/Typ/Status), Anlegen/Bearbeiten/
  Löschen, Detailansicht mit Schutzbedarf (C/I/A 1–4), Abhängigkeiten
  (beide Richtungen, hinzufügen/entfernen), zugeordneten Prozessen mit
  Primär-/Sekundär-Rolle und Platzhalter für zugeordnete Risiken
- Prozesse & BIA: Liste mit Kritikalität/RTO/MTD, Prozess-Detail mit
  Asset-Zuordnung nach Rolle (primär/sekundär), BIA-Formular
  (RTO/RPO/MTD, Schadenshöhe je Schutzziel, Kritikalität nach Max-Prinzip)
- Server-Actions mit Zod-Validierung, requirePermission und Audit-Log
  für jede schreibende Aktion; Tenant-Guard um upsert-Injektion erweitert
- Prisma: Asset, AssetRelation, Process, ProcessAsset, BiaEntry
  inkl. RLS-Policies; Seed mit Beispiel-Assets, Prozessen und BIA
- Im Browser verifiziert: CRUD, Relationen, BIA-Speichern, Audit-Einträge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Martin
2026-07-02 12:35:19 +02:00
co-authored by Claude Fable 5
parent 880afed391
commit 392bb246cf
41 changed files with 6085 additions and 149 deletions
+15 -1
View File
@@ -24,7 +24,16 @@ export const prisma =
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
/** Models that carry a tenantId column and must never be queried without one. */
const TENANT_MODELS = new Set<string>(["User", "Role", "AuditLog"]);
const TENANT_MODELS = new Set<string>([
"User",
"Role",
"AuditLog",
"Asset",
"AssetRelation",
"Process",
"ProcessAsset",
"BiaEntry",
]);
/**
* Returns a Prisma client that transparently enforces the tenant scope:
@@ -44,8 +53,10 @@ export function dbForTenant(tenantId: string) {
if (
operation === "findMany" ||
operation === "findFirst" ||
operation === "findFirstOrThrow" ||
operation === "count" ||
operation === "aggregate" ||
operation === "groupBy" ||
operation === "updateMany" ||
operation === "deleteMany"
) {
@@ -87,6 +98,9 @@ export function dbForTenant(tenantId: string) {
`Tenant isolation violation: ${model} belongs to another tenant`
);
}
if (operation === "upsert") {
a.create = { ...(a.create as object), tenantId };
}
}
return query(args);