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
# Benutzer-Lifecycle-Policy
2026-03-06 12:25:18 +01:00
Letzte Aktualisierung: 2026-03-06
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
## Ziel
Globale Regeln für automatische Benutzer-Deaktivierung und spätere Löschung.
- Stufe 1: Benutzer wird auf `inactive` gesetzt.
- Stufe 2: Inaktiver Benutzer wird nach weiterer Frist gelöscht (Hard Delete).
## Settings
Die Regeln werden in `settings` gespeichert:
- `user_inactivity_deactivate_days`
- `user_inactivity_delete_days`
Semantik:
- Wertebereich: `0..3650`
- `0` deaktiviert die jeweilige Regel
- Löschung wird nur angewendet, wenn Deaktivierung aktiv ist (`deactivate > 0` )
Defaults:
- Deaktivierung: `180`
- Löschung: `365` (ab Inaktivsetzung)
## Referenzdaten
- Deaktivierung basiert auf `COALESCE(last_login_at, created)` .
- Löschung basiert auf `active_changed_at` (nur wenn gesetzt).
## Privilegierte Benutzer (ausgenommen)
Automatische Lifecycle-Aktionen ignorieren Benutzer mit mindestens einer aktiven Rolle, die eine der Permissions hat:
- `settings.update`
- `tenants.update`
## Ausführung
### Manueller Run (Admin UI)
- Endpoint: `POST /admin/settings/run-user-lifecycle`
- Schutz: Login + `settings.update` + CSRF
2026-02-23 12:58:19 +01:00
- Verdrahtung: `SchedulerServicesFactory` erstellt `UserLifecycleService` instanzbasiert.
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
### Cron/CLI
- Bevorzugt über den zentralen Scheduler:
- Script: `bin/scheduler-run.php` (führt fällige Jobs aus, inkl. `user_lifecycle_run` )
- Beispiel (minütlich):
```bash
* * * * * docker compose exec php php bin/scheduler-run.php
```
Exit-Codes:
- `0` erfolgreich
- `1` Fehler/Lock-Konflikt
## Concurrency
Zur Vermeidung paralleler Runs wird ein MySQL-Lock verwendet:
- `GET_LOCK('user_lifecycle_maintenance', 0)`
- `RELEASE_LOCK('user_lifecycle_maintenance')`
## Session-Wirkung
Wenn ein bereits eingeloggter Benutzer automatisch deaktiviert wurde, greift die bestehende Session-Refresh-Logik beim nächsten Request und führt zum Logout.
## Audit-Log (Delete/Restore)
Lifecycle-Events werden in `user_lifecycle_audit_log` protokolliert.
- `deactivate` : erfolgreich ausgeführte automatische Deaktivierung
- `delete` : Löschversuch mit Snapshot
- `restore` : Wiederherstellung aus einem Delete-Event
Wichtige Regeln:
- Delete ist fail-closed: ohne erfolgreich gespeicherten Snapshot wird nicht gelöscht.
- Snapshot wird verschlüsselt in `snapshot_enc` gespeichert.
- Snapshot enthält nur whitelisted Profilfelder (keine Secrets/Tokens).
- Audit-Retention: 365 Tage (`POST /admin/user-lifecycle-audit/purge` ).
## Wiederherstellung (ohne Assignments)
Restore ist nur für `action=delete` + `status=success` möglich und nur einmal pro Event.
Konfliktregeln (Hard fail):
- UUID existiert bereits
- E-Mail existiert bereits
Restore-Ergebnis:
- User wird neu angelegt mit Snapshot-Stammdaten
- `active=0`
- zufälliges Passwort
- keine Wiederherstellung von Tenant-/Role-/Department-Zuweisungen
## Rechte
- Ansicht Lifecycle-Protokolle: `user_lifecycle_audit.view`
- Wiederherstellen aus Lifecycle-Protokoll: `users.lifecycle_restore`
- Purge: `settings.update`