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>
12 KiB
Kickoff-Prompt — Framework-Dimension: ISO 27001 neben TISAX
Du übernimmst den Anwendungsumbau für die Mehr-Framework-Fähigkeit. Die Inhaltsseite ist fertig: seed/isms-vorlagenpaket-v2 trägt seit Branch feature/iso27001-framework-mapping zwei Framework-Mappings auf einem Dokumentensatz — mapping.json (VDA ISA, 321 Anforderungen) und mapping-iso.json (ISO/IEC 27001:2022, 120 Anforderungen). Die Anwendung kennt das zweite Mapping nicht: parsePackageFiles liest mapping.json fest verdrahtet.
Pflichtlektüre vor der ersten Zeile Code: docs/UEBERGABE-framework-iso27001.md — insbesondere §1 „Die vier Fallen". Hintergrund und Begründung der Entscheidung: docs/FRAMEWORK-MAPPING-ISO27001.md. Gesamtarchitektur: docs/KONZEPT-framework-iso27001.md (D4 und Lane 2 sind dort per Nachtrag korrigiert).
Repo & Branch
- origin:
git.certvia.de/msolarczek/certvia; zweiter Remotelocal-gitea. - Basis ist
feature/iso27001-framework-mapping, nichtdev— dort liegt die Vorarbeit (Commits492d315,bbde804,7769908,b28d0f0). - AP1 auf
feature/framework-core, PR gegen den Basis-Branch. AP2–AP5 danach je eigener Branch, parallelisierbar.
Nicht anfassen
seed/isms-vorlagenpaket-v2/**— generiert. Inhaltliche Änderungen laufen ausschließlich über_iso_crosswalk.json/_iso_sections.json+python3 _generate_iso.py, nie direkt in den Markdown-Dateien (der Generator überschreibt sentinel-begrenzte Blöcke).- Die TISAX-Logik verhaltensgleich lassen:
src/lib/maturity.ts,src/lib/scope-filter.ts,src/server/assessment-level.ts,src/lib/control-titles.ts,src/lib/export/vda-isa*.ts. Wenn du sie hinter eineFrameworkStrategyziehst, muss das Verhalten identisch bleiben.
Vier Invarianten — hier geht es sonst schief
reconcilePackagearchiviert fremde Anforderungen.prisma/import-policies.ts:368-371setztarchivedAtauf jedePolicyRequirement, derenreqIdnicht im importierten Paket steht. Ein ISO-Import in einen TISAX-Mandanten legt damit alle 321 VDA-ISA-Anforderungen still — und umgekehrt. Lösung:PolicyRequirement.frameworkergänzen (BackfillTISAX) und den Archivierungslauf aufwhere: { tenantId, framework }einschränken. Für Dokumente, Variablen, Baseline und Nachweisregister gilt das nicht — die sind geteilt und identisch, sie dürfen genau einmal je Mandant abgeglichen werden.- Zwei Unique-Constraints brechen.
PolicyTemplateVersion.version @unique(prisma/schema.prisma:1639) →@@unique([framework, version]), sonst kollidieren ISO 2.1 und TISAX 2.1.PolicyPackageState.tenantId @unique(:1614) →@@unique([tenantId, framework]), sonst merkt sich ein Mandant nur eine Paketversion. - TISAX darf sich nicht verändern. Messlatte ist
python3 seed/isms-vorlagenpaket-v2/_render_diff.py HEAD→ 0 Abweichungen. - Den Fail-Safe in
src/lib/policy-render.tsnicht entfernen.buildContextbelegt fehlende Framework-Flags vor (FLAG_FW_TISAX = true,FLAG_FW_ISO27001 = false), damit Bestandsmandanten vor dem Paket-Re-Import keine leeren Anforderungsblöcke sehen.
AP1 — Framework-Dimension (Fundament, blockiert alles)
Schema, additiv:
enum Framework { ISO_27001 TISAX }
model TenantFramework {
id String @id @default(cuid())
tenantId String @map("tenant_id")
framework Framework
isPrimary Boolean @default(false) @map("is_primary")
config Json? // z. B. { tisaxLevel: "AL3" } bzw. { certScope }
createdAt DateTime @default(now()) @map("created_at")
@@unique([tenantId, framework])
@@index([tenantId])
@@map("tenant_frameworks")
}
Dazu PolicyRequirement.framework, PolicyTemplateVersion.framework, PolicyPackageState.framework. Backfill aller Bestandsdaten auf TISAX. TenantFramework gehört in TENANT_MODELS (src/server/db.ts:81) und braucht eine RLS-Policy in der Migration.
Code:
| Datei | Änderung |
|---|---|
prisma/import-policies.ts |
parsePackageFiles(seedDir, mappingFile = "mapping.json"); Requirements framework-scoped reconcilen |
prisma/template-store.ts:147 |
resolvePackageForTenant(prisma, tenantId, seedDir, framework); loadPublishedPackage(prisma, locale, framework); getAvailableVersion ebenso |
scripts/sync-policy-templates.ts:23 |
über Frameworks × Sprachen iterieren |
Die vier Aufrufer bekommen den Parameter durchgereicht: src/server/provision.ts:139, src/server/actions/policy-package.ts:28, src/server/actions/admin.ts, src/app/(app)/policies/updates/page.tsx:44. Das Seed-Verzeichnis bleibt für beide Frameworks dasselbe — die fünf SEED_DIR-Konstanten ändern sich nicht, nur der Mapping-Dateiname.
DoD: Bestandsmandanten laufen unverändert als TISAX; ein Mandant lässt sich mit ["ISO_27001"], ["TISAX"] oder beiden provisionieren; bei Doppel-Framework koexistieren 321 + 120 Anforderungen und keine ist fälschlich archiviert.
AP2 — Provisionierung und Flags (klein, direkt nach AP1)
ProvisionOpts (src/server/provision.ts:37) um frameworks: Framework[]. provisionTenant schreibt die TenantFramework-Zeilen, importiert je Framework das passende Mapping und setzt die Sichtbarkeits-Flags als PolicyVariable: nur TISAX → true/false, nur ISO → false/true, beides → true/true.
Reihenfolge beachten: reconcilePackage erhält nutzergepflegte Variablenwerte und überschreibt sie nicht — die Flags also nach dem Import setzen, sonst bleibt der Schema-Default stehen und ein ISO-Mandant sieht die VDA-ISA-Sicht. tisaxLevel bleibt auf TenantSettings, ist aber TISAX-scoped; bei einem reinen ISO-Mandanten keine AL-Flags setzen.
DoD: Frisch provisionierter ISO-Mandant öffnet /policies und sieht je Abschnitt *Anforderungsbezug:* ISO/IEC 27001 … plus die 19 ISO-only-Abschnitte; keine VDA-ISA-Anforderungen.
AP3 — SoA-Modul (das fehlende ISO-Kernartefakt)
Der Modul-Key soa (src/lib/modules.ts:19) zeigt auf /soa, die Route existiert nicht; die heutige Logik liegt als Wizard-Schritt in src/server/actions/soa.ts und ist ein VDA-ISA-Reifegrad-Assessment (0–3), nicht die ISO-Anwendbarkeitserklärung.
model SoaEntry {
id String @id @default(cuid())
tenantId String @map("tenant_id")
framework Framework
control String // "A.5.15"
applicable Boolean @default(true)
justification String // Begründung Einbeziehung ODER Ausschluss
source String? // Risiko-ID / gesetzliche / vertragliche Anforderung
implementationStatus String @default("geplant") // umgesetzt | teilweise | geplant
ownerId String? @map("owner_id")
policyCode String? @map("policy_code")
evidenceId String? @map("evidence_id")
@@unique([tenantId, framework, control])
@@index([tenantId])
@@map("soa_entries")
}
applicable, justification, implementationStatus und die Ausschlussbegründung sind normative Pflichtangaben (ISO/IEC 27001:2022, 6.1.3 d) — ohne sie ist die SoA im Zertifizierungsaudit angreifbar. Vorbefüllung aus mapping-iso.json (93 Controls); das Feld condition steuert die Default-Anwendbarkeit. Fachliche Vorlage für Aufbau und Spalten: seed/isms-vorlagenpaket-v2/Statement-of-Applicability-ISO.md.
DoD: SoA vollständig pflegbar und als PDF/XLSX exportierbar; ein Control ohne Begründung wird als unvollständig markiert.
AP4 — Kennzahlen, Managementbewertung, Korrekturmaßnahmen
| Klausel | Modell | Inhalt |
|---|---|---|
| 9.1 | Kpi / KpiValue |
Kennzahl, Datenquelle, Zielwert, Turnus, Verantwortlicher, Messwerte je Periode |
| 9.3 | ManagementReview |
Datum, Eingaben nach 9.3.2, Ergebnisse nach 9.3.3, Beschlüsse mit Verantwortlichem und Termin |
| 10.2 | Nonconformity + CorrectiveAction |
Herkunft, Sofortkorrektur, Ursachenanalyse, Maßnahme, Wirksamkeitsbewertung |
Aufsetzen auf Vorhandenes: Task.recurrence (RRULE), Task.remindAt, Task.effectiveUntil (Wirksamkeitsintervall, gekoppelt an Evidence.validUntil), TaskParticipant (RACI), AuditLog. Datenquellen für Kennzahlen liegen bereits im Tool: Aufgabenfristen und Überfälligkeit, Incident-SLA und Meldefristen (src/lib/incident-deadlines.ts), Reifegrade je Control, Maßnahmenstatus. Die Feldinhalte stehen fachlich in R03 der Bibliothek (ISO-MS-MESSUNG, ISO-MS-MGMTREVIEW, ISO-MS-CAPA).
DoD: Kennzahlenblatt mit Zielwerten über zwei Perioden auswertbar; Management-Review entlang der 9.3.2-Agenda protokollierbar; ein Maßnahmenfall inklusive dokumentierter Wirksamkeitsprüfung abschließbar.
AP5 — Dokumentenlenkung (klein, hohe Auditwirkung)
PolicyDocument.reviewCycle+nextReviewAt— heute führt nurManagedRegistereinenreviewCycle; A.5.1 verlangt die Überprüfung „in geplanten Abständen".PolicyAcknowledgement { tenantId, policyDocumentId, version, userId, acknowledgedAt }— Lesebestätigung, inSPEC.md§4.6 vorgesehen und bis heute nicht gebaut. Zugleich der einfachste Nachweis für Klausel 7.3 und Control A.6.3.- Änderungshistorie je Dokumentversion — aus
AuditLog(Vorher/Nachher) ableitbar oder eigene Tabelle.
DoD: Übersicht „Prüfung fällig"; Auswertung der Lesebestätigungen je Richtlinienversion; Dokumenthistorie über mindestens zwei Versionen sichtbar.
Validierungs-Gate vor jedem PR
npx tsc --noEmit && npm run lint && npm run build
cd seed/isms-vorlagenpaket-v2
python3 _verify.py # TISAX-Sicht → OK
python3 _verify_iso.py # ISO-Sicht → OK (0 Befunde)
python3 _render_diff.py HEAD # TISAX-Regression → 0 Abweichungen
Zusätzlich beachten:
- Migrationsflow Prisma 7 (
docs/HANDOVER-DEV.md:100):migrate diff --from-config-datasource … --to-schema … --script, danach den RLS-DO-Block manuell an diemigration.sqlanhängen, dannmigrate deploy. scripts/check-module-guards.tsläuft alsprebuild-Gate: jede neue Datei untersrc/server/actions/dort eintragen (Modul-Key oderEXEMPT), sonst schlägt der Build fehl.- Bei paralleler Lane-Entwicklung teilen sich die Worktrees dieselbe lokale Postgres-DB: beim Erzeugen einer Migration nur die eigenen DDL-Blöcke übernehmen, Fremd-Drops von Hand entfernen.
Definition of Done (gesamt)
| Prüfung | Erwartung |
|---|---|
| Bestandsmandant (TISAX) nach Deploy | Readiness und Exporte identisch zum Snapshot vor dem Umbau |
| Import ISO in Mandant mit TISAX | 120 neue Anforderungen, 0 archivierte ISA-Anforderungen |
| Import ISO, Umsetzungstexte | 120 von 120 gefüllt |
| Dokumente bei Doppel-Framework | 39 Dokumente, nicht doppelt |
| Parallelbetrieb im Dokument | beide Anforderungssichten unter einem gemeinsamen Umsetzungstext |
| Gate | tsc, lint, build, beide _verify*, _render_diff grün |
parsePackageFiles ist reine Dateiarbeit und ohne Datenbank testbar; für den Mandanten-Import gibt es reconcilePackage(..., { dryRun: true }) — Änderungsreport ohne Schreibzugriff, geeignet als Freigabebedingung.
Reihenfolge und Aufwand
AP1 Framework-Dimension 4–6 PT ← blockiert alles
├─ AP2 Provisionierung 1–2 PT
├─ AP3 SoA-Modul 5–8 PT
├─ AP4 Managementkl. 5–8 PT
└─ AP5 Dok.-Lenkung 2–3 PT
AP3–AP5 sind nach AP1 parallelisierbar. Feature-Flag: ISO bleibt laut Entscheidung D7 hinter einem Plattform-Schalter, bis AP3 abgenommen ist.
Nicht dein Scope
Diese Punkte gehören dem ISB bzw. der Redaktion: Nachweisregister um Zeilen für Kennzahlenblatt, Management-Review-Protokoll und Maßnahmenregister ergänzen; VA-15 trennen und ein Verfahren für Korrekturmaßnahmen ergänzen (Nummer ab VA-21, VA-20 ist belegt); REVIEW_CYCLE an den 33 Bestandsstellen auf die getrennten Zyklus-Variablen umstellen; ISB-Freigabe der 19 neuen Abschnittstexte.