Admin-Tools
Alle Admin-Seiten sind via Gate::allows('admin') geschuetzt. Admins werden ueber config('postbox.admin_emails') definiert. Nicht-Admins erhalten 404 statt 403 (URL-Verschleierung).
Einheitliche Cron-Status-Anzeige
Alle Admin-Seiten mit zugehoerigen Scheduled Commands zeigen einen einheitlichen Status-Block via <x-admin.cron-status> Blade-Component.
Anzeige
| Element | Beschreibung |
|---|---|
| Status-Badge | Farbcodiert: Gruen (Erfolgreich), Amber (Verzoegert), Rot (Fehlgeschlagen), Grau (Ausstehend) |
| Letzter Lauf | Absoluter Zeitstempel (z.B. "08.03.2026 11:38 UTC") + relatives Datum ("vor 2 Stunden") |
| Naechster Lauf | Naechste geplante Ausfuehrung, berechnet aus der Cron-Expression |
Technische Umsetzung
- Service:
CronStatusService(app/Services/CronMonitoring/CronStatusService.php) - Component:
<x-admin.cron-status>(resources/views/components/admin/cron-status.blade.php) - Datenquelle: Heartbeat-Cache-Keys (
cron:heartbeat:{key}) + Cron-Expressions viadragonmantank/cron-expression - Status-Logik:
ok(innerhalb max_minutes),warning(>75% von max_minutes),failed(ueberfaellig),pending(kein Heartbeat)
Integration pro Admin-Seite
| Seite | Heartbeat-Keys |
|---|---|
| Social Profiles | instagram_scrape, youtube_scrape |
| AI Enhancements | pipeline_run |
| Tag Management | tag_cache |
| YouTube Management | youtube_video_sync, websub_manage, youtube_rss_poll |
| Publishing Analytics | youtube_publishing_stats |
| Related Channels | cross_platform_auto_fill |
| Profil-Links (Import Status) | collector_requeue |
| Explore Status | pipeline_run, explore_metrics |
| Public Explorer | public_explorer_refresh |
| AI Agent Analytics | indexnow_submit, sitemap_generate |
| Open Graph | public_explorer_refresh |
| API Management | google_api_sync |
| SEO Dashboard | seo_sync_search_console, indexnow_submit |
Verwendung
{{-- Einzelner Heartbeat --}}
<x-admin.cron-status :keys="'pipeline_run'" />
{{-- Mehrere Heartbeats (worst-case Status) --}}
<x-admin.cron-status :keys="['youtube_video_sync', 'websub_manage']" />
Bei mehreren Keys wird der schlechteste Status angezeigt (failed > warning > ok > pending), der letzte Lauf ist der aktuellste, der naechste Lauf der frueheste.
Location: app/Services/CronMonitoring/CronStatusService.php, resources/views/components/admin/cron-status.blade.php
Admin SocialProfiles
Route: /admin/social-profiles
Title: Admin: Social Profiles
Zentrale Verwaltungs-Seite fuer alle getracken Profile mit Health-Stats, Filtern und Aktionen.
Health-Stats
Oben auf der Seite werden aggregierte Statistiken angezeigt:
| Stat | Beschreibung |
|---|---|
| Gesamt | Alle Profile |
| Tracking aktiv | tracking_enabled = true |
| Deaktiviert | deactivated_at IS NOT NULL (Fail-Streak) |
| Sanitizer | sanitized_at IS NOT NULL |
| Pending Retry | Im Retry-Lifecycle |
| Archiviert | archived_at IS NOT NULL |
| Gesperrt | blocked_at IS NOT NULL |
| Ohne Metriken | Keine social_profile_daily_metrics |
| API OK / Fehler / Inaktiv | API-Status des letzten Scrapes |
Filter
| Filter | Optionen |
|---|---|
| Suche | Name, Handle |
| Plattform | YouTube, Instagram |
| Tracking | Aktiv, Inaktiv |
| API-Status | OK, Fehler, Inaktiv |
| Sanitizer | Aktiv (sanitized), Deaktiviert, Admin-geschuetzt |
| Sortierung | Name, Followers, Created, Updated |
Aktionen
| Aktion | Methode | Beschreibung |
|---|---|---|
| Block | block() | Profil sperren (blocked_at, blocked_by, block_reason) |
| Unblock | unblock() | Sperre aufheben |
| Enable Tracking | enableTracking() | Tracking aktivieren, Sanitizer-Schutz setzen |
| Disable Tracking | disableTracking() | Tracking deaktivieren |
| Reset Fail-Streak | resetFailStreak() | Deaktivierung aufheben |
| Reset Related | resetRelatedChannels() | Related Channels zuruecksetzen |
| Prune | pruneProfile() | Profil physisch loeschen (nur wenn tracking disabled + keine Watcher) |
Location: app/Livewire/Admin/SocialProfiles/Index.php
Admin Statistics
Route: /admin/statistics
Title: Admin: Statistiken
Dashboard-Charts fuer System-Ueberblick mit globalem Zeitraum-Filter (Default: 1 Tag):
| Chart | Serien | Datenquelle |
|---|---|---|
| Plattform-Verteilung | YouTube, Instagram | SocialProfile::created_at |
| Workspaces & Watchers | Workspaces, Watchers | Workspace::created_at, Watcher::created_at |
| Account-Status | Users, Blocked, Sanitized, Kontakte | User, SocialProfile, SocialProfileLink |
| Mail-Zustellung | Gesendet, Fehlgeschlagen | NotificationStat |
Zeitraum-Filter
| Range | Beschreibung |
|---|---|
1d | Letzter Tag (Default) |
7d | Letzte 7 Tage |
30d | Letzte 30 Tage |
all | Gesamter Zeitraum |
Ein globaler Range-Filter steuert alle 4 Charts gleichzeitig. Daten werden mit 1h Cache-TTL geladen (Cache::remember("admin:statistics:{chart}:{range}", now()->addHours(1), ...)). Der refreshCharts()-Button invalidiert alle Cache-Keys und berechnet die Charts neu.
Mail-Features
| Feature | Beschreibung |
|---|---|
| Mail Flood Guard Status | Zeigt aktuellen Flood-Guard-Status (aktiv/pausiert) |
| Test-E-Mail senden | Admin kann Test-Mail an sich selbst senden |
Location: app/Livewire/Admin/Statistics/Index.php
Admin Log & Queue
Route: /admin/log-queue
Title: Admin: Log & Queue
Container-Seite fuer:
- Log Viewer: Integration von
opcodesio/log-viewer(via separater Route/admin/logs) - Queue Status: Live-Metriken der Queue-Worker
- YouTube Update Status: Collector-Job-Status (queued/leased/completed/failed)
- Queue Metrics Chart: Jobs pending/processing/failed ueber Zeit
Sub-Komponenten:
QueueMetricsChart- Zeitreihen-Chart der Queue-MetrikenYoutubeUpdateStatus- Aktueller Status der YouTube-Collector-Jobs
Location: app/Livewire/Admin/LogQueue/Index.php, app/Livewire/Admin/LogQueue/QueueMetricsChart.php, app/Livewire/Admin/LogQueue/YoutubeUpdateStatus.php
Admin YouTube Management
Route: /admin/youtube-management
Title: Admin: YouTube Management
Zentrale Uebersichts-Seite fuer YouTube Video Detection, PRO-Profile, WebSub, RSS-Polling und Video-Statistiken-Tracking.
Video-Statistiken Abruf-Diagramm (Plan 30)
Interaktives ApexCharts-Diagramm zeigt taeglich, wie viele Videos frische Statistiken erhalten haben.
Datenfluss:
graph TD
A[youtube:sync-video-stats - 14:00 UTC] --> B[youtube_video_daily_metrics]
C[youtube:calculate-video-scores - 21:00 UTC] --> D[youtube_video_scores]
B --> E[youtube:aggregate-video-stats-tracking - 22:00 UTC]
D --> E
E --> F[youtube_video_stats_daily_aggregations]
F --> G[ApexCharts auf /admin/youtube-management]
Aggregations-Tabelle: youtube_video_stats_daily_aggregations
| Spalte | Typ | Beschreibung |
|---|---|---|
date | date | Aggregierter Tag (unique) |
total_videos | int | Videos im Bestand (nicht entfernt) |
total_removed | int | Entfernte Videos |
videos_with_metrics | int | Videos mit frischen Metriken |
videos_without_metrics | int | Videos ohne Metriken |
reason_removed | int | Grund: Video entfernt |
reason_sync_disabled | int | Grund: Profil auto_sync deaktiviert |
reason_over_limit | int | Grund: Ueber max_videos Limit |
reason_before_cutoff | int | Grund: Vor Cutoff-Datum |
reason_tracking_disabled | int | Grund: Profil tracking_enabled = false |
profiles_synced | int | Anzahl gesyncter Profile |
quota_units_used | int | API Quota Units verbraucht |
videos_with_score | int | Videos mit VPS-Score |
videos_score_pending | int | Videos mit Pending-Score |
health_score | tinyint | Gesundheits-Score (0-100) |
Chart-Features:
| Feature | Beschreibung |
|---|---|
| Multi-Serien Chart | Videos im Bestand (Line), Abgerufen (Area), Nicht abgerufen (Area), Quota Units (dashed Line) |
| Zeitraum-Toggle | 7 Tage / 30 Tage |
| Custom Tooltip | Bestand, Abgerufen, Coverage %, Quota Units, Health Score |
| KPI-Kacheln | Coverage %, Health Score, Quota Units, VPS-Score Stats |
| Aufschluesselungs-Tabelle | Tageszeilen mit Gruende-Breakdown |
| Coverage-Alert | Admin-Notification wenn Coverage < 50% |
| Profil-Drill-Down | Welche Profile an einem Tag gesynct wurden |
Health-Score-Berechnung (0-100):
- Coverage % (50% Gewichtung) — videos_with_metrics / total_videos
- Sync-Aktivitaet (25% Gewichtung) — profiles_synced / total auto_sync profiles
- Score-Vollstaendigkeit (25% Gewichtung) — videos_with_score / videos_with_metrics
Gruende-Prioritaet (keine Doppelzaehlung): removed > sync_disabled > tracking_disabled > before_cutoff > over_limit
Command:
# Gestern aggregieren (Default)
php artisan youtube:aggregate-video-stats-tracking
# Bestimmtes Datum
php artisan youtube:aggregate-video-stats-tracking --date=2026-03-01
# Alle fehlenden Tage nachberechnen
php artisan youtube:aggregate-video-stats-tracking --backfill
Schedule: Taeglich 22:00 UTC (nach Video-Sync 14:00 und Scores 21:00)
Weitere Sektionen
| Sektion | Beschreibung |
|---|---|
| WebSub Subscriptions | Gesamt, Aktiv, Ausstehend, Fehlgeschlagen, Ablaufend (48h), Erneuerungsfehler |
| Video-Erkennung | Neue Videos 24h/7d/30d/Gesamt |
| PRO-Profile | Auto-Sync aktiv/deaktiviert, Tracking-Startdatum, Fail-Streak |
| RSS-Polling | Gepollt (letzte Stunde), Noch nie gepollt, Mit ETag |
| Konfiguration | WebSub/RSS Status, Intervall, PRO Max Videos |
| Neue Videos Trend (14 Tage) | Tabelle mit Balkendiagramm |
Location: app/Livewire/Admin/YouTubeManagement/Index.php, app/Console/Commands/AggregateVideoStatsTracking.php
Admin YouTube Research
Route: /admin/youtube-research
YouTube Data API Search Tool fuer Admins mit Einzel- und Batch-Suche.
Features
| Feature | Beschreibung |
|---|---|
| Einzelsuche | YouTube-Suche mit Freitext und Topic-IDs |
| Batch-Suche | Bis zu 20 Keywords gleichzeitig mit Qualitaetsfilter |
| Qualitaetsfilter | Min. Subscriber, Min. Videos pro Kanal (via channels.list API) |
| Keyword-Suggestions | AI-Keywords aus bestehenden Profilen mit 14-Tage-Cooldown |
| YouTube Suggest | Autocomplete-Vorschlaege von YouTube Suggest API |
| Ergebnisse | Anzeige mit Kanal-Info, Followers, Views |
| Import | Ergebnisse direkt in einen Workspace importieren |
| URL Export | Ergebnis-URLs exportieren |
| History | Vergangene Suchanfragen mit Ergebnissen und Batch-Status |
Batch-Suche
graph TD
A[Admin gibt Keywords ein] --> B[ProcessYouTubeResearchBatch Job]
B --> C{Fuer jedes Keyword}
C --> D[YouTube Search API]
D --> E{Qualitaetsfilter aktiv?}
E -->|Ja| F[channels.list API: Subscriber/Video Check]
E -->|Nein| G[Alle Ergebnisse speichern]
F --> G
G --> H[YouTubeResearchBatchProgress Event]
H --> I[Echtzeit-Fortschritt im UI]
C --> J[Batch abgeschlossen]
Batch-Filter-Optionen:
| Filter | Typ | Beschreibung |
|---|---|---|
topic_id | string | YouTube Topic-ID (Music, Gaming, Sports, etc.) |
relevance_language | string | ISO 639-1 Sprache |
region_code | string | ISO 3166-1 Region |
min_subscribers | int | Mindest-Subscriber-Anzahl |
min_videos | int | Mindest-Video-Anzahl |
Location: app/Livewire/Admin/YouTubeResearch/Index.php, app/Jobs/ProcessYouTubeResearchBatch.php
Admin AI Enhancements
Route: /admin/ai-enhancements
Uebersicht aller AI-Detections (Gemini):
- Statistiken: Gesamt-Detections, Erfolgs-/Fehlerrate, Profile mit Kategorie/Keywords/Description
- Tabelle: Badges fuer Sprache, Land, Kategorie, Keywords, Description
- Detail-Modal: Alle AI-generierten Daten mit Confidence-Levels
- Filter: Plattform, Status, Sprache, Land, Confidence
- Quick-Fix: "AI bearbeiten"-Button im Detail-Modal oeffnet den AiFieldEditor
Location: app/Livewire/Admin/AiEnhancements/Index.php
Admin AiFieldEditor (Manual Override)
Trigger: Event openAiFieldEditor — kann von beliebigen Seiten ausgeloest werden.
Modales Admin-Component fuer manuelle Korrektur von AI-generierten Feldern (Kategorie, Beschreibung, Keywords). Dual-Field-System: ai_manual_* Felder ueberschreiben ai_* Felder, alle Consumer nutzen effective_* Accessors.
Integration
Der "AI bearbeiten"-Button ist auf drei Seiten verfuegbar:
| Seite | Trigger |
|---|---|
| Watcher Show | Button neben Profil-Details (Admin-only) |
| Public Explorer Show | Button auf der Profilseite (Admin-only) |
| AI Enhancements Detail-Modal | Button im Modal |
Features
| Feature | Beschreibung |
|---|---|
| Vergleichsansicht | AI-Wert vs. Manual Override nebeneinander |
| Override-Toggles | Checkbox pro Feld aktiviert/deaktiviert den manuellen Override |
| Cross-Platform Verify | Verifizierung von Cross-Platform-Zuordnungen (cross_profile_verified_at) |
| Cross-Platform Propagate | Kategorie + Keywords auf Partner-Profil uebertragen |
| Audit-History | Letzte 10 Aenderungen mit Admin-Name und Zeitstempel |
| Explore-Sync | Speichern aktualisiert sofort die Explore-Kategorie |
Audit-Log
Jede Aenderung wird in ai_manual_override_logs protokolliert:
field:category,descriptionoderkeywordsold_value/new_value: Vorheriger und neuer Wertuser_id: Admin der die Aenderung vorgenommen hat
Location: app/Livewire/Admin/AiFieldEditor.php, resources/views/livewire/admin/ai-field-editor.blade.php, app/Models/AiManualOverrideLog.php
Admin Google API Usage
Route: /admin/google-api-usage
Title: Admin: Google API Usage
Navigation: YouTube-Gruppe (Sidebar)
Quota-Dashboard fuer Google API Keys mit Live-Sync-Status:
- Donut-Charts: Verbrauch pro Projekt/Metrik
- Zeitreihen: Quota-Verlauf ueber Tage
- Sync: Manueller Sync via
google:sync-api-usage(queued, nicht synchron) - Sync-Overlay: Waehrend Background-Sync zeigt ein halbtransparentes Overlay auf allen Projekt-Cards "Daten werden aktualisiert..." mit Spinner. Polling wechselt von 1h auf 10s. Automatische Erkennung wenn Sync abgeschlossen (vergleicht
synced_atTimestamps mit Sync-Startzeit). Button zeigt Spinner-Animation. - Circuit Breaker Status: Zeigt den Status aller YouTube API Key Pools (default, video, research, extended)
- Quota Guard Metriken: Circuit-Open, Jobs-Blocked, Jobs-Released pro Pool
- Auto-Refresh: Polling alle 3600s (1h), waehrend Sync alle 10s
Location: app/Livewire/Admin/GoogleApiUsage/Index.php
Admin Related Channels
Route: /admin/related-channels
Verwaltungs-Seite fuer Related Channels:
| Feature | Beschreibung |
|---|---|
| Status-Uebersicht | Pending, Running, Completed, Failed Counts |
| Suche | Nach Profil-Name/Handle |
| Status-Filter | Alle, Pending, Completed, Failed |
| Platform-Filter | YouTube, Instagram |
| Reset | Related Channels fuer ein Profil zuruecksetzen |
| Stuck-Erkennung | Findet Profile im "running"-Status seit >1h |
Location: app/Livewire/Admin/RelatedChannels/Index.php
Admin App Monitoring
Route: /admin/app-monitoring
Title: Admin: App Monitoring
Zentrale Monitoring-Übersichtsseite die den Gesamtstatus aller Systeme auf einen Blick zeigt.
Sektionen
| Sektion | Beschreibung |
|---|---|
| System-Ampel | Großer Status-Badge: "Alle Systeme OK" (grün) / "Warnung" (gelb) / "Kritisch" (rot) — basierend auf dem schlechtesten Sub-System-Status |
| Server-KPIs | CPU, RAM, Disk, PG Connections als kompakte Badges mit Farb-Codierung (Daten aus Pulse) |
| Queue-Status | Queued/Failed Jobs, Worker-Status (aktiv/inaktiv) |
| Uptime SLA (E2) | System-Uptime-Prozentsatz mit Period-Selector (7d/30d), Top-5 schlechteste Heartbeats |
| Cron-Heartbeat-Tabelle | Alle Heartbeats mit Status, Alter, Limit, Abhängigkeiten, Mute/Unmute-Buttons |
| Dependency Map (E4) | Konfigurierte Abhängigkeiten zwischen Commands mit Upstream-Status |
| Event-Historie (Phase 3) | Letzte 50 Events (failed, recovered, escalated, muted, unmuted) mit Filter |
Heartbeat-Status-Farben
| Status | Farbe | Beschreibung |
|---|---|---|
ok | Grün | Heartbeat innerhalb max_minutes |
failed | Rot | Heartbeat überfällig |
not_required | Gelb | Kein Heartbeat, aber Deploy-Grace-Period aktiv |
muted | Grau | Von Admin stumm geschaltet |
Alter-Farbcodierung
- Grün: <50% von max_minutes
- Gelb: 50-100% von max_minutes
- Rot: >100% von max_minutes (überfällig)
Admin-Aktionen
| Aktion | Beschreibung |
|---|---|
| Stumm schalten | Heartbeat-Alerting deaktivieren (bleibt sichtbar mit "Muted" Badge) |
| Stummschaltung aufheben | Alerting wieder aktivieren |
Auto-Refresh
wire:poll.30s — automatische Aktualisierung alle 30 Sekunden.
Location: app/Livewire/Admin/AppMonitoring/Index.php, resources/views/livewire/admin/app-monitoring/index.blade.php
Admin Server Monitoring
Route: /admin/server
Title: Admin: Server
Live Server-Monitoring mit Echtzeit-Updates via Reverb:
- Metriken: CPU, RAM, Disk, Swap, Load Average
- Alerts: Schwellwert-basierte Alarme
- Alert History: Vergangene Alarme
- Refresh: Automatisch alle 15 Sekunden
Events: .server.metrics.updated, .server.alert.triggered
Location: app/Livewire/Admin/ServerDashboard.php
Admin Reverb Test
Route: /admin/reverb-test
WebSocket-Konnektivitaets-Test:
- Test-Event senden (
TestBroadcast) - Event-Log anzeigen
- Verbindungsstatus pruefen
Location: app/Livewire/Admin/ReverbTest/Index.php
Admin Pages (CMS)
Route: /admin/pages, /admin/pages/create, /admin/pages/{page}/edit
CMS-lite fuer statische Seiten (Impressum, Datenschutz, etc.):
Status Workflow
| Status | Beschreibung |
|---|---|
is_draft | Default fuer neue Seiten, nicht oeffentlich sichtbar |
is_review_needed | Zur internen Pruefung markiert |
is_published | Oeffentlich sichtbar |
Features
- Auto-generierte Meta-Description aus HTML-Content
- Navigation-Priority fuer Menu-Reihenfolge
- Show-in-Header/Footer/Sidebar Toggles
- Revision History via Laravel Auditing
- One-Click Restore vorheriger Versionen
Location: app/Livewire/Admin/Pages/Index.php, app/Livewire/Admin/Pages/Edit.php
Profile Sanitizer
Automatische Deaktivierung von Low-Value-Profilen via profiles:sanitize (taeglich 04:30 UTC).
Regeln
| Plattform | Bedingung fuer Deaktivierung |
|---|---|
| YouTube | video_count < 1 AND followers_count < 100 |
post_count < 1 AND followers_count < 100 |
Schutz-Bedingungen
- Mindestalter: 7 Tage seit Erstellung
- Mindest-Metriken: 3 Metriken-Eintraege
- Uebersprungen: Blocked, Archived, Deactivated (Fail-Streak), Admin-geschuetzt
Admin Override Flow
- Admin findet sanitized Profil in
/admin/social-profiles(Filter: Sanitizer -> Deaktiviert) - Admin klickt "Enable" ->
enableTracking()setztsanitized_at = null, behaeltsanitize_checked_at - Sanitizer ueberspringt Profile mit
sanitize_checked_at IS NOT NULL AND sanitized_at IS NULL - Permanenter Schutz: Nur Fail-Streak kann das Profil erneut deaktivieren
Re-Check Zyklus
Bereits sanitized Profile werden alle 3 Monate erneut geprueft. Falls die Metriken sich verbessert haben, wird das Profil reaktiviert.
php artisan profiles:sanitize
php artisan profiles:sanitize --dry-run
Config: config('postbox.sanitizer') - alle Werte env-konfigurierbar
Prune
Physisches Loeschen von Profilen und zugehoerigen Daten. Unabhaengig vom Sanitizer.
Commands
# Max-Anzahl pro Plattform (aelteste zuerst)
php artisan watchers:prune-to-max
php artisan watchers:prune-to-max --dry-run
# Nach Metriken (Follower, Videos, Posts)
php artisan watchers:prune-by-metrics
php artisan watchers:prune-by-metrics --dry-run
Admin UI Prune
Einzelnes Profil loeschen ueber /admin/social-profiles:
- Voraussetzung:
tracking_enabled = falseUND keine aktiven Watcher - Admin-Workspace wird zuerst bereinigt
Location: app/Livewire/Admin/SocialProfiles/Index.php (Methode pruneProfile())
Admin Users
Route: /admin/users
Title: Admin: Users
User-Verwaltung mit Workspace- und Watcher-Counts, User-Blocking und Block-History.
User-Blocking-System
Admins koennen User account-weit sperren. Gesperrte User werden sofort aus allen Sessions ausgeloggt.
graph TD
A[Admin klickt Block] --> B[Block-Grund eingeben]
B --> C[blockUser: blocked_at + blocked_by + block_reason]
C --> D[Sessions loeschen + remember_token null]
C --> E[UserBlock Audit-Log erstellen]
D --> F[User sofort ausgeloggt]
F --> G{User versucht Login}
G --> H[CheckBlockedUser Middleware: 403]
G --> I[Fortify Login: generische Fehlermeldung]
Blocking-Aktionen
| Aktion | Methode | Beschreibung |
|---|---|---|
| Block | blockUser(int $id) | User sperren mit Grund. Sessions + Token invalidieren. Audit-Log. |
| Unblock | unblockUser(int $id) | Sperre aufheben. Audit-Log. |
| Block History | showBlockHistory(int $id) | Alle Block/Unblock-Aktionen anzeigen (Modal) |
Sicherheits-Checks
- Admin-Selbstsperre verhindert:
if ($user->id === auth()->id()) return - Middleware-Integration:
CheckBlockedUserprueftisBlocked()bei jedem authentifizierten Request - Fortify-Integration: Login-Versuch wird mit generischer Fehlermeldung abgelehnt
Filter
| Filter | Optionen |
|---|---|
| Suche | Name, E-Mail |
| Admin | Alle, Admins, Nicht-Admins |
| Status | Alle, Gesperrt |
Location: app/Livewire/Admin/Users/Index.php
Admin Tag Management
Route: /admin/tag-management
Tag-Verwaltung fuer AI-generierte Tags:
| Feature | Beschreibung |
|---|---|
| Block Tag | Tag sperren (mit Grund) |
| Unblock Tag | Sperre aufheben |
| Consolidation | AI-gesteuerte Tag-Zusammenfuehrung starten |
| Suche | Tags durchsuchen |
| Filter | Nur geblockte Tags anzeigen |
Location: app/Livewire/Admin/TagManagement/Index.php
Admin Update Status
Route: /admin/update-status
Title: Admin: Update Status
Container fuer YouTube- und Instagram-Update-Status sowie Pipeline-Monitoring:
- YouTube: Queue-Status der Collector-Jobs, Breakdown-Kategorien mit Fortschritt
- Instagram: Scrape-Status pro Rotation (queued/completed/failed), Retry-Statistiken
- Pipeline: Tages-Pipeline mit Schritten, Health-Indikator, PRO Video Metrics Check
Breakdown-Stabilität: Die Kategorie-Summen (PRO, Leader, Candidate, Favorit, Catch-Up, Rotation, Low-Priority) bleiben über den Tag stabil. Profile, die nach dem Scraping ihre ursprüngliche Kategorie-Zuordnung verlieren (z.B. isNew → false), werden automatisch über einen elseif ($isUpdatedToday) Catch-All in die korrekte Kategorie zurückgezählt.
Pipeline Status Dashboard
Die Pipeline-Status-Seite zeigt den taeglichen Verarbeitungsfortschritt aller Pipeline-Schritte (YouTube Sync, Instagram Scrape, Explore-Berechnung, Trending Videos etc.).
| Feature | Beschreibung |
|---|---|
| Gesundheits-Indikator | Prominenter Banner: Gruen „Alles OK" (alle Schritte abgeschlossen), Blau „In Bearbeitung" (Steps laufen), Rot „X Probleme" (Fehler erkannt) |
| Trending Videos Step | Pipeline-Schritt „Trending Videos" in der Verarbeitungsgruppe. Zeigt Anzahl berechneter Videos pro Tag aus explore_trending_videos. Retry: explore:calculate --type=videos |
| PRO Video Metrics Health Check | Prueft ob alle PRO-Profile taegliche Video-Metriken haben. Nur Videos innerhalb des Tracking-Fensters (video_tracking_start_date oder cutoff_months) werden gezaehlt, begrenzt auf pro_max_videos (100). Warnung mit paginierter Tabelle (25/Seite) inkl. Beschreibungstext. Gruener Badge wenn alles OK |
| Instagram Stall Detection | Erkennt wenn Instagram-Scraping haengt (keine Fortschritte ueber laengeren Zeitraum) und zeigt Warnung |
Location: app/Livewire/Admin/UpdateStatus/DailyPipelineStatus.php, app/Services/Pipeline/PipelineStatusService.php
Retry-Statistiken (Instagram)
In der Instagram-Sektion werden zusätzlich Retry/Inactive-Profile-Statistiken angezeigt:
| Stat | Farbe | Beschreibung |
|---|---|---|
| In Cooldown | Amber | Profile mit scrape_fail_streak >= 3 (noch aktiv, aber im Cooldown) |
| Warten auf Retry | Orange | Deaktivierte Profile mit next_retry_at in der Zukunft |
| Gesamt inaktiv | Orange | Alle deaktivierten, nicht-archivierten Profile |
| Archiviert | Rot | Profile mit archived_at (> 6 Monate deaktiviert) |
Collector Health Dashboard
Integriert in die Instagram-Sektion auf /admin/update-status:
| Feature | Beschreibung |
|---|---|
| Circuit Breaker Status | Zeigt ob der CollectorCircuitBreaker offen (pausiert) oder geschlossen (aktiv) ist, inkl. aktueller Fehlerrate der letzten 60 Minuten |
| Collector-Client-Health | Pro Client: healthy/offline-Badge basierend auf Heartbeat-Timeout (10 Min, COLLECTOR_CLIENT_HEARTBEAT_TIMEOUT). Deaktivierte Clients (alle Tokens revoziert) werden automatisch ausgeblendet. |
| Recovery-Erkennung | Wenn ein offline-Client wieder auftaucht, wird ein Cache-Event geschrieben und eine Admin-Notification gesendet |
| Systemic-Outage-Alarm | Bei >500 requeued expired Leases in einem collector:requeue-expired-leases-Lauf wird eine Admin-Notification via NotificationService::announceToAll() ausgeloest |
| Caching | getResearchImportStats() gecacht (1h TTL), getPriorityProfileIds() gecacht (4h TTL). Manueller Refresh-Button löscht Cache. |
Config:
| Key | Default | Beschreibung |
|---|---|---|
COLLECTOR_CIRCUIT_BREAKER_THRESHOLD | 0.5 | Fehlerrate ab der der Circuit Breaker oeffnet (50%) |
COLLECTOR_CIRCUIT_BREAKER_MIN_SAMPLE | 50 | Minimale Job-Anzahl bevor der Breaker greifen kann |
COLLECTOR_CLIENT_HEARTBEAT_TIMEOUT | 600 | Sekunden ohne Heartbeat bis Client als offline gilt |
COLLECTOR_MAX_FAIL_COUNT | 3 | Max. explizite Failures pro Job bevor permanent failed |
COLLECTOR_REQUEUE_BACKOFF | [30, 120] | Exponentieller Backoff in Sekunden bei transientem Fehler-Requeue |
Location: app/Livewire/Admin/UpdateStatus/InstagramUpdateStatus.php, app/Services/Collector/CollectorCircuitBreaker.php, app/Models/CollectorClient.php
Admin Error Monitor
Route: /admin/error-monitor
Title: Admin: Error Monitor
HTTP-Fehlerseiten-Monitoring (400–599) und URL-Redirect-Management.
Features
| Feature | Beschreibung |
|---|---|
| Error-Logging | Automatisch via TrackErrorPages Middleware (PostgreSQL UPSERT: 1 Zeile pro Pfad + Status + Stunde) |
| Bot-Erkennung | User-Agent-Analyse fuer Bot-Traffic-Filterung |
| 4 KPI-Boxen | 4xx gestern/heute (Trend), 5xx gestern/heute (Trend), Unique Pfade (24h), Bot-Anteil |
| Tages-Chart | 14-Tage-Verlauf (4xx + 5xx), inkl. Live-Daten fuer heute |
| Fehler-Tabelle | Pfad, Status, Hits, letzter Hit, Bot-Anteil — filterbar, paginiert (50/Seite) |
| Redirect-CRUD | URL-Redirects mit Regex-Support, Loop-Detection, Status-Code-Auswahl (301/302/307/308/410) |
| Dismiss (Kein Redirect) | Pfad als "Kein Redirect noetig" markieren — Redirect-Button wird ausgeblendet, Pfad bleibt sichtbar |
| Mute (Stummschalten) | Pfad stummschalten — wird weiterhin getrackt, aber von Anomalie-Detection/Alert-Emails ausgeschlossen. Nützlich fuer Pfade die natuerlich Fehler erzeugen (z.B. abgelaufene CSRF-Tokens, Bot-Probes) |
| Anomalie-Detection | Stuendliche Pruefung gegen Schwellwerte, konsolidierte Alert-Email (max 1/h). Gemutete Pfade werden uebersprungen |
| Weekly Report | Woechentlicher Error-Report an Admin-Emails (mit Stumm-Spalte) |
Datenfluss
graph TD
A[HTTP Request] --> B[HandleRedirects Middleware]
B -->|301/302/307/308| C[Redirect + Hit-Counter]
B -->|410| C2[abort 410 Gone + Hit-Counter]
B -->|Kein Match| D[Routing + Controller]
D --> E[Response]
E --> F[TrackErrorPages Middleware]
F -->|4xx/5xx| G[ErrorMonitorService::recordErrorSimple]
G --> H[error_page_logs UPSERT]
I[Cron: error-monitor:rollup-daily] --> J[error_page_daily_stats]
K[Cron: error-monitor:check-anomalies] --> L{Schwellwert ueberschritten?}
L -->|Ja| M[ErrorMonitorAnomalyAlert Email]
Commands
| Command | Schedule | Beschreibung |
|---|---|---|
error-monitor:rollup-daily | 01:10 taeglich | Logs → Daily Stats aggregieren |
error-monitor:check-anomalies | Stuendlich | Schwellwerte pruefen + Alert |
error-monitor:prune | Sonntag 03:00 | Logs + Stats > 365 Tage loeschen |
error-monitor:weekly-report | Montag 08:00 | Woechentlicher Report an Admins |
Redirect-Management
Admins koennen URL-Redirects mit optionalem Regex-Pattern erstellen. Loop-Detection verhindert Redirect-Schleifen. Hit-Counter verfolgt die Nutzung.
| Status-Code | Verhalten |
|---|---|
| 301 | Permanent Redirect → Browser cacht |
| 302 | Temporary Redirect |
| 307 | Temporary Redirect (Methode beibehalten) |
| 308 | Permanent Redirect (Methode beibehalten) |
| 410 | Gone — abort(410), kein Redirect, Seite als dauerhaft entfernt markiert |
Bei 410 wird kein Ziel-URL benoetigt — die Middleware gibt direkt abort(410, 'Gone') zurueck. Hit-Counter wird trotzdem gezaehlt.
Pfad-Aktionen (Fehler-Tabelle)
Pro Fehlerpfad stehen drei Aktionen zur Verfuegung:
| Aktion | Button | Beschreibung |
|---|---|---|
| Redirect erstellen | Redirect | Oeffnet Redirect-Modal mit vorausgefuelltem Source-Pfad |
| Kein Redirect | Kein Redirect | Markiert Pfad als "Kein Redirect noetig" — Redirect-Button wird ausgeblendet, Pfad bleibt in Tabelle. Aufhebbar per X-Button |
| Stummschalten | Lautsprecher-Icon | Pfad wird weiterhin getrackt, aber von checkAnomalies() uebersprungen — keine Alert-Emails mehr. Amber-Badge "Stumm" zeigt Status an. Aufhebbar per Klick auf Badge |
Mute und Dismiss sind unabhaengig — ein Pfad kann gleichzeitig "Kein Redirect" UND "Stumm" sein.
Datenbank: dismissed_error_paths Tabelle mit path_hash (MD5, unique), is_muted (boolean), dismissed_by (FK → users).
Excluded Paths
Pfade die von der Middleware gar nicht erst getrackt werden (kein DB-Eintrag):
// config/postbox.php → error_monitor.excluded_paths
'/api/*', '/livewire/*', '/livewire-*', '/broadcasting/*',
'/_debugbar/*', '/_ignition/*', '/up', '/up_system'
Hinweis: /livewire-* matcht Livewire v3 AJAX-Requests (/livewire-{hash}/update). Das aeltere Pattern /livewire/* greift nur fuer /livewire/... (ohne Hash-Suffix).
Location: app/Livewire/Admin/ErrorMonitor/Index.php, app/Services/ErrorMonitor/ErrorMonitorService.php, app/Services/ErrorMonitor/RedirectManager.php
Admin Explore & Discover Status
Route: /admin/explore-status
Title: Admin: Explore Status
Explore-System-Ueberblick mit Inventar-Statistiken und Bestandsentwicklung.
KPI-Boxen (6)
| KPI | Beschreibung |
|---|---|
| In Explore | Gesamtzahl Profile in Explore |
| Abdeckung | Prozentuale Coverage aller Profile |
| Trending | Anzahl Profile mit Trending-Score |
| Rising Stars | Neue Rising Stars |
| Neue Profile (24h) | Heute hinzugefuegte Profile |
| Trending Videos | Videos mit Trending-Score |
Bestandsentwicklung (letzte 14 Tage)
Tabelle mit taeglichen Explore-Inventar-Snapshots:
- Gesamtzahl, Plattform-Split (YouTube/Instagram)
- Tier-Verteilung (Mega/Large/Medium/Small/Micro)
- Trending- und Rising-Stars-Counts
- Delta-Spalte mit Veraenderung zum Vortag (gruen/rot)
Datenquelle: explore_daily_snapshots-Tabelle, befuellt nach explore:calculate --type=daily.
Weitere Sektionen
- Tier-Verteilung: Balkendiagramm (Mega/Large/Medium/Small/Micro)
- Plattform-Verteilung: YouTube vs. Instagram
- Kategorie-Tabelle: Profile pro Kategorie mit Count
Location: app/Livewire/Admin/ExploreStatus/Index.php, app/Models/ExploreDailySnapshot.php
Admin AI-Agent Analytics
Route: /admin/ai-agent-analytics
Title: Admin: AI-Agent Analytics
Umfassendes Monitoring-Dashboard fuer AI-Bot-Traffic, Konfigurations-Compliance und SEO-Indexierung. Zeigt welche AI-Bots via robots.txt erlaubt/blockiert sind, trackt Cloudflare AI Crawl Traffic und ueberwacht IndexNow-Submissions.
Tabs
| Tab | Beschreibung |
|---|---|
| Config | 12 konfigurierte AI-Bots (OpenAI, Anthropic, Perplexity etc.) mit Operator, Kategorie (Search/Assistant/Training), Status (erlaubt/blockiert). SEO-Dateien-Status (robots.txt, llms.txt, llms-full.txt, sitemap.xml) |
| Traffic | KPI-Cards (Total Requests, Data Transfer, Unique Bots, Top Bot). Bot-Traffic-Chart (24h/7d). Donut-Chart Data Transfer by Bot. Top Crawled Paths. Response-Status pro Bot |
| Analysis | Crawler-Effizienz-Bewertung (efficient/normal/heavy/excessive). Content-Value-Schaetzung (USD). Traffic-Anomalien (Spike/Drop vs. Vorperiode) |
| Discovery | Unbekannte Bot User-Agents mit Request-Counts. Robots.txt-Violations (Bots die trotz Blockierung zugreifen) |
| IndexNow | Submission-Statistiken (Success/Failure), tägliches Chart, aktuelle Submissions-Log |
Datenquelle: Cloudflare GraphQL Analytics API (AI Crawl Metrics), Redis-Cache
Location: app/Livewire/Admin/AiAgentAnalytics/Index.php
Admin API Management
Route: /admin/api-management
Title: Admin: API Management
Sanctum-API-Token-Lifecycle-Management fuer Collector-Clients. Erstellen, Revozieren, Loeschen von Personal Access Tokens mit Ablaufdatum, Abilities und IP-Whitelisting.
Features
| Feature | Beschreibung |
|---|---|
| Token erstellen | Name, Abilities, optionales Ablaufdatum, IP-Whitelist |
| Aktive Tokens | Tabelle mit Name, Abilities, Ablaufstatus, Erstelldatum, Aktionen (Chart, IP-Edit, Revoke) |
| Revozierte Tokens | Soft-revozierte Tokens mit permanenter Loesch-Option |
| Token-Usage-Charts | Lazy-loaded Line-Charts pro Token ueber 24h/7d/30d |
| Uebersichts-Chart | Sparkline der gesamten API-Nutzung |
| IP-Whitelist-Editor | Modal zum Bearbeiten erlaubter IPs (kommasepariert) |
| Plaintext-Banner | Einmalige Anzeige des generierten Tokens (nur bei Erstellung) |
Location: app/Livewire/Admin/ApiManagement/Index.php
Admin Cloudflare Management
Route: /admin/cloudflare-management
Title: Admin: Cloudflare Management
R2-Storage-Bucket-Monitoring und Analytics-Dashboard. Zeigt Kapazitaet, Kosten-Schaetzungen, Anomalien, Operations-Metriken und Billing-Trends.
Features
| Feature | Beschreibung |
|---|---|
| Bucket-Metriken | Bucket-Groesse (MB), Objekt-Anzahl, Snapshot-Timestamp |
| Kosten-Schaetzung | Monatliche Aufschluesselung: Storage, Class A/B Ops, Egress, Gesamt (USD) |
| Operations-Breakdown | Counts nach Typ (List, Get, Put, Delete), Class A/B Totals |
| Account-Metriken | Storage-Klassen: Standard und Infrequent-Access |
| Backup-Status | Health-Check, Objekt-Anzahl, letzter Sync |
| Anomalie-Erkennung | Alerts bei ungewoehnlichen Metrik-Aenderungen (aktuell vs. Vorperiode) |
| Storage-Forecast | 6-Monats-Projektion: aktuell GB, projiziert GB, taegliche Wachstumsrate |
| Billing-Vergleich | Aktueller vs. vorheriger Monat mit Prozent-Delta |
| R2 Metrics Chart | Zeitreihen-Chart der R2-Metriken (stündlich/täglich) |
| Manueller Refresh | Background-Command mit Polling bis Abschluss |
Location: app/Livewire/Admin/CloudflareManagement/Index.php, app/Livewire/Admin/CloudflareManagement/R2MetricsChart.php
Admin DB-Monitoring
Route: /admin/db-monitoring
Title: Admin: DB-Monitoring
PostgreSQL-Performance- und Health-Monitoring-Dashboard. Zeigt Live-Connection-Counts, Cache-Hit-Ratios, Query-Dauer, Slow-Query-Log, Tabellen-Statistiken und historische Trend-Charts.
Features
| Feature | Beschreibung |
|---|---|
| Aktuelle Metriken | KPI-Cards: Active Connections, Cache Hit Ratio, Longest Query, DB Size (30s Cache) |
| Performance-Warnungen | Schwellwert-basierte Warnings (Connections, Cache Hit, Query Duration) |
| Historische Charts | 4 Line-Charts: Connections, Cache Hit Ratio, Longest Query, DB Size (1h/6h/24h/7d/30d) |
| Live-Queries | Echtzeit-Tabelle langlaufender Queries (>5s) mit Dauer und State |
| Slow-Query-Log | Aggregierte Slow Queries aus pg_stat_statements (Top 50, gruppiert nach Hash) |
| Query-Detail-Modal | Vollstaendige Slow-Query-Anzeige fuer selektierten Hash |
| Tabellen-Statistiken | Top 30 Tabellen nach Groesse mit Row Count, Dead Rows, Vacuum-Status |
| Index-Probleme | Ungenutzte/selten genutzte Indexes, Sequential-Scan-Warnings |
| Table-Size-Chart | 14-Tage-Trend der Top-10-Tabellen |
Datenquelle: pg_stat_activity, pg_stat_statements, db_monitoring_snapshots, db_slow_query_log, db_table_size_snapshots
Location: app/Livewire/Admin/DbMonitoring/Index.php
Admin Import Status
Route: /admin/import-status
Title: Admin: Profil-Links Verwaltung
Contact-Link-Verwaltung und Review-Dashboard. Zeigt alle extrahierten Kontakt-Links (URLs, E-Mails, Social Handles) ueber Profile hinweg mit Approve/Reject-Workflows.
Features
| Feature | Beschreibung |
|---|---|
| Statistik-Boxen | Total Links, Pending Review, Approved, Rejected, Auto-Backref, Import-Status |
| Paginierte Link-Liste | 50 pro Seite mit Link-Wert, Quell-Profil, Typ, Plattform, Approval-Status |
| Suche | Volltextsuche nach Link-Wert oder Profil-Handle |
| Filter | Status (Review/Approved/Rejected), Plattform, Typ (Social/E-Mail/Telefon/URL) |
| Review-Aktionen | Approve, Reject, Unapprove, Unreject mit sofortigem Status-Update |
| Auto-Backref | Gegenseitige Verlinkungen aus Import-Prozess |
| Discovery-Status | Pending/Completed/Failed/Not Found fuer Auto-Discovery |
Location: app/Livewire/Admin/ImportStatus/Index.php
Admin Matomo Statistiken
Route: /admin/matomo-statistics
Title: Admin: Matomo Statistiken
Self-hosted Matomo Analytics Dashboard (ana.lyse.io). Zeigt Website-Besucher-Statistiken, Content-Performance, Referrer-Quellen, Geraete-/Browser-Daten, Events und Echtzeit-Aktivitaet.
Features
| Feature | Beschreibung |
|---|---|
| KPI-Cards | Today/7d/30d: Visits, Actions, Bounce Rate, Avg. Time |
| Live-Counter | Echtzeit Visits und Actions (Matomo Live API) |
| Zeitraum-Tabs | today, last7, last30 mit Lazy-Loading |
| Top-Seiten | Meistbesuchte Seiten mit Clicks, Impressions, CTR |
| Top-Referrer | Direct, Search Engines, Social, Referral, Campaigns |
| Top-Laender | Geographische Besucher-Verteilung |
| Geraete/Browser | Desktop/Mobile/Tablet + Browser-Verteilung |
| Site Search | Suchbegriffe und No-Result-Searches |
| Echtzeit-Besucher | Letzte 15 Visits mit Details |
| Perioden-Vergleich | Aktuell vs. Vorperiode mit Delta-Prozenten |
| Trend-Charts | 30-Tage Visits und Geraete-Verteilung |
| Goals | Goal-Conversion-Tracking |
Datenquelle: Matomo Reporting API (gecacht)
Location: app/Livewire/Admin/MatomoStatistics/Index.php
Admin Open Graph
Route: /admin/open-graph
Title: Admin: Open Graph
OG-Image-Generierung und -Management fuer oeffentliche Profile. Ueberwacht Generierungs-Statistiken, Queue-Status und Job-Logs. Erlaubt Bulk-Generierung und Einzelprofil-Regenerierung.
Features
| Feature | Beschreibung |
|---|---|
| Generierungs-Stats | Total Profile, mit/ohne OG-Image, Coverage %, geschaetzte Speichergroesse |
| Plattform-Stats | YouTube/Instagram: Total, mit OG, ohne OG |
| Regenerierungs-Form | Plattform-Filter, Tier-Filter, Force-Regenerate Checkbox |
| Bulk-Dispatch | Job-Dispatch mit chunkById(100) Iteration |
| Job-Log-Tabelle | Paginierte Liste (50/Seite) mit Status (Success/Failed/Skipped), Profil, Timestamp |
| Log-Filter | Filter nach Status mit Count-Badges |
| Einzelprofil-Regenerierung | Button pro Profil fuer sofortige Regenerierung |
Location: app/Livewire/Admin/OpenGraph/Index.php
Admin SEO Dashboard
Route: /admin/seo-dashboard
Title: Admin: SEO Dashboard
Vereintes SEO-Monitoring mit Google Search Console Metriken, Core Web Vitals Daten und IndexNow-Submissions.
Tabs
| Tab | Beschreibung |
|---|---|
| GSC | Sync-Status, Top 20 Pages/Queries nach Clicks, KPI-Totals (Clicks, Impressions, CTR, Position). Manueller Sync-Trigger |
| Web Vitals | Current vs. Previous Period (LCP, FCP, INP, CLS, TTFB). Device Breakdown (Mobile/Desktop/Tablet). Page Type Breakdown. 5 Trend-Charts (7/14/30d). URL Drilldown fuer schlechteste Performance |
IndexNow-Integration
Enabled/Configured Status, Submission-Statistiken (Total, Success, Failed, letzte Submission).
Datenquelle: search_console_metrics, web_vitals_metrics, index_now_submissions
Location: app/Livewire/Admin/SeoDashboard/Index.php
Admin Sitemap Management
Route: /admin/sitemap-management
Title: Admin: Sitemap Management
XML-Sitemap-Generierung, -Validierung und -Monitoring. Trackt taegliche Snapshots mit Deltas, Health-Score und bietet manuelle Generierung mit Dry-Run.
Features
| Feature | Beschreibung |
|---|---|
| Heartbeat-Status | Letzter Generierungs-Zeitpunkt, ob heute gelaufen |
| Sitemap-Dateien | XML-Dateien mit Groesse und Validierungs-Ergebnissen |
| 14-Tage-History | Taegliche Snapshots: Total URLs, Static/Category/Tag/Profile URLs, Dateien, Groesse, Dauer |
| Health-Score (0–100) | 40% Validierungen + 30% Stabilitaet + 20% Vollstaendigkeit + 10% Geschwindigkeit |
| 14-Tage-Chart | Line-Chart: Total URLs und Profile URLs Trend |
| Manuelle Generierung | Synchroner Trigger mit Heartbeat-Recording |
| Dry-Run | Preview der URL-Counts ohne Dateien zu schreiben |
Datenquelle: sitemap_daily_snapshots, Storage-Dateien
Location: app/Livewire/Admin/SitemapManagement/Index.php
Admin Mark Video as Short
Trigger: Inline-Livewire-Component auf Video-Detail-Seiten (kein eigener Route)
Admin-only Toggle-Button zum manuellen Markieren/Entmarkieren von YouTube-Videos als Shorts (vs. Auto-Erkennung).
Features
| Feature | Beschreibung |
|---|---|
| Admin-Only Button | Kleiner "S"-Button, nur fuer Admins sichtbar |
| Toggle-State | Badge bei Markierung, kein Badge bei Entmarkierung |
| Mark as Short | Setzt is_short=true, is_short_marked_at=now() |
| Unmark | Setzt is_short=null, is_short_marked_at=null (zurueck zur Auto-Erkennung) |
| Toast-Feedback | Erfolgs-/Info-Toast bei Toggle |
Location: app/Livewire/Admin/MarkVideoAsShort.php