Freigabe-Workflow + Aufgaben-Modul + Dashboard-Kachel

Konzept (abgestimmt): Beim Einreichen wählt der Einreicher einen konkreten
Freigeber; die Freigabe/Ablehnung erfolgt im neuen Aufgaben-Modul (Vier-Augen).

- Modell: generisches Task + TaskComment (Migration inkl. RLS; Task/TaskComment
  in TENANT_MODELS). Erster Typ policy_approval. Neues Modul „tasks" (lib/modules,
  Nav, i18n) — für Bestands-Tenants per Default aktiv.
- policies.ts: submitForApproval(code, formData) verlangt einen Freigeber (aktiver
  Nutzer mit policy:approve, ≠ Einreicher), setzt IN_FREIGABE und erzeugt eine
  Aufgabe; Resubmit schließt alte offene Aufgaben. Alte approvePolicy/rejectPolicy
  entfernt (wandern ins Aufgaben-Modul).
- actions/tasks.ts: approveTask/rejectTask (nur zugewiesener Freigeber, ≠ Einreicher;
  Richtlinie → FREIGEGEBEN bzw. zurück auf ENTWURF) und commentTask (nur Beteiligte);
  Kommentare/Statuswechsel historisiert, Audit.
- /tasks: Aufgaben des Nutzers (offen/erledigt) mit Freigeben/Ablehnen (Grund
  erforderlich)/Kommentieren + Verlauf. Richtlinien-Editor: Freigeber-Dropdown beim
  Einreichen, „Zur Freigabe bei …" + Link zur Aufgabe (keine Inline-Freigabe mehr).
- Dashboard: Kachel „N offene Aufgabe(n)" verlinkt auf /tasks.
- Seed: zweiter ISB „Bea Approver" als Freigeber (ermöglicht den Vier-Augen-Flow).

Browser-verifiziert: R08 eingereicht (Freigeber Bea) → Aufgabe; Dashboard-Kachel
bei Bea; Freigeben in /tasks → R08 FREIGEGEBEN, Task DONE, Kommentar-Historie
(submit+approve). tsc + lint + build + Guard-Check grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 11:41:22 +02:00
co-authored by Claude Opus 4.8
parent 73c98137ea
commit 1d8f56343d
15 changed files with 397 additions and 67 deletions
+41
View File
@@ -746,6 +746,47 @@ model AuditLog {
@@map("audit_logs")
}
// Generisches Aufgaben-/Freigabe-Modell (erweiterbar). Erster Typ: policy_approval
// (Richtlinien-Freigabe an eine konkrete Person). Kommentare/Statuswechsel historisiert.
model Task {
id String @id @default(cuid())
tenantId String @map("tenant_id")
type String // policy_approval | …
title String
status String @default("OPEN") // OPEN | DONE | REJECTED | CANCELLED
entityType String? @map("entity_type") // z. B. policy_document
entityId String? @map("entity_id")
entityRef String? @map("entity_ref") // Deep-Link-Referenz, z. B. Policy-Code
assigneeId String? @map("assignee_id") // wer bearbeiten/freigeben soll
createdById String? @map("created_by_id")
dueDate DateTime? @map("due_date")
resolvedById String? @map("resolved_by_id")
resolvedAt DateTime? @map("resolved_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
comments TaskComment[]
@@index([tenantId, status])
@@index([tenantId, assigneeId, status])
@@map("tasks")
}
model TaskComment {
id String @id @default(cuid())
tenantId String @map("tenant_id")
taskId String @map("task_id")
authorId String? @map("author_id")
kind String @default("comment") // comment | approve | reject | submit
body String
createdAt DateTime @default(now()) @map("created_at")
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
@@index([tenantId, taskId])
@@map("task_comments")
}
// ── Richtlinien & Verfahren (VDA-ISA 2027 Vorlagenpaket) ──────────────────────
// Dokumente werden aus ihrer echten Markdown-Vorlage gerendert; Variablen,
// Feature-Flags und Baseline-Parameter sind die eine Pflegestelle (§7).