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,67 @@
|
||||
// AP3 — Anwendbarkeitserklärung (SoA). Prüft Vorbefüllung, Bedingungs-Logik,
|
||||
// Idempotenz und Vollständigkeits-Markierung gegen die lokale DB (Wegwerf-Mandant).
|
||||
//
|
||||
// Lauf: npx tsx scripts/test-soa.ts
|
||||
|
||||
import "dotenv/config";
|
||||
import { prisma, dbForTenant } from "../src/server/db";
|
||||
import { ensureSoaEntries, loadIsoSoaControls } from "../src/server/soa-statement";
|
||||
import { isSoaEntryComplete } from "../src/lib/soa";
|
||||
|
||||
let failures = 0;
|
||||
const ok = (c: boolean, m: string) => { console.log(`${c ? "✓" : "✗ FEHLER"} ${m}`); if (!c) failures++; };
|
||||
const SLUG = "ap3-test-soa";
|
||||
|
||||
async function cleanup() {
|
||||
const t = await prisma.tenant.findUnique({ where: { slug: SLUG }, select: { id: true } });
|
||||
if (t) {
|
||||
await prisma.soaEntry.deleteMany({ where: { tenantId: t.id } });
|
||||
await prisma.policyVariable.deleteMany({ where: { tenantId: t.id } });
|
||||
await prisma.tenant.delete({ where: { id: t.id } });
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cleanup();
|
||||
|
||||
const controls = loadIsoSoaControls();
|
||||
ok(controls.length === 93, `loadIsoSoaControls: ${controls.length} Annex-A-Controls (erwartet 93)`);
|
||||
const devControl = controls.find((c) => c.condition === "FLAG_DEV_INHOUSE");
|
||||
const plainControl = controls.find((c) => c.condition === null);
|
||||
ok(!!devControl && !!plainControl, "je ein Control mit/ohne Bedingung vorhanden");
|
||||
|
||||
const tenant = await prisma.tenant.create({ data: { name: "AP3 SoA", slug: SLUG } });
|
||||
const t = tenant.id;
|
||||
// Flags: DEV-Inhouse AUS → DEV-Controls default nicht anwendbar; Personendaten AN.
|
||||
await prisma.policyVariable.createMany({
|
||||
data: [
|
||||
{ tenantId: t, key: "FLAG_DEV_INHOUSE", title: "Dev", kind: "boolean", value: "false" },
|
||||
{ tenantId: t, key: "FLAG_PERSONAL_DATA", title: "PD", kind: "boolean", value: "true" },
|
||||
],
|
||||
});
|
||||
const db = dbForTenant(t);
|
||||
|
||||
const n1 = await ensureSoaEntries(db, t);
|
||||
ok(n1 === 93, `ensureSoaEntries legt 93 Zeilen an (${n1})`);
|
||||
const n2 = await ensureSoaEntries(db, t);
|
||||
ok(n2 === 0, "zweiter Lauf ist idempotent (0 neue Zeilen)");
|
||||
ok((await prisma.soaEntry.count({ where: { tenantId: t } })) === 93, "93 SoA-Zeilen persistiert");
|
||||
|
||||
const devEntry = await prisma.soaEntry.findFirst({ where: { tenantId: t, control: devControl!.control } });
|
||||
ok(devEntry?.applicable === false, `Bedingung greift: ${devControl!.control} (FLAG_DEV_INHOUSE aus) → nicht anwendbar`);
|
||||
const plainEntry = await prisma.soaEntry.findFirst({ where: { tenantId: t, control: plainControl!.control } });
|
||||
ok(plainEntry?.applicable === true, `Control ohne Bedingung (${plainControl!.control}) → anwendbar`);
|
||||
|
||||
// Vollständigkeit: frisch ohne Begründung → unvollständig; nach Begründung → vollständig.
|
||||
ok(!isSoaEntryComplete({ applicable: true, justification: "" }), "Control ohne Begründung → unvollständig");
|
||||
ok(isSoaEntryComplete({ applicable: false, justification: "Ausschluss: keine Eigenentwicklung" }), "Ausschluss mit Begründung → vollständig");
|
||||
const incomplete = await prisma.soaEntry.count({ where: { tenantId: t, justification: "" } });
|
||||
ok(incomplete === 93, "alle 93 Zeilen initial ohne Begründung (unvollständig)");
|
||||
|
||||
await cleanup();
|
||||
console.log("\n✓ aufgeräumt (Wegwerf-Mandant entfernt)");
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => { console.log(failures === 0 ? "\nAP3-SoA 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); });
|
||||
Reference in New Issue
Block a user