'boolean', 'vlan_id' => 'integer', 'scan_interval_minutes' => 'integer', 'last_scanned_at' => 'datetime', ]; /** Ist ein automatischer Scan fällig? */ public function isScanDue(): bool { if (!$this->active || !$this->scan_interval_minutes) { return false; } if (!$this->last_scanned_at) { return true; } return $this->last_scanned_at->addMinutes($this->scan_interval_minutes)->isPast(); } /** Lesbare Intervall-Beschreibung */ public function getScanIntervalLabelAttribute(): string { return match($this->scan_interval_minutes) { 5 => 'alle 5 Minuten', 15 => 'alle 15 Minuten', 30 => 'alle 30 Minuten', 60 => 'stündlich', 360 => 'alle 6 Stunden', 720 => 'alle 12 Stunden', 1440 => 'täglich', default => 'manuell', }; } public function createdBy(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function scans(): HasMany { return $this->hasMany(NetworkScan::class, 'segment_id'); } public function latestScan(): HasMany { return $this->hasMany(NetworkScan::class, 'segment_id')->latestOfMany(); } /** Alle Hosts dieses Segments (über Scans) */ public function hosts(): HasManyThrough { return $this->hasManyThrough(NetworkHost::class, NetworkScan::class, 'segment_id', 'scan_id'); } /** Anzahl online-Hosts im letzten Scan */ public function getOnlineCountAttribute(): int { return $this->scans()->latest()->first()?->online_hosts ?? 0; } /** Anzahl Geräte gesamt im letzten Scan */ public function getTotalCountAttribute(): int { return $this->scans()->latest()->first()?->total_hosts ?? 0; } /** Letzter Scan-Zeitpunkt */ public function getLastScannedAtAttribute(): ?string { return $this->scans()->latest()->first()?->created_at?->format('d.m.Y H:i'); } }