retentionDays = $stored > 0 ? (string) $stored : null; } /** Persist the retention policy, audit the change and notify the operator. */ public function saveRetention(): void { $validated = $this->validate([ 'retentionDays' => ['nullable', 'integer', 'min:1', 'max:3650'], ]); $days = $validated['retentionDays'] !== null && $validated['retentionDays'] !== '' ? (int) $validated['retentionDays'] : 0; Setting::put('audit_retention_days', $days > 0 ? (string) $days : null); $this->retentionDays = $days > 0 ? (string) $days : null; AuditEvent::create([ 'user_id' => Auth::id(), 'actor' => Auth::user()?->name ?? 'system', 'action' => 'audit.retention_set', 'target' => 'audit_retention_days='.$days, 'ip' => request()->ip(), ]); $this->dispatch('notify', message: __('audit.retention_saved_notify')); } /** Effective retention in days (0 = unlimited) for the policy summary. */ protected function retentionPolicy(): int { return $this->retentionDays !== null && $this->retentionDays !== '' ? (int) $this->retentionDays : 0; } /** * Letzte Audit-Ereignisse, optional gefiltert. Echte Daten aus der DB; * die Filterung läuft im Speicher über die geladenen 50 Einträge. */ protected function events(): Collection { $events = AuditEvent::with('server')->latest()->limit(50)->get(); $needle = trim($this->q); if ($needle === '') { return $events; } $needle = mb_strtolower($needle); return $events->filter(function (AuditEvent $e) use ($needle): bool { $haystack = mb_strtolower(implode(' ', array_filter([ $e->actor, $e->action, $e->action_label, $e->target, $e->server?->name, ]))); return str_contains($haystack, $needle); })->values(); } public function render() { return view('livewire.audit.index', [ 'events' => $this->events(), 'retentionPolicy' => $this->retentionPolicy(), ])->title(__('audit.title')); } }