Basis: Certvia dev@a48c5fb als Fundament für Craftvia
CI / build-and-check (push) Canceled after 0s
CI / audit (push) Canceled after 0s
CI / sbom (push) Canceled after 0s

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:
2026-09-14 11:05:39 +02:00
co-authored by Claude Opus 5
commit c8e6f30a27
720 changed files with 140143 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
// Direkt-Download-Pfad: exportTenant(persist:false) liefert das verschlüsselte
// Artefakt als Buffer OHNE Store-Roundtrip (Grundlage der /api/platform/backup/download-Route).
// Lauf: npx tsx scripts/test-backup-download.ts (nutzt lokale isms-DB)
import "dotenv/config";
import { prisma } from "../src/server/db";
import { exportTenant } from "../src/server/backup/export";
let failures = 0;
const ok = (cond: boolean, msg: string) => {
console.log(`${cond ? "✓" : "✗ FEHLER"} ${msg}`);
if (!cond) failures++;
};
async function main() {
const demo = await prisma.tenant.findFirst({ where: { slug: "demo" }, select: { id: true } });
if (!demo) throw new Error("Mandant 'demo' fehlt — bitte seeden.");
const res = await exportTenant(demo.id, { persist: false });
ok(res.artifact.length > 1000, `Artefakt hat Bytes (${res.artifact.length})`);
ok(res.artifact.subarray(0, 4).toString("utf8") === "CVB1", `verschlüsselter Kopf „CVB1" (hex ${res.artifact.subarray(0, 4).toString("hex")})`);
ok(res.artifactKey === null, "persist:false → NICHT im Store abgelegt (artifactKey === null)");
ok((res.manifest.totalRows ?? 0) > 0, `Manifest: Zeilen > 0 (${res.manifest.totalRows})`);
ok(res.snapshotId.length > 0, `snapshotId für den Dateinamen vorhanden (${res.snapshotId})`);
await prisma.$disconnect();
console.log(failures === 0 ? "\nAlle grün." : `\n${failures} FEHLER`);
process.exit(failures === 0 ? 0 : 1);
}
main().catch((e) => { console.error(e); process.exit(1); });