Richtlinien: Lesemodus als eigene Seite + Bearbeitungsmodus (§8)
Auf Wunsch: Dokumente öffnen nicht mehr als Popup, sondern als eigene Seite
mit Zurück-Navigation.
- Neue Routen /policies/[code] (Lesen) und /policies/[code]/edit (Bearbeiten);
Popup-Modals durch PolicyReadView/PolicyRegisterView ersetzt. Alle Deeplinks
({{LINK}}, Coverage, Bibliothek, Register-Callouts) zeigen auf /policies/CODE.
- Detailseite: „← Zurück zur Bibliothek", Titel/Status/Version, Control-Chips,
„Bearbeiten"-Button (nur Vorlagen-Dokumente, policy:write).
- Bearbeitungsmodus für Leitlinie/Richtlinien/Verfahren:
* Vorlagen-Markdown-Editor (Textarea) mit Live-Vorschau (Lesemodus),
Speichern via updatePolicyTemplate.
* Dokument-bezogene Variablen (§8 Variablen-Scoping): nur die im Dokument
vorkommenden Variablen — inkl. über BL-Referenzen gebundene — einzeln
editierbar; Änderung propagiert zentral in alle Dokumente (eine Pflegestelle).
- Register-Actions revalidieren jetzt /policies per layout (Detailseiten aktuell).
Verifiziert: R08 als Seite (kein Modal), Editor mit 23 dokument-bezogenen
Variablen; PW_MIN_LENGTH 12→14 propagiert in R08 und Handbuch; Template-Speichern
mit Redirect zur Ansicht; zurückgesetzt.
Hinweis: Der Vier-Augen-Freigabe-Workflow mit Versionierung/Diff (§8) folgt als
nächster Schritt — aktuell speichert der Editor direkt (mit Audit-Log).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
import { z } from "zod";
|
||||
import { requireSession } from "@/server/auth";
|
||||
import { dbForTenant } from "@/server/db";
|
||||
@@ -35,7 +36,7 @@ export async function addCryptoEntry(formData: FormData) {
|
||||
},
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "crypto_entry" });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
export async function updateCryptoEntry(id: string, formData: FormData) {
|
||||
@@ -53,14 +54,14 @@ export async function updateCryptoEntry(id: string, formData: FormData) {
|
||||
},
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "crypto_entry", entityId: id });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
export async function deleteCryptoEntry(id: string) {
|
||||
const { session, db } = await guard();
|
||||
await db.cryptoEntry.delete({ where: { id } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "delete", entity: "crypto_entry", entityId: id });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
/* ── Klassifizierungs-Handhabungsmatrix (R02 / VA-08) ── */
|
||||
@@ -74,7 +75,7 @@ export async function updateHandlingRule(classId: string, aspectId: string, form
|
||||
create: { tenantId: session.user.tenantId, classId, aspectId, text },
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "handling_rule" });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
export async function addHandlingAspect(formData: FormData) {
|
||||
@@ -89,7 +90,7 @@ export async function addHandlingAspect(formData: FormData) {
|
||||
},
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "handling_aspect" });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
export async function addClassificationClass(formData: FormData) {
|
||||
@@ -104,7 +105,7 @@ export async function addClassificationClass(formData: FormData) {
|
||||
},
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "classification_class" });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
/* ── Risiko-Bewertungsmatrix (R03 / VA-09) ── */
|
||||
@@ -120,5 +121,28 @@ export async function updateRiskClass(id: string, formData: FormData) {
|
||||
},
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "risk_matrix_class", entityId: id });
|
||||
revalidatePath("/policies");
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
/* ── Bearbeitungsmodus Richtlinien/Verfahren ── */
|
||||
|
||||
/** Vorlagen-Markdown eines Dokuments speichern. */
|
||||
export async function updatePolicyTemplate(code: string, formData: FormData) {
|
||||
const { session, db } = await guard();
|
||||
const doc = await db.policyDocument.findFirst({ where: { code } });
|
||||
if (!doc) throw new Error("Dokument nicht gefunden");
|
||||
const rawMarkdown = String(formData.get("rawMarkdown") ?? "");
|
||||
await db.policyDocument.update({ where: { id: doc.id }, data: { rawMarkdown } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "policy_document", entityId: doc.id });
|
||||
revalidatePath("/policies", "layout");
|
||||
redirect(`/policies/${encodeURIComponent(code)}`);
|
||||
}
|
||||
|
||||
/** Eine dokument-bezogene Variable ändern (eine Pflegestelle, §7/§8) — propagiert in alle Dokumente. */
|
||||
export async function updatePolicyVariable(key: string, formData: FormData) {
|
||||
const { session, db } = await guard();
|
||||
const value = String(formData.get("value") ?? "");
|
||||
await db.policyVariable.updateMany({ where: { key }, data: { value } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "policy_variable", after: { key, value } });
|
||||
revalidatePath("/policies", "layout");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user