> /dev/null 2>&1 * * Timezone: Europe/Berlin (Dresden Zeitzone) */ class KernelSchedulerExample extends ConsoleKernel { /** * Define the application's command schedule. */ protected function schedule(Schedule $schedule) { // ===================================================================== // EVENT IMPORTS // ===================================================================== // Täglicher Event-Import um 03:00 Uhr nachts $schedule->command('events:import') ->dailyAt('03:00') ->name('events.daily_import') ->onSuccess(function () { $this->logSuccess('Täglicher Event-Import erfolgreich'); }) ->onFailure(function () { $this->logFailure('Täglicher Event-Import fehlgeschlagen'); }); // Stündlicher Import für häufig aktualisierte Quellen $schedule->command('events:import --source="Stadt Dresden"') ->hourly() ->name('events.dresden_hourly') ->withoutOverlapping(30); // Verhindere Überschneidungen // Alle 6 Stunden andere Quellen $schedule->command('events:import --source="Kulturzentrum Hellerau"') ->everyFourHours() ->name('events.hellerau_import'); // ===================================================================== // EVENT MAINTENANCE // ===================================================================== // Markiere abgelaufene Termine als "completed" $schedule->call(function () { \App\Models\EventOccurrence::query() ->where('status', 'scheduled') ->where('end_datetime', '<', now()) ->update(['status' => 'completed']); \Illuminate\Support\Facades\Log::info('Completed events marked as finished'); }) ->dailyAt('04:00') ->name('events.mark_completed'); // Archiviere verwaiste Events (ohne Termine, älter als 1 Monat) $schedule->call(function () { $archived = \App\Models\Event::query() ->doesntHave('occurrences') ->where('status', 'published') ->where('created_at', '<', now()->subMonths(1)) ->update(['status' => 'archived']); \Illuminate\Support\Facades\Log::info("Archived {$archived} orphaned events"); }) ->weekly() ->sundays() ->at('05:00') ->name('events.cleanup_orphaned'); // Lösche softly gelöschte Events nach 90 Tagen $schedule->call(function () { \App\Models\Event::onlyTrashed() ->where('deleted_at', '<', now()->subDays(90)) ->forceDelete(); \Illuminate\Support\Facades\Log::info('Permanently deleted old soft-deleted events'); }) ->weekly() ->name('events.purge_deleted'); // ===================================================================== // PERFORMANCE & OPTIMIZATION // ===================================================================== // Bereinige abgelaufene Cache-Einträge $schedule->command('cache:prune-stale-tags') ->hourly() ->name('cache.prune'); // Bereinige alte Log-Dateien $schedule->command('log:prune') ->daily() ->at('02:00') ->name('logs.prune'); // ===================================================================== // MONITORING & ALERTS (optional) // ===================================================================== // Benachrichtige bei zu vielen fehlgeschlagenen Jobs $schedule->call(function () { $failedCount = \Illuminate\Support\Facades\DB::table('failed_jobs')->count(); if ($failedCount > 10) { \Illuminate\Support\Facades\Log::warning("Alert: {$failedCount} failed jobs"); // Hier könnte Slack/Email-Notification kommen } }) ->everyFiveMinutes() ->name('monitor.failed_jobs'); // ===================================================================== // QA/TESTING (nur Development) // ===================================================================== if (app()->environment('local')) { // Backup der Datenbank täglich um 22:00 $schedule->command('backup:run') ->dailyAt('22:00') ->name('backup.daily'); } } /** * Register the commands for the application. */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } /** * Get the timezone that should be used by default for scheduled events. */ protected function scheduleTimezone(): string { return 'Europe/Berlin'; } // Helper-Methoden für Logging private function logSuccess($message) { \Illuminate\Support\Facades\Log::info("✅ {$message}"); } private function logFailure($message) { \Illuminate\Support\Facades\Log::error("❌ {$message}"); } }