Fundament: ISMS-Module entfernt; Craftvia-Rollen, Module, Navigation, i18n-Split

- ISMS-Routen, Actions, Server-/Lib-Code, Komponenten, Prisma-Modelle, Seeds,
  Importer, Skripte und ISMS-Tests entfernt (Fundament bleibt: Auth, Identity,
  MFA/WebAuthn, RBAC, Audit, Mail, Storage, Backup/DSGVO, Plattform-Admin)
- Schema auf Fundament-Modelle reduziert; TenantSettings generisch (+phone/email)
- TENANT_MODELS (db.ts, backup/topology.ts) und PII-Felder ausgedünnt
- RBAC: Rollen tenant-admin/backoffice/team-lead/technician + Craftvia-Permissions
- Modul-Katalog (customers, sites, teams, work_orders, imports, field, reports,
  emergency, documents, notifications, lotse) + Navigation aus src/lib/nav.ts
- Modul-Routen mit requireModule-Layout und Platzhalterseite
- Message-Katalog je Namespace (messages/<locale>/<namespace>.json), fs-Loader
- check-module-guards: Modul-Key aus src/server/actions/<moduleKey>/
- Provisionierung, Admin-Konsole, Einstellungen, Files-Route, Mail entkoppelt
- Seed minimal (demo/demo2, Nutzer je Rolle); Fundament-Tests auf Role/
  NotificationPreference-Fixtures umgestellt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 11:35:44 +02:00
co-authored by Claude Opus 5
parent c8e6f30a27
commit 8491c7f173
443 changed files with 1325 additions and 87773 deletions
-1136
View File
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
{
"backToOverview": "Zurück zur Übersicht",
"crumb": "Mandant",
"sub": "Kürzel {slug}{sector}",
"statusActive": "Aktiv",
"statusSuspended": "Gesperrt",
"statusArchived": "Archiviert",
"masterDataTitle": "Stammdaten",
"masterDataHint": "Unternehmensdaten aus den Mandanten-Einstellungen.",
"orgName": "Unternehmensname",
"orgShort": "Kurzname",
"slug": "Kürzel",
"address": "Adresse",
"sector": "Sektor",
"status": "Status",
"notSet": "—",
"mainContactTitle": "Hauptkontakt",
"mainContactHint": "Abgeleitet aus dem/den Mandanten-Administrator(en).",
"mainContactNone": "Kein aktiver Mandanten-Administrator hinterlegt.",
"manageTitle": "Verwaltung",
"manageHint": "Module und Benutzer dieses Mandanten in einem Popup verwalten.",
"manageModules": "Module verwalten",
"manageUsers": "Benutzer verwalten",
"usersCount": "{count} Nutzer",
"modulesTitle": "Module",
"modulesHint": "Deaktivierte Module sind für den Kunden ausgeblendet und serverseitig gesperrt.",
"moduleActive": "Aktiv",
"moduleInactive": "Inaktiv",
"moduleActivate": "Aktivieren",
"moduleDeactivate": "Deaktivieren",
"modulesModalSub": "Module für {name} aktivieren/deaktivieren",
"usersModalSub": "Benutzer von {name} — anlegen, Rollen, deaktivieren, Passwort zurücksetzen",
"lifecycleTitle": "Lebenszyklus",
"lifecycleActivate": "Aktivieren",
"lifecycleSuspend": "Sperren (Login blockiert)",
"lifecycleArchive": "Archivieren",
"lifecycleNote": "Gesperrte Mandanten können sich nicht anmelden; Archivierung blendet sie aus.",
"mfaTitle": "MFA-Pflicht",
"mfaHint": "Bei Aktivierung müssen alle Nutzer dieses Mandanten beim nächsten Login eine Zwei-Faktor-Authentifizierung einrichten. Aktuell: {state}.",
"mfaStateOn": "aktiv",
"mfaStateOff": "aus",
"mfaActivate": "MFA-Pflicht aktivieren",
"mfaDeactivate": "MFA-Pflicht deaktivieren",
"auditTitle": "Audit-Trail",
"auditHint": "Nachvollziehbare Aktivitäten dieses Mandanten — wer hat wann was geändert.",
"auditView": "Audit-Trail einsehen",
"auditSub": "Aktivitäten von {name} (neueste zuerst, letzte 200)",
"userCreate": "Benutzer anlegen",
"userCreateSub": "Neuer Nutzer für {name}",
"userEdit": "Benutzer bearbeiten — {name}",
"close": "Schließen",
"phone": "Telefon",
"email": "E-Mail",
"localeTitle": "Mandantensprache",
"localeHint": "Standardsprache für Benachrichtigungen und Dokumente dieses Mandanten (Nutzer wählen ihre UI-Sprache selbst). Aktuell: {lang}.",
"localeDe": "Deutsch",
"localeEn": "English"
}
+23
View File
@@ -0,0 +1,23 @@
{
"appName": "Craftvia",
"appTagline": "Handwerk. Digital auf Kurs.",
"language": "Sprache",
"logout": "Abmelden",
"create": "Anlegen",
"save": "Speichern",
"cancel": "Abbrechen",
"edit": "Bearbeiten",
"delete": "Löschen",
"back": "Zurück",
"close": "Schließen",
"search": "Suchen…",
"actions": "Aktionen",
"add": "Hinzufügen",
"remove": "Entfernen",
"none": "—",
"comingSoon": "Bald verfügbar",
"confirmDelete": "Wirklich löschen?",
"yes": "Ja",
"no": "Nein",
"readOnly": "Nur-Lese-Zugriff."
}
+8
View File
@@ -0,0 +1,8 @@
{
"title": "Dashboard",
"crumb": "Übersicht",
"subtitle": "Willkommen, {name} — {tenant}",
"placeholderTitle": "Dashboard in Umsetzung",
"placeholder": "Hier erscheinen künftig offene Aufträge, heutige Einsätze, freizugebende Berichte und Notdienst-Meldungen.",
"moduleDisabled": "Das angeforderte Modul ist für Ihren Betrieb nicht freigeschaltet."
}
+11
View File
@@ -0,0 +1,11 @@
{
"title": "Anmelden",
"tagline": "Handwerk. Digital auf Kurs.",
"subtitle": "Melde dich mit deinem Firmenkonto an.",
"email": "E-Mail-Adresse",
"password": "Passwort",
"mfaOptional": "MFA-Code (falls eingerichtet)",
"submit": "Anmelden",
"forgotPassword": "Passwort vergessen?",
"error": "Anmeldung fehlgeschlagen. Bitte prüfe E-Mail und Passwort."
}
+18
View File
@@ -0,0 +1,18 @@
{
"customers": "Kunden",
"sites": "Objekte",
"teams": "Teams",
"workOrders": "Aufträge",
"imports": "Auftragsimport",
"field": "Einsätze",
"reports": "Berichte",
"emergency": "Notdienst",
"documents": "Dokumente",
"notifications": "Benachrichtigungen",
"lotse": "Lotse (KI-Assistent)",
"placeholder": {
"crumb": "Modul",
"status": "Modul in Umsetzung",
"hint": "Dieser Bereich wird gerade gebaut. Navigation, Modul-Freischaltung und Berechtigungen sind bereits aktiv."
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"dashboard": "Dashboard",
"workOrders": "Aufträge",
"imports": "Import",
"customers": "Kunden",
"sites": "Objekte",
"teams": "Teams",
"reports": "Berichte",
"documents": "Dokumente",
"settings": "Einstellungen",
"admin": "Admin-Konsole"
}
-1136
View File
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
{
"backToOverview": "Back to overview",
"crumb": "Tenant",
"sub": "Slug {slug}{sector}",
"statusActive": "Active",
"statusSuspended": "Suspended",
"statusArchived": "Archived",
"masterDataTitle": "Master data",
"masterDataHint": "Company data from the tenant settings.",
"orgName": "Company name",
"orgShort": "Short name",
"slug": "Slug",
"address": "Address",
"sector": "Sector",
"status": "Status",
"notSet": "—",
"mainContactTitle": "Main contact",
"mainContactHint": "Derived from the tenant administrator(s).",
"mainContactNone": "No active tenant administrator on record.",
"manageTitle": "Management",
"manageHint": "Manage this tenant's modules and users in a popup.",
"manageModules": "Manage modules",
"manageUsers": "Manage users",
"usersCount": "{count} users",
"modulesTitle": "Modules",
"modulesHint": "Disabled modules are hidden from the customer and blocked server-side.",
"moduleActive": "Active",
"moduleInactive": "Inactive",
"moduleActivate": "Activate",
"moduleDeactivate": "Deactivate",
"modulesModalSub": "Enable/disable modules for {name}",
"usersModalSub": "Users of {name} — create, roles, deactivate, reset password",
"lifecycleTitle": "Lifecycle",
"lifecycleActivate": "Activate",
"lifecycleSuspend": "Suspend (login blocked)",
"lifecycleArchive": "Archive",
"lifecycleNote": "Suspended tenants cannot sign in; archiving hides them.",
"mfaTitle": "MFA requirement",
"mfaHint": "When enabled, every user of this tenant must set up two-factor authentication at their next login. Currently: {state}.",
"mfaStateOn": "on",
"mfaStateOff": "off",
"mfaActivate": "Enable MFA requirement",
"mfaDeactivate": "Disable MFA requirement",
"auditTitle": "Audit trail",
"auditHint": "Traceable activity of this tenant — who changed what and when.",
"auditView": "View audit trail",
"auditSub": "Activity of {name} (newest first, last 200)",
"userCreate": "Create user",
"userCreateSub": "New user for {name}",
"userEdit": "Edit user — {name}",
"close": "Close",
"phone": "Phone",
"email": "E-mail",
"localeTitle": "Tenant language",
"localeHint": "Default language for notifications and documents of this tenant (users choose their own UI language). Currently: {lang}.",
"localeDe": "German",
"localeEn": "English"
}
+23
View File
@@ -0,0 +1,23 @@
{
"appName": "Craftvia",
"appTagline": "Trades. Digitally on course.",
"language": "Language",
"logout": "Sign out",
"create": "Create",
"save": "Save",
"cancel": "Cancel",
"edit": "Edit",
"delete": "Delete",
"back": "Back",
"close": "Close",
"search": "Search…",
"actions": "Actions",
"add": "Add",
"remove": "Remove",
"none": "—",
"comingSoon": "Coming soon",
"confirmDelete": "Really delete?",
"yes": "Yes",
"no": "No",
"readOnly": "Read-only access."
}
+8
View File
@@ -0,0 +1,8 @@
{
"title": "Dashboard",
"crumb": "Overview",
"subtitle": "Welcome, {name} — {tenant}",
"placeholderTitle": "Dashboard under construction",
"placeholder": "Open work orders, today's jobs, reports awaiting approval and emergency calls will appear here.",
"moduleDisabled": "The requested module is not enabled for your company."
}
+11
View File
@@ -0,0 +1,11 @@
{
"title": "Sign in",
"tagline": "Trades. Digitally on course.",
"subtitle": "Sign in with your company account.",
"email": "E-mail address",
"password": "Password",
"mfaOptional": "MFA code (if enabled)",
"submit": "Sign in",
"forgotPassword": "Forgot password?",
"error": "Sign-in failed. Please check e-mail and password."
}
+18
View File
@@ -0,0 +1,18 @@
{
"customers": "Customers",
"sites": "Sites",
"teams": "Teams",
"workOrders": "Work orders",
"imports": "Order import",
"field": "Field jobs",
"reports": "Reports",
"emergency": "Emergency service",
"documents": "Documents",
"notifications": "Notifications",
"lotse": "Lotse (AI assistant)",
"placeholder": {
"crumb": "Module",
"status": "Module under construction",
"hint": "This area is currently being built. Navigation, module activation and permissions are already in place."
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"dashboard": "Dashboard",
"workOrders": "Work orders",
"imports": "Import",
"customers": "Customers",
"sites": "Sites",
"teams": "Teams",
"reports": "Reports",
"documents": "Documents",
"settings": "Settings",
"admin": "Admin console"
}