add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
# Architektur
2026-02-23 12:58:19 +01:00
Letzte Aktualisierung: 2026-02-22 (geprüft)
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
## 1) Zielbild
Die Anwendung ist eine servergerenderte Multi-Tenant-Admin-Anwendung mit klarer Trennung von:
- HTTP/Request-Flow (`/web/index.php` , `lib/Http/*` )
- Action-Layer (`/pages/**` )
- Business-Logik (`/lib/Service/**` )
- Datenzugriff (`/lib/Repository/**` )
- Rendering (`/templates/**` , `*.phtml` )
- Frontend-Verhalten (`/web/js/**` )
## 2) Request-Lebenszyklus
Zentraler Entry Point ist `/web/index.php` .
Ablauf pro Request:
1. Bootstrap (`vendor/autoload.php` , `config/config.php` , `config/router.php` , Helper)
2. Firewall + Session Start
3. Locale-Ermittlung (URL/Session/Cookie/default)
4. Remember-Me Auto-Login
5. Optionales Tenant-Snapshot-Refresh in Session
6. Redirect auf locale-prefixed URL (falls nötig)
7. Access Guard (`AccessControl` ) für Public/Protected Paths
8. Action-Layer aus `pages/**` laden
9. View + Template rendern
10. Session beenden, DB schließen
## 3) Routing-Modell
2026-02-23 12:58:19 +01:00
- Route-Definitionen (Pfad-Aliase) liegen in `/config/routes.php` .
- Registrierung erfolgt in `/config/router.php` (liest nur `path` und `target` ; das `public` -Feld wird vom Router nicht ausgewertet).
- Welche Pfade ohne Login erreichbar sind, steuert `lib/Http/AccessControl.php` :
- Hartkodierte `ALWAYS_PUBLIC_PREFIXES` (z. B. `auth/microsoft/` , `api/` , `branding/` , `flash/` )
- `APP_PUBLIC_PATHS` -Konstante (gesetzt in `config/config.php` )
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
MintyPHP-Konvention (Dateinamensrouting):
- `pages/admin/users/edit($id).php` erwartet URL-Parameter `id`
- `pages/admin/users/data().php` für Datenendpunkte
- `...(none).phtml` für responses ohne Template-Layout
2026-02-23 12:58:19 +01:00
- Binärausgaben (z. B. Onboarding-PDF/ZIP) setzen `MINTY_ALLOW_OUTPUT` im Action-Endpoint.
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
## 4) Schichten und Verantwortungen
### Action-Layer (`/pages`)
- Eingaben lesen/validieren
- Permissions und Tenant-Scope prüfen
- Services aufrufen
- View-Daten vorbereiten
### Service-Layer (`/lib/Service`)
- Geschäftsregeln
- Cross-Cutting-Logik (z. B. Auth, Settings, Branding)
- Orchestrierung mehrerer Repositories
2026-02-23 12:58:19 +01:00
- Scheduler/Lifecycle sind instanzbasiert über `lib/Service/Scheduler/SchedulerServicesFactory.php` verdrahtet.
- Import/Import-Audit sind instanzbasiert über `lib/Service/Import/ImportServicesFactory.php` verdrahtet.
- User-Domain ist instanzbasiert über `lib/Service/User/UserServicesFactory.php` verdrahtet
(Services: `UserAccountService` , `UserAssignmentService` , `UserTenantContextService` , `UserPasswordService` ;
Repositories: `UserReadRepository` , `UserWriteRepository` , `UserListQueryRepository` + Assignment-Repositories).
- Auth-/SSO-Domain ist instanzbasiert über `lib/Service/Auth/AuthServicesFactory.php` verdrahtet
(u. a. `AuthService` , `RememberMeService` , `SsoUserLinkService` , `TenantSsoService` , `MicrosoftOidcService` ).
- Auth-Infra-Repositories (`ApiTokenRepository` , `RememberTokenRepository` , `PasswordResetRepository` ,
`EmailVerificationRepository` ) werden ebenfalls instanzbasiert über die Factory injiziert.
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
### Repository-Layer (`/lib/Repository`)
- SQL und Mapping
- Filter-/Paging-Mechaniken
- Keine UI-/HTTP-Logik
### Template/View-Layer (`/templates`, `*.phtml`)
- Nur Rendering
- Keine DB-Zugriffe
- Wiederkehrende UI-Teile als Partials
## 5) Datenmodell (fachlich)
Kernobjekte:
- `users`
- `tenants`
- `departments`
- `roles`
- `permissions`
Verknüpfungen:
- `user_tenants` , `user_departments` , `user_roles`
- `role_permissions`
- `tenant_auth_microsoft` , `user_external_identities`
- `tenant_custom_field_definitions` , `tenant_custom_field_options`
- `user_custom_field_values` , `user_custom_field_value_options`
Hinweis:
- `departments` ist 1:1 an `tenants` gebunden über `departments.tenant_id` (kein M:N-Mapping).
- In der User-Organisation wird die Department-Auswahl tenantweise gerendert (ein Multi-Select je zugewiesenem Tenant), gespeichert wird weiterhin flach über `user_departments` .
- Tenant-spezifische User-Zusatzfelder werden separat modelliert:
- Definitionen/Optionen pro Tenant in `tenant_custom_field_*`
- Werte pro User in `user_custom_field_*`
- Filterung im Address Book über dynamische Query-Keys `cf_*` , `cfm_*` , `cfd_*` .
- `field_key` bleibt intern (tenant-weit eindeutig), wird im Tenant-UI automatisch aus dem Label erzeugt und nicht manuell gepflegt.
- `is_filterable` ist fachlich nur für `select` , `multiselect` , `boolean` , `date` aktiv.
- User-Zusatzfeldwerte sind in V1 optional (keine Pflichtvalidierung).
- Tenant-Theme-Overrides werden direkt auf `tenants` gespeichert:
- `tenants.default_theme` (`NULL` = globales `app_theme` )
- `tenants.allow_user_theme` (`NULL` = globales `app_theme_user` ).
- Auflösung immer über `$_SESSION['current_tenant']` und damit tenant-spezifisch für Multi-Tenant-User.
- Tenant-SSO für Microsoft Entra ID:
- Konfiguration pro Tenant in `tenant_auth_microsoft` .
- Externe Identitäts-Verknüpfung stabil über `user_external_identities` (`provider + tid + oid` ).
- Login-Endpunkte: `login` (optional `?tenant={slug}` ), `auth/microsoft/start` , `auth/microsoft/callback` .
- Shared-App-Credentials liegen global in `settings` ; optionale Tenant-Overrides sind möglich.
- Profil-Sync wird tenant-spezifisch über `tenant_auth_microsoft.sync_profile_on_login` und
`tenant_auth_microsoft.sync_profile_fields` gesteuert.
- Erlaubte Sync-Felder in V1: `first_name` , `last_name` , `phone` , `mobile` , `avatar` .
- `phone/mobile/avatar` kommen über Microsoft Graph (`/me` , `/me/photo/$value` ) und sind fail-open
(Graph-Fehler blockieren den Login nicht).
Sicherheits-/Audit-nahe Tabellen:
- `user_remember_tokens`
- `password_resets`
- `email_verifications`
- `mail_log`
## 6) Sicherheits- und Scope-Modell
- Auth Guard: protected by default
- Permission Checks: feature-spezifisch in Actions/Services
- Tenant Scope: datenabhängig über Tenant-Matches
- Strictness steuerbar über `TENANT_SCOPE_STRICT`
Details siehe:
`/docs/sicherheitsmodell.md`
## 7) Frontend-Architektur
JS-Struktur:
- `/web/js/core` Basismodule (DOM/Grid Factory)
- `/web/js/components` UI-Komponenten
- `/web/js/pages` seitenspezifische Helfer
Bootstrap:
- `app-boot.js` früh (no-js/js state, localStorage UI state)
- `app-init.js` für Default-Template
- `app-login-init.js` für Login-Template
CSS-Struktur:
- Layer-Entrypoint: `/web/css/app-layers.css`
- Basen/Variablen in `/web/css/base`
- Layout in `/web/css/layout`
- Komponenten in `/web/css/components`
- Seitenstile in `/web/css/pages`
- Vendor-Overrides in `/web/css/vendor-overrides`
## 8) Asset-Steuerung
Konfiguration liegt in `/config/assets.php` .
- Template-Gruppen: `default` , `login`
- Seiten-Gruppen optional via `Buffer::set('style_groups', ...)`
- Rendering über Helper: `renderTemplateStyles()` und `renderPageStyles()`
## 9) Erweiterungsstrategie
Pragmatischer Weg für neue Features:
1. Repository erweitern (SQL)
2. Service-Regel bauen
3. Action anbinden
4. View/Partial integrieren
5. JS nur falls interaktiv nötig
6. Tests + Lint/Analyse laufen lassen
So bleibt die Trennung stabil und Refactoring kontrollierbar.
## 10) Settings-Architektur (DB + Datei-Cache)
- `settings` (DB) ist die alleinige fachliche Quelle für globale Settings.
- `config/settings.php` ist ein technischer Teil-Cache für sehr häufig gelesene UI-Basiswerte.
- Zugriffsmuster:
2026-02-23 12:58:19 +01:00
- `SettingGateway` (verdrahtet über `SettingServicesFactory` ) -> `SettingService` -> DB
- `appSetting(...)` -> `SettingServicesFactory` -> `SettingCacheService` (Datei-Cache)
add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
- Konsequenz:
- Es ist korrekt, dass nicht alle DB-Settings im Datei-Cache stehen (z. B. SMTP/SSO/API-Details).
- Der Cache muss nur die Keys enthalten, die im Runtime-Helper `appSetting(...)` verwendet werden.
Details:
`/docs/einstellungen-speicherung.md`