# 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 Remote `local-gitea`. - **Basis ist `feature/iso27001-framework-mapping`**, nicht `dev` — dort liegt die Vorarbeit (Commits `492d315`, `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 eine `FrameworkStrategy` ziehst, muss das Verhalten identisch bleiben. ## Vier Invarianten — hier geht es sonst schief 1. **`reconcilePackage` archiviert fremde Anforderungen.** `prisma/import-policies.ts:368-371` setzt `archivedAt` auf jede `PolicyRequirement`, deren `reqId` nicht im importierten Paket steht. Ein ISO-Import in einen TISAX-Mandanten legt damit **alle 321 VDA-ISA-Anforderungen still** — und umgekehrt. Lösung: `PolicyRequirement.framework` ergänzen (Backfill `TISAX`) und den Archivierungslauf auf `where: { 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. 2. **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. 3. **TISAX darf sich nicht verändern.** Messlatte ist `python3 seed/isms-vorlagenpaket-v2/_render_diff.py HEAD` → 0 Abweichungen. 4. **Den Fail-Safe in `src/lib/policy-render.ts` nicht entfernen.** `buildContext` belegt 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:** ```prisma 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. ```prisma 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 nur `ManagedRegister` einen `reviewCycle`; A.5.1 verlangt die Überprüfung „in geplanten Abständen". - `PolicyAcknowledgement { tenantId, policyDocumentId, version, userId, acknowledgedAt }` — Lesebestätigung, in `SPEC.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 ```bash 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 die `migration.sql` anhängen, dann `migrate deploy`. - **`scripts/check-module-guards.ts`** läuft als `prebuild`-Gate: jede neue Datei unter `src/server/actions/` dort eintragen (Modul-Key oder `EXEMPT`), 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.