Files
craftvia/docs/_certvia-archiv/KONZEPT-ui-i18n.md
T
msolarczekandClaude Opus 5 cadaedc6cc L10b Betrieb & Aufräumen: Deploy – craftvia-worker, CI-Testjob, DEPLOY.md, Certvia-Doku archiviert
- docker-compose.coolify(.prebuilt).yml: Service craftvia-worker (Target worker, Chromium,
  shm_size 1gb, gleiche Härtung), Craftvia-Variablen für app und worker.
- Dockerfile: worker-Stage mit HOME=/home/app (Chromium-Profil für non-root); lokaler
  docker build der Targets runner und worker erfolgreich, PDF-Erzeugung im Image geprüft.
- .env.example/.env.prod.example/.env.coolify.example: alle Craftvia-Variablen inkl. RLS,
  KI-Provider, PDF_CHROMIUM_PATH, OFFLINE_MAX_DAYS, API_RATE_LIMIT_*, AI_GENERATION_RETENTION_DAYS,
  AI_MONTHLY_TOKEN_LIMIT.
- CI (.github, .gitea): Job gate mit Postgres (pgvector) und Redis als Service: migrate deploy,
  seed, Passwort für craftvia_app, tsc, lint, build, npm run test.
- docs/craftvia/DEPLOY.md (aus den Certvia-Deploy-Docs abgeleitet): Architektur, Domains, Secrets,
  Worker, Migrationen, RLS-Aktivierung, Backup/Restore, KI, Rate Limits, Aufbewahrung, Smoke,
  Update/Rollback. build-and-push-images.sh baut craftvia-worker.
- Certvia-/ISMS-Dokumente aus docs/ nach docs/_certvia-archiv/ (mit README); Verweise in README.md
  und Skript-Kommentaren angepasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00

5.0 KiB

Konzept — Betreiber-Konsole-UX + vollständige i18n (parallele Lane)

Status: Backlog/Feindesign-Skizze (kein Code). Produkt: certvia (ISMS-Tool). Unabhängig von Identity/Backup/Härtung → parallel abarbeitbar. Enthält die zwei gemeldeten „Bugfixes" + zwei kleine Ergänzungen.

Bugfix 1 — Betreiber-Konsole: Module & Benutzer als Popup, Stammdaten sichtbar

Betrifft: src/app/(platform)/admin/[id]/page.tsx (Mandanten-Detailseite im Betreiber-Portal).

Ist: Module-Liste und Benutzerverwaltung liegen inline direkt auf dem Kundenprofil; die eigentlichen Stammdaten des Kunden sind dort nicht prominent.

Soll:

  • Module → Popup: nicht mehr inline, sondern per Button „Module verwalten" → Popup (Muster wie gehabt über searchParam, z. B. ?modules=1, <Modal>). Toggle/Import bleiben im Popup.
  • Benutzer → Popup: die Benutzer-Tabelle/-Verwaltung nicht mehr im Hauptfenster, sondern Button „Benutzer verwalten" → Popup (?users=1). Anlage/Bearbeiten laufen wie bisher als verschachtelte Modals (?new/?edit).
  • Hauptfenster stattdessen: Stammdaten (aus TenantSettings: Unternehmensname/Kurzname, Adresse, Sektor, D-U-N-S, TISAX-Level, Status) + Hauptkontakt prominent sichtbar. „Hauptkontakt" = neues/abgeleitetes Feld (z. B. designierter Mandanten-Admin oder ein Stammdaten-Kontaktfeld) — offene Kleinentscheidung: eigenes Feld in TenantSettings (mainContactName/Email/Phone) vs. Ableitung aus dem tenant-admin.

Muster ist vorhanden: die Seite nutzt bereits <Modal> + searchParams (?new/?edit/?audit) → Module/Benutzer analog kapseln, keine neue Infrastruktur.

Dateien: src/app/(platform)/admin/[id]/page.tsx, ggf. src/components/* (Auslagerung Module-/Benutzer-Block), optional Migration für mainContact* in TenantSettings.

Bugfix 2 — Vollständige UI-Sprache (Menü + Beschreibungen) + per-Mitarbeiter-Umschaltung

Wichtiger Befund: Der englische UI-Katalog existiert bereits (messages/en.json, ~95 % vs. messages/de.json). Bisher ist nur der Richtlinien-Inhalt EN (über TenantSettings.locale, das die Import-Sprache der Vorlagen steuert). Das Menü/die Beschreibungen sind EN im Katalog vorhanden, werden aber nie angezeigt, weil:

src/i18n/request.ts:8  → const locale = "de";   // hart verdrahtet
// Kommentar: "MVP is fixed to de; per-user locale (en) is prepared — switch here later"

Soll: die UI-Sprache per Mitarbeiter individuell umschaltbar.

  • Speicherort (Option-C-konform): persönliche Präferenz gehört an die Identity (folgt der Person über alle Mandanten) — neues Feld Identity.uiLocale (de|en, Default de). (Alternative: pro Mitgliedschaft — verworfen, weil Menüsprache eine Personen-, keine Mandantenpräferenz ist.)
  • Aktivierung: src/i18n/request.ts liest statt der Konstante die uiLocale der aktiven Session-Identity (Fallback de).
  • Umschalter: im Nutzer-Menü (Header/Profil) ein Sprachauswahl-Control → Server-Action setUiLocale → Identity.uiLocale speichern, Seite neu laden.
  • Restsprache: messages/en.json auf 100 % prüfen/auffüllen (Lücken, neue Strings aus TISAX/Identity-Umbau). Sicherstellen, dass alle sichtbaren Strings über den Katalog laufen (keine hartkodierten deutschen Texte in Komponenten).

Abgrenzung: TenantSettings.locale bleibt für die Vorlagen-Import-Sprache (Inhalt); neu ist die UI-Sprache je Person (Identity.uiLocale) — zwei getrennte Achsen.

Dateien: prisma/schema.prisma (Identity.uiLocale + Migration), src/i18n/request.ts, Nutzer-Menü-Komponente (Header/Profil) + setUiLocale-Action, messages/en.json (Lückenschluss), Audit der hartkodierten Strings.

Ergänzung A — Login-Maske: Organisationsfeld entfällt

Ist: src/app/login/page.tsx zeigt weiterhin ein optionales Feld „Organisation" (tenant, als Hinweis behalten). Soll: Feld entfernen — nach Option C ist es überflüssig (Login gegen globale Identity; Mandant wird nach dem Login über /select-tenant gewählt). Die tenant-Durchreichung in login-Action / signMfaPending / signLoginTicket kann entfallen bzw. leer bleiben. Dateien: src/app/login/page.tsx (Feld raus), ggf. src/server/login-ticket.ts-Signaturen entschlacken.

Ergänzung B — Konsistenz-Check „Stammdaten"

Beim Sichtbarmachen der Stammdaten (Bugfix 1) prüfen, dass die Quelle eine bleibt (TenantSettings speist die ISMS-Variablen) — keine Doppelpflege einführen.

Reihenfolge / Parallelität

  • Bugfix 1 (Betreiber-Konsole) und Bugfix 2 (i18n) sind unabhängig → parallel.
  • Ergänzung A (Login) ist ein 10-Minuten-Fix, gern zusammen mit Bugfix 2 (beide Auth-/UI-nah).
  • Keine Abhängigkeit zu Backup/Härtung; Bezug zu Option C nur konzeptuell (Identity.uiLocale, /select-tenant existiert bereits).

Gate (wie immer)

tsc/lint/build + scripts/test-*.ts grün; UI-Änderungen im Browser verifizieren (Betreiber-Popups, Sprachumschaltung DE↔EN, Login ohne Organisationsfeld).