# Geplante Aufgaben Letzte Aktualisierung: 2026-03-06 ## Ziel Scheduler-Betrieb und Job-Erweiterung kurz und verlässlich dokumentieren. ## Kernkomponenten - Runner: `bin/console scheduler:run` - Orchestrierung: `lib/Service/Scheduler/SchedulerRunService.php` - Job-Konfiguration: `lib/Service/Scheduler/ScheduledJobService.php` - Registry: `lib/Service/Scheduler/ScheduledJobRegistry.php` - Schedule-Berechnung: `lib/Service/Scheduler/ScheduleCalculator.php` ## Datenmodell - `scheduled_jobs`: Job-Konfiguration und letzter Laufstatus - `scheduled_job_runs`: Historie einzelner Läufe - `scheduler_runtime_status`: Heartbeat/Runner-Status (eine Zeile, `id = 1`) Retention: - Run-Logs: 90 Tage (`ScheduledJobService::purgeRunsExpired`) - System-Audit: konfigurierbar über `system_audit_retention_days` (Job `system_audit_purge`) ## Laufmodell 1. Runner startet und synchronisiert Registry-Jobs (`ensureSystemJobs`). 2. Globaler MySQL-Lock wird gesetzt (`scheduled_jobs_runner`). 3. Fällige Jobs (`enabled=1`, `next_run_at <= now`) werden abgearbeitet. 4. Jeder Lauf wird als `success`/`failed`/`skipped` protokolliert. 5. `next_run_at` wird neu berechnet. 6. Heartbeat wird aktualisiert, Lock wird freigegeben. ## Scheduling Unterstützt: - `hourly` (1..24) - `daily` (1..365 + Uhrzeit) - `weekly` (1..52 + Uhrzeit + Wochentage) `catchup_once` steuert Nachholverhalten: - `1`: genau ein Nachhol-Lauf, danach normal weiter - `0`: kein Backlog-Sturm, verpasste Fenster werden übersprungen ## Rechte - `jobs.view`: Übersicht sehen - `jobs.manage`: Job speichern - `jobs.run_now`: Job manuell starten - Purge der Run-Logs: `settings.update` Registrierte Core-Jobs: - `user_lifecycle_run` - `system_audit_purge` ## Neuen Job registrieren (kurz) 1. Handler in `lib/Service/Scheduler/Handler/*` erstellen (`ScheduledJobHandlerInterface`). 2. Job-Key + Handler in `ScheduledJobRegistry` ergänzen. 3. Abhängigkeiten in `SchedulerServicesFactory` verdrahten. Danach wird der Job bei `ensureSystemJobs()` automatisch in `scheduled_jobs` angelegt. ## Troubleshooting - `lock_not_acquired`: ein anderer Runner läuft. - Job bleibt `running`: stale-running Schutz greift nach 2 Stunden. - Job läuft nicht: `enabled`, `next_run_at`, `timezone`, Schedule prüfen.