// Vorlagen-Versionierung je Framework (Falle 1.2, docs/UEBERGABE-framework-iso27001.md §1). // // Sichert die Daten-Invariante, auf der der framework-fähige Vorlagen-Editor // (policy-templates.ts) aufsetzt — ohne die session-geschützten Actions aufzurufen: // 1. Dieselbe Versionsnummer darf je Framework existieren (@@unique([framework, version])): // (TISAX, "99.1") UND (ISO_27001, "99.1") koexistieren. // 2. Das Publish-Archivieren ist framework-scoped: ein `updateMany` mit // `framework=ISO_27001` archiviert NUR die ISO-Version, die TISAX-Version bleibt // PUBLISHED (sonst archivierte ein ISO-Publish die TISAX-Vorlage und umgekehrt). // Nutzt eindeutige Wegwerf-Versionen ("99.1") und räumt sie wieder ab. // // Lauf: npx tsx scripts/test-framework-templates.ts import "dotenv/config"; import { prisma } from "../src/server/db"; let failures = 0; const ok = (c: boolean, m: string) => { console.log(`${c ? "✓" : "✗ FEHLER"} ${m}`); if (!c) failures++; }; const V = "99.1"; // Wegwerf-Version, kollidiert nicht mit echten Paketständen async function cleanup() { await prisma.policyTemplateVersion.deleteMany({ where: { version: V } }); } async function main() { await cleanup(); // ── 1. Gleiche Version je Framework koexistiert (Unique-Constraint) ────────── const tisax = await prisma.policyTemplateVersion.create({ data: { framework: "TISAX", version: V, status: "PUBLISHED", publishedAt: new Date() } }); let isoCreated = false; try { await prisma.policyTemplateVersion.create({ data: { framework: "ISO_27001", version: V, status: "PUBLISHED", publishedAt: new Date() } }); isoCreated = true; } catch { isoCreated = false; } ok(isoCreated, "gleiche Versionsnummer je Framework erlaubt (@@unique([framework, version]))"); const both = await prisma.policyTemplateVersion.findMany({ where: { version: V }, select: { framework: true } }); ok(both.length === 2, "beide Versionen (TISAX + ISO) existieren nebeneinander"); // ── 2. Framework-scopes Archivieren (wie publishDraft) ────────────────────── const ids = (await prisma.policyTemplateVersion.findMany({ where: { version: V }, select: { id: true } })).map((r) => r.id); // Repliziert die Publish-Bedingung `where { status: PUBLISHED, framework }` — zusätzlich // auf die Testzeilen eingegrenzt, um echte Paketstände nicht anzufassen. await prisma.policyTemplateVersion.updateMany({ where: { status: "PUBLISHED", framework: "ISO_27001", id: { in: ids } }, data: { status: "ARCHIVED" }, }); const tisaxAfter = await prisma.policyTemplateVersion.findFirst({ where: { framework: "TISAX", version: V }, select: { status: true } }); const isoAfter = await prisma.policyTemplateVersion.findFirst({ where: { framework: "ISO_27001", version: V }, select: { status: true } }); ok(tisaxAfter?.status === "PUBLISHED", "TISAX-Version bleibt PUBLISHED, wenn ISO archiviert wird"); ok(isoAfter?.status === "ARCHIVED", "ISO-Version wird archiviert (framework-scoped)"); void tisax; await cleanup(); console.log("\n✓ aufgeräumt (Wegwerf-Versionen entfernt)"); } main() .then(() => { console.log(failures === 0 ? "\nVorlagen-Versionierung je Framework grün." : `\n${failures} Prüfung(en) fehlgeschlagen.`); process.exit(failures === 0 ? 0 : 1); }) .catch(async (e) => { console.error(e); await cleanup().catch(() => {}); process.exit(1); });