- HANDOVER-DEV §10: neue Härtungs-/Verwaltungspakete dokumentiert (Modul-Guard, Plattform-Admin-Store + optionale MFA, nicht-destruktiver Re-Import, Benutzer-/ Rollenverwaltung, Force-Change, Passwort-Policy, Nutzer-MFA) inkl. Dateiverweise; §11 aktualisierte Einstiegspunkte (Paket 4 SMTP, tenant-weite MFA-Pflicht). - HANDOVER-PM: Statusblock „Neu auf dev" mit umgesetzten Paketen; Paket 4 als zurückgestellt markiert. Stand/Branch-Zeilen aktualisiert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15 KiB
Entwickler-Übergabe — ISMS-Tool
Stand: 2026-07-22 · Branch
dev(Produktionshärtung + Benutzerverwaltung) · BasismainZweck: Kontext, Setup und Konventionen, damit ein neuer Entwickler direkt weiterarbeiten kann. Fachlicher Status (fertig/offen) siehedocs/HANDOVER-PM.md. Neue Härtungs-/Verwaltungspakete: §10.
1. Repository & Zugriff
- Lokaler Pfad:
~/Projects/ISMS-Tool - Git-Remote (Gitea, nur HTTP):
http://gitea-vkbhbn2qdkz5ppk9q4qgb0tn.192.168.1.207.sslip.io/msolarczek/ISMS-Tool.git(interner Server; kein SSH). Zugangstoken liegt im macOS-Schlüsselbund (nicht im Repo, nicht in Klartext weitergeben). Fürgit pushwird der Token als HTTP-Passwort verwendet. - Default-Branch:
main(es wird direkt aufmaincommittet; Commits sind fein granular je Thema). - Commit-Konvention: deutschsprachige, aussagekräftige Messages; Referenz auf Spec-Abschnitte (z. B. „§7b"). Co-Authored-By-Trailer für KI-Beiträge.
2. Tech-Stack (verifizierte Versionen)
| Bereich | Technologie |
|---|---|
| Runtime | Node.js 26 |
| Framework | Next.js 16 (App Router, React 19, Server Components + Server Actions, Turbopack im Dev) |
| Sprache | TypeScript (strict) |
| DB / ORM | PostgreSQL (mit pgvector) · Prisma 7 (@prisma/client + @prisma/adapter-pg, prisma.config.ts) |
| Auth | NextAuth v5 (Credentials, JWT-Session) · Passwörter mit @node-rs/argon2 |
| i18n | next-intl (Default de, en vorbereitet; Catalog in messages/de.json/en.json) |
| UI | Tailwind v4 + shadcn/ui (Base-UI-Variante), Dark-Theme über zentrale CSS-Tokens in src/app/globals.css |
| Spezial | Handlebars + marked (Richtlinien-Rendering), @xyflow/react + @dagrejs/dagre (Abhängigkeitsgraph), zod (Validierung) |
Scripts (package.json): dev (next dev), build, start, lint (eslint). Seed: npx tsx prisma/seed.ts.
3. Setup (von Null)
# 1. Repo klonen (Token als HTTP-Passwort)
git clone http://gitea-…/msolarczek/ISMS-Tool.git
cd ISMS-Tool
# 2. Abhängigkeiten
npm install
# 3. .env anlegen (Vorlage vorhanden)
cp .env.example .env
# Wichtige Variablen: DATABASE_URL (Postgres inkl. pgvector), AUTH_SECRET, AUTH_URL,
# optional REDIS_URL, AI_PROVIDER/AI_API_KEY, SMTP_* (noch ungenutzt).
# 4. Infrastruktur starten (docker-compose.yml im Repo-Root)
docker compose up -d postgres # Postgres mit pgvector (Image pgvector/pgvector:pg16)
# Weitere Services im Compose: app, worker, redis, minio (Objektspeicher, für späteren
# Logo-Upload), mailhog (SMTP-Dev). Für lokale Entwicklung reicht i. d. R. 'postgres'.
# 5. Prisma-Client + Migrationen
npx prisma generate
npx prisma migrate deploy # wendet alle Migrationen an (inkl. RLS-Policies)
# 6. Seed (Demo-Mandant, Kataloge, Richtlinienpaket, Admin-Konsole)
npx tsx prisma/seed.ts
# 7. Dev-Server
npm run dev # http://localhost:3000 (Port 3000, siehe .claude/launch.json)
Demo-Logins (Passwort Demo1234!): admin@demo.example (Mandanten-Admin + ISB), auditor@demo.example, owner@demo.example, user@demo.example — alle über den Mandanten-Login /login.
Plattform-Admin (Betrieb): getrennter Store + eigener Login /platform/login (TOTP-MFA-Pflicht, Enrollment beim ersten Login). Demo-Konto: admin@demo.example / Demo1234! (gleiche Adresse, aber getrennte Session ohne Mandantenkontext). Das frühere isPlatformAdmin-Flag ist abgelöst; die Admin-Konsole /admin ist nur mit Plattform-Session erreichbar. Siehe Paket 2 der Produktionshärtung.
4. Architektur & tragende Konventionen
Mandantenfähigkeit (kritisch!)
- Jede Fachtabelle hat
tenant_id. Nie ohne Mandantenkontext queren. - Zentraler Guard
dbForTenant(tenantId)insrc/server/db.ts: filtert reads automatisch nachtenantId, injiziert ihn beicreate, prüft Ownership beifindUnique/update/delete. Neue tenant-bezogene Modelle müssen inTENANT_MODELS(indb.ts) eingetragen werden. - Zusätzlich Postgres Row Level Security je Tabelle (Policy
tenant_isolation, gesetzt in den Migrationen). Superadmin/plattformweite Reads laufen über den rohenprisma-Client (nichtdbForTenant). - Session (
src/server/auth.ts) trägttenantId,roles,permissions,isPlatformAdmin.
RBAC
- Katalog + Rollen-Blueprints in
src/server/rbac.ts(PERMISSIONS,ROLE_DEFS). Serverseitige Durchsetzung:requirePermission(session, "x:y")/hasPermission(...). UI-Verstecken ist nur Komfort.
Modul-Gating (§3.4)
- Modul-Katalog in
src/lib/modules.ts. Je MandantTenantModule-Zeilen (enabled). Navigation blendet deaktivierte Module aus (layout.tsx). - Serverseitige Durchsetzung:
requireModule("key")insrc/server/modules.ts, angewandt als Modul-layout.tsxje Routenordner (assets/,processes/,risks/,measures/,policies/,suppliers/,dependencies/) → schützt auch Unterrouten. In Server-Actions läuft der Layout-Guard erst nach der Mutation, daher zusätzlichrequireModuleim Action-guard()(bisher exemplarisch nurpolicies.ts— auf übrige Action-Dateien nachzuziehen).
UI-Muster
- Detail/Bearbeiten/Anlegen überwiegend als URL-gesteuerte Popups (
?detail=/?edit=/?new=1,src/components/modal.tsx) — Ausnahme: Richtlinien-Dokumente wurden bewusst auf eigene Seiten (/policies/[code],.../edit) umgestellt. - Dark-Theme: keine hartkodierten Hex-Werte in Komponenten — zentrale Tokens verwenden (
--bg-0,--panel,--surface-soft,--band,--ok/--warn/--risk/--info, …). - Formulare mit „einem Speichern-Button" nutzen HTML-
form-Attribut-Assoziation (form="id"). - Alle sichtbaren Texte über den next-intl-Catalog (
messages/*.json) — Admin-/Register-Detailtexte teils bewusst inline-Deutsch.
Prisma-7-Migrationen (Eigenheit)
Nicht-interaktiv, in zwei Schritten:
npx prisma migrate diff --from-config-datasource prisma.config.ts \
--to-schema prisma/schema.prisma --script > prisma/migrations/<ts>_name/migration.sql
# RLS-DO-Block manuell an die migration.sql anhängen (siehe bestehende Migrationen)
npx prisma migrate deploy
(Die interaktiven migrate dev-Prompts sind in dieser Umgebung blockiert; Flag-Namen in Prisma 7 geändert: --from-config-datasource/--to-schema.)
5. Verzeichnisstruktur (Auszug)
src/
app/(app)/ # geschützter App-Bereich (Sidebar-Shell = layout.tsx)
dashboard/ assets/ processes/ risks/ measures/ dependencies/ suppliers/
policies/ # Richtlinien: page + [code]/(page,edit) + layout.tsx (Modul-Guard)
admin/ admin/[id]/ # Plattform-Admin-Konsole (Superadmin)
settings/ # Kunden-Einstellungen (tenant:manage)
app/login/ # Login
components/ # UI + Fach-Modals (asset-, supplier-, service-, policy-*.tsx …)
server/
auth.ts db.ts rbac.ts modules.ts provision.ts audit.ts
risk-calc.ts dependency-graph.ts
actions/ # Server Actions je Modul (assets, risks, measures, suppliers,
# services, policies, admin, tenant-settings)
lib/ # modules, policy-render, supplier(+include), risk, control-titles,
# isa-controls, levels, measure, utils
prisma/
schema.prisma seed.ts import-policies.ts import-managed.ts migrations/
messages/ de.json en.json
seed/isms-vorlagenpaket-v2/ # VDA-ISA-Vorlagenpaket (Richtlinien/Verfahren, mapping.json, Baseline …)
docs/ SPEC.md HANDOVER-PM.md HANDOVER-DEV.md *.html (Mockups)
6. Modul-Kurzreferenz (wo liegt was)
- Richtlinien: Rendering-Engine
src/lib/policy-render.ts(Handlebars, Flags, BL-Entfernung,applyProtectionfür TISAX-Level), Importprisma/import-policies.ts+prisma/import-managed.ts, UIsrc/app/(app)/policies/**+src/components/policy-*.tsx, Actionssrc/server/actions/policies.ts. Control-Titelsrc/lib/control-titles.ts. - Lieferanten/IT-Service: Engine
src/lib/supplier.ts, Includessrc/lib/supplier-include.ts, UIsrc/components/supplier-modals.tsx/service-modals.tsx/supplier-cockpit.tsx, Actionssuppliers.ts/services.ts. - Admin/Mandanten: Provisionierung
src/server/provision.ts(von Seed undactions/admin.tsgenutzt, idempotent),actions/tenant-settings.ts(Stammdaten → ISMS-Variablen viasyncPolicyVariablesFromSettings). - Risiko/Graph:
src/server/risk-calc.ts,src/server/dependency-graph.ts,src/lib/risk.ts.
7. Datenmodell — zentrale Modelle
Tenant, TenantSettings (Quelle der ISMS-Variablen), TenantModule, User (isPlatformAdmin), Role/Permission/RolePermission/UserRole, AuditLog (scope: tenant|platform).
Fachlich: Asset/AssetRelation, Process/ProcessAsset/BiaEntry, Risk/RiskAsset/Measure/RiskMeasure, Threat/Vulnerability, SupplierProfile/ITServiceProfile (+ Assessments/Contracts/Ndas/Evidence/Raci/Maturity), Richtlinien: PolicyDocument/PolicyRequirement/PolicyVariable/PolicyBaselineParam/PolicyEvidence + verwaltete Register (CryptoEntry, ClassificationClass/HandlingAspect/HandlingRule, RiskMatrixClass/RiskEwLevel/RiskDamageDimension, HandbookTopic).
8. Verifikations-Workflow
Nach jeder Änderung: npx tsc --noEmit → npm run lint → npm run build. Danach – wo relevant – Browser-Verifikation (Dev-Server + Login admin@demo.example). Bei DB-Änderungen: Migration erzeugen/anwenden + npx tsx prisma/seed.ts neu laufen lassen. Für das Richtlinien-Rendering existiert ein Residue-Check-Muster (rückstandsfrei über Flag-Kombinationen, angelehnt an seed/.../_verify.py).
9. Bekannte Fallstricke
- Beschädigte Seed-Tokens: Das VDA-ISA-Paket enthält in einigen VA-RACI-Tabellen (VA-05/08/09/10/12/13) abgeschnittene
{{VAR |-Tokens. Bei jedem Paket-Update erneut prüfen & reparieren (sonst bricht Handlebars). Scan: unbalancierte{{/}}je Zeile. - Richtlinien-Re-Import ist nicht-destruktiv (Phase-1-Härtung Paket 3,
prisma/import-policies.ts): Diff/Upsert über stabile Schlüssel (code/reqId/key/blId/nr). Vorhandenes wird inhaltlich aktualisiert, aber Status/Override/Freigabe (PolicyDocument) und nutzergepflegte Variablenwerte bleiben erhalten; entfernte Paket-Einträge werden deaktiviert (archivedAt) statt gelöscht (aktive Ansichten filternarchivedAt: null). Verwaltete Register ausimport-managed.ts(CRYPTO/RISKMATRIX/CLASSIFICATION/HANDBUCH) liegen außerhalb des Paket-Namensraums und werden nicht angetastet. Jeder Lauf liefert einen Änderungsreport (Audit-Log, Entitypolicy_package);{ dryRun: true }erzeugt die Vorschau ohne Schreibzugriff. Akzeptanztest:npx tsx scripts/test-reimport.ts. - RLS-Kontext: RLS-Policies erwarten
current_setting('app.tenant_id'). Die App nutzt primär dendbForTenant-Guard; wenn direkte DB-Zugriffe hinzukommen,app.tenant_idin der Transaktion setzen. - Turbopack-HMR kann veraltete Fehler/
MISSING_MESSAGEzeigen, nachdemmessages/*.jsongeändert wurde → Dev-Server neu starten. Produktions-Build ist maßgeblich. - Prisma-7-Migrationsflow wie in §4 (kein
migrate dev). .next-Cache nicht löschen, während der Dev-Server läuft (Turbopack-Korruption) → Server stoppen,rm -rf .next, neu starten.- TISAX-Flags:
FLAG_HIGH_PROTECTIONist im Modell stets aktiv,FLAG_ELEVATED_PROTECTIONwird abgeleitet (applyProtection) — nie manuell setzen. Effektiver Level = Dokument-Override sonst global.
10. Produktionshärtung & Benutzerverwaltung (umgesetzt, Branch dev)
Aufbauend auf dem Fundament wurden mehrere Härtungspakete umgesetzt (feingranulare Commits auf dev):
- API-Modul-Durchsetzung (§3.4): zentraler
moduleGuard("<key>")insrc/server/action-guard.ts; jede mutierende Action eines gegateten Moduls läuft überguard(...)(Session →assertModuleEnabled→ RBAC). Vollständigkeitscheckscripts/check-module-guards.ts(Registry Action→Modul) alsprebuild— Build failt bei nicht zugeordneter Action-Datei. Neue Action-Datei ⇒ dort eintragen (Modul-Key oderEXEMPT). - Plattform-Admins getrennt: Store
PlatformAdmin(keintenant_id), eigene NextAuth-Instanzsrc/server/platform-auth.ts(eigener Cookie/basePath/api/platform-auth, Session ohne Tenant), Login/platform/login, Bereich untersrc/app/(platform)/…. MFA (TOTP,src/server/mfa.ts) ist optional — Enrollment nur erzwungen, wennPlatformSetting.mfaRequired(Singleton) an ist; Umschaltung + Self-Service unter/platform/profile. Rate-Limit/Lockout am Login bleiben. Auditscope=platformviawritePlatformAudit. - Nicht-destruktiver Richtlinien-Re-Import: siehe §9 Punkt 2.
- Benutzer- & Rollenverwaltung (ohne E-Mail-Flow):
- Plattform-Admin je Mandant:
src/server/actions/platform-users.ts+components/platform-tenant-users.tsx, eingebettet in/admin/[id]. Anlegen mit Initial-/Einmal-Passwort (selbst setzen oder generiert, einmalig angezeigt), Rollen, Deaktivieren/Reaktivieren, Passwort-Reset. - Mandanten-Admin intern:
src/server/actions/tenant-users.ts+components/tenant-users-manager.tsx/role-manager.tsx, Seite/settings/users(nuruser:manage/role:manage). Benutzer-CRUD und Rollen-CRUD (eigene Rollen + Permissions; Standardrollen schreibgeschützt/klonbar). StriktdbForTenant(session)→ kein Cross-Tenant. Lockout-Schutz für den letzten aktiven Mandanten-Admin. - Force-Change: neue Nutzer starten mit
mustChangePassword=true; das(app)-Layout leitet autoritativ (DB) auf/change-passwordund sperrt deaktivierte Konten. Passwort-Policy:src/lib/password-policy.ts(Validierung, client-safe) +src/server/password.ts(Argon2id-Hash + Generator); QuelleTenantSettings.securityPolicy.password. - Nutzer-MFA optional: Tenant-Login (
auth.ts) verlangt TOTP nur bei eingerichteter MFA; Self-Service unter/account.role:manageist neu im RBAC-Katalog (Mandanten-Admin).
- Plattform-Admin je Mandant:
- Zukunftssicher:
createTenantUser/createUserkapseln die Aktivierung über Initial-/Einmal-Passwort — der spätere E-Mail-Einladungs-Flow (Paket 4) lässt sich als alternative Aktivierung (Token statt Passwort) einhängen, ohne die UI umzubauen.
11. Nächste sinnvolle Aufgaben (Einstiegspunkte)
- SMTP + Einladungs-/Aktivierungs-/Reset-Flow (Paket 4, M): transaktionale Mails (Nodemailer), signierte Einladungs-/Reset-Tokens; ersetzt/ergänzt den Initial-Passwort-Weg.
- Admin Phase 2 — Impersonation (M): neues Modell
ImpersonationSession, Cookie-basierter effektiver Tenant + Banner, Ablauf, Audit. - Tenant-weite MFA-Pflicht scharfschalten (S):
securityPolicy.mfaRequiredwird vondisableOwnMfabereits respektiert; Enrollment-Erzwingung analog zum Force-Change-Gate (Seite außerhalb der(app)-Shell) nachziehen. - NIS2-Modul (L): eigenes Modul inkl. Incident-Reporting mit Fristen-Timern.
- Richtlinien-Versionierung/Diff (M–L) und DOCX/PDF-Export (M).
Weitere Details, Priorisierung und Aufwände: docs/HANDOVER-PM.md. Projekt-Spec: docs/SPEC.md + Modul-Prompts/Mockups.