Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
// AP1 — Framework-Dimension: Kern-Invarianten (docs/UEBERGABE-framework-iso27001.md §1).
|
||||
//
|
||||
// Prüft gegen die lokale DB (Demo-Mandant):
|
||||
// 1. Backfill: jeder Mandant hat ≥1 TenantFramework; Bestands-Anforderungen sind TISAX;
|
||||
// getTenantFrameworks(demo) beginnt mit TISAX; Fallback ["TISAX"] ohne Zeile.
|
||||
// 2. Beide Mappings parsen: mapping.json (VDA ISA) und mapping-iso.json (ISO) — gemeinsamer
|
||||
// Dokumentensatz, unterschiedliche Anforderungen.
|
||||
// 3. Doppel-Framework-Reconcile: ISO-Import in einen TISAX-Mandanten legt die ISO-
|
||||
// Anforderungen an und archiviert KEINE TISAX-Anforderung (Falle 1.1); Dokumente
|
||||
// werden nicht dupliziert (reconcileShared).
|
||||
// 4. Rück-Reconcile TISAX archiviert die ISO-Anforderungen NICHT.
|
||||
// Räumt die ISO-Testdaten am Ende wieder ab.
|
||||
//
|
||||
// Lauf: npx tsx scripts/test-framework-core.ts
|
||||
|
||||
import "dotenv/config";
|
||||
import { join } from "node:path";
|
||||
import { prisma } from "../src/server/db";
|
||||
import { parsePackageFiles, reconcilePackage } from "../prisma/import-policies";
|
||||
import { getTenantFrameworks, getTenantPrimaryFramework } from "../prisma/template-store";
|
||||
|
||||
const SEED_DIR = join(process.cwd(), "seed", "isms-vorlagenpaket-v2");
|
||||
let failures = 0;
|
||||
const ok = (c: boolean, m: string) => { console.log(`${c ? "✓" : "✗ FEHLER"} ${m}`); if (!c) failures++; };
|
||||
|
||||
const activeReqs = (tenantId: string, framework: "TISAX" | "ISO_27001") =>
|
||||
prisma.policyRequirement.count({ where: { tenantId, framework, archivedAt: null } });
|
||||
const archivedReqs = (tenantId: string, framework: "TISAX" | "ISO_27001") =>
|
||||
prisma.policyRequirement.count({ where: { tenantId, framework, archivedAt: { not: null } } });
|
||||
|
||||
async function main() {
|
||||
const tenant = await prisma.tenant.findFirst({ where: { slug: "demo" } });
|
||||
if (!tenant) throw new Error("Demo-Mandant fehlt (prisma/seed.ts ausführen).");
|
||||
const t = tenant.id;
|
||||
|
||||
// ── 1. Backfill / Framework-Zuordnung ───────────────────────────────────────
|
||||
const allTenants = await prisma.tenant.count();
|
||||
const tenantsWithFw = await prisma.tenantFramework.groupBy({ by: ["tenantId"] });
|
||||
ok(tenantsWithFw.length === allTenants, `jeder Mandant hat ≥1 TenantFramework (${tenantsWithFw.length}/${allTenants})`);
|
||||
|
||||
const demoFw = await getTenantFrameworks(prisma, t);
|
||||
ok(demoFw[0] === "TISAX", "getTenantFrameworks(demo) beginnt mit TISAX");
|
||||
ok((await getTenantPrimaryFramework(prisma, t)) === "TISAX", "Primär-Framework = TISAX");
|
||||
ok((await getTenantFrameworks(prisma, "does-not-exist"))[0] === "TISAX", "Fallback ohne Zeile → [\"TISAX\"]");
|
||||
|
||||
const isoBaseline = await prisma.policyRequirement.count({ where: { tenantId: t, framework: "ISO_27001" } });
|
||||
ok(isoBaseline === 0, "Demo-Mandant hat vor dem Test keine ISO-Anforderungen");
|
||||
|
||||
// ── 2. Beide Mappings parsen ────────────────────────────────────────────────
|
||||
const tisaxPkg = parsePackageFiles(SEED_DIR, "mapping.json");
|
||||
const isoPkg = parsePackageFiles(SEED_DIR, "mapping-iso.json");
|
||||
ok(tisaxPkg.requirements.length > 300, `mapping.json: ${tisaxPkg.requirements.length} Anforderungen (VDA ISA)`);
|
||||
ok(isoPkg.requirements.length === 120, `mapping-iso.json: ${isoPkg.requirements.length} Anforderungen (erwartet 120)`);
|
||||
ok(tisaxPkg.documents.length === isoPkg.documents.length, "gemeinsamer Dokumentensatz (gleiche Dokumentanzahl)");
|
||||
|
||||
// ── 3. Doppel-Framework: ISO in TISAX-Mandant ───────────────────────────────
|
||||
const tisaxActiveBefore = await activeReqs(t, "TISAX");
|
||||
const tisaxArchivedBefore = await archivedReqs(t, "TISAX");
|
||||
const docsBefore = await prisma.policyDocument.count({ where: { tenantId: t } });
|
||||
|
||||
const isoRun = await reconcilePackage(prisma, t, isoPkg, { framework: "ISO_27001", reconcileShared: false });
|
||||
ok(isoRun.report.requirements.added === isoPkg.requirements.length,
|
||||
`ISO-Import legt ${isoRun.report.requirements.added} Anforderungen an (= ${isoPkg.requirements.length})`);
|
||||
ok(isoRun.report.documents.added === 0 && isoRun.report.documents.updated === 0,
|
||||
"ISO-Import fasst die geteilten Dokumente NICHT an (reconcileShared=false)");
|
||||
|
||||
const isoActive = await activeReqs(t, "ISO_27001");
|
||||
ok(isoActive === isoPkg.requirements.length, `ISO-Anforderungen aktiv: ${isoActive}`);
|
||||
|
||||
const tisaxActiveAfter = await activeReqs(t, "TISAX");
|
||||
const tisaxArchivedAfter = await archivedReqs(t, "TISAX");
|
||||
ok(tisaxActiveAfter === tisaxActiveBefore, `KEINE TISAX-Anforderung archiviert (aktiv ${tisaxActiveBefore} → ${tisaxActiveAfter})`);
|
||||
ok(tisaxArchivedAfter === tisaxArchivedBefore, "ISO-Import erzeugt keine neu archivierten TISAX-Anforderungen (Falle 1.1)");
|
||||
|
||||
const docsAfter = await prisma.policyDocument.count({ where: { tenantId: t } });
|
||||
ok(docsAfter === docsBefore, `Dokumente nicht dupliziert (${docsBefore} → ${docsAfter})`);
|
||||
|
||||
const coexist = tisaxActiveAfter + isoActive;
|
||||
ok(tisaxActiveAfter > 0 && isoActive === 120, `Doppel-Framework: ${tisaxActiveAfter} TISAX + ${isoActive} ISO koexistieren (${coexist})`);
|
||||
|
||||
// ── 4. Rück-Reconcile TISAX archiviert ISO NICHT ────────────────────────────
|
||||
await reconcilePackage(prisma, t, tisaxPkg, { framework: "TISAX", reconcileShared: true });
|
||||
const isoStillActive = await activeReqs(t, "ISO_27001");
|
||||
ok(isoStillActive === isoPkg.requirements.length, "TISAX-Re-Import archiviert die ISO-Anforderungen NICHT");
|
||||
|
||||
// ── Aufräumen: ISO-Testdaten entfernen (Demo-Mandant zurücksetzen) ──────────
|
||||
const removed = await prisma.policyRequirement.deleteMany({ where: { tenantId: t, framework: "ISO_27001" } });
|
||||
console.log(`\n✓ aufgeräumt (${removed.count} ISO-Test-Anforderungen entfernt)`);
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => { console.log(failures === 0 ? "\nAP1-Framework-Kern grün." : `\n${failures} Prüfung(en) fehlgeschlagen.`); process.exit(failures === 0 ? 0 : 1); })
|
||||
.catch((e) => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user