Zum Hauptinhalt springen

Watchers/Index

Watcher-Liste eines Workspaces mit Multi-Import, Suche, Filtern, Sortierung und Bulk-Operationen.

Route: /watchers, /workspace/{workspace} View: resources/views/livewire/watchers/index.blade.php Location: app/Livewire/Watchers/Index.php

Public Properties

PropertyTypDefaultQuery StringBeschreibung
$qstring''jaSuchbegriff (Name, Handle, mit Trigram-Fuzzy auf PostgreSQL)
$platformstring''jaPlattform-Filter: '', 'youtube', 'instagram'
$sortstring'score_desc'jaSortierung (siehe Sortier-Optionen). Admin-Workspace: 'created_desc'
$favoritesFilterstring'all'ja'all' oder 'favorites'
$relatedFilterstring''ja'', 'with', 'without' (nur Admin-Workspace)
$verifiedFilterstring''ja'', 'verified', 'unverified'
$perPageint25neinEintraege pro Seite
$pageint1jaAktuelle Seite
$multiImportTextstring''neinTextarea-Inhalt fuer Multi-Import
$multiImportOpenboolfalseneinMulti-Import Modal offen
$multiImportCsvarray[]neinHochgeladene CSV-Dateien
$importRunIdint|nullnullneinAktive Import-Run ID
$selectedWatcherIdsarray[]neinAusgewaehlte Watcher fuer Bulk-Ops
$selectAllWatchersboolfalseneinSelect-All Checkbox State
$moveWorkspaceIdint|nullnullneinZiel-Workspace fuer Verschieben
$deletingWatcherIdint|nullnullneinWatcher-ID fuer Loeschen-Bestaetigung
$showWorkspaceEditModalboolfalseneinWorkspace-Bearbeitung Modal

Sortier-Optionen

WertBeschreibung
name_asc / name_descAlphabetisch nach Name
followers_desc / followers_ascNach Follower-Anzahl
views_desc / views_ascNach View-Anzahl
videos_desc / videos_ascNach Video-Anzahl
following_desc / following_ascNach Following-Anzahl
posts_desc / posts_ascNach Post-Anzahl
score_desc / score_ascNach Postbox Score
created_desc / created_ascNach Erstellungsdatum

Sortierung nutzt Subqueries auf SocialProfileDailyMetric und SocialProfileScore fuer performante Sortierung ohne JOINs.

Default-Sort: score_desc fuer normale Workspaces, created_desc fuer den Admin-Workspace (ID 999999999999). Die Umschaltung passiert in mount() und wird nur angewendet, wenn kein expliziter ?sort=-Parameter in der URL steht.

Performance-Analyse der Sortier-Varianten

Die render()-Methode haengt 18 korrelierte Subqueries im addSelect() an die Watcher-Query. Diese Subqueries holen fuer jede Row die aktuellen Metriken, Score-Werte und Profil-Daten. Das Verhalten dieser Subqueries haengt entscheidend vom gewahlten Sort ab.

Warum created_desc der schnellste Sort ist

created_desc sortiert mit ORDER BY id DESC — PostgreSQL kann hier den PK-Index rueckwaerts scannen, nach workspace_id filtern und nach dem LIMIT (z.B. 25) sofort stoppen. Die 18 SELECT-Subqueries werden nur fuer die ~25 Seiten-Rows ausgewertet. Alle anderen Sorts erfordern ein berechnetes Feld im ORDER BY, was PostgreSQL zwingt alle Watcher des Workspace zu evaluieren, bevor das LIMIT greifen kann.

Geschaetzte Response-Zeiten

Sort-Variante1.000 Watcher10.000 WatcherStrategie
created_desc / created_asc~15–30 ms~20–40 msPK-Index, Early-Stop
followers_desc / views_desc~300–500 ms~3–6 sFull-Scan, Metriken-Subquery im ORDER BY
name_asc / name_desc~250–450 ms~2.5–5 sFull-Scan, kein Index auf name
score_desc / score_asc~350–600 ms~3.5–7 sFull-Scan, 2-Level Sort (Priority + Score)

Kostentreiber

FaktorAuswirkung
18 korrelierte Subqueries~1 ms pro Row (Index-Seeks auf social_profile_daily_metrics, social_profile_scores)
Full-Scan bei non-PK SortAlle N Rows muessen evaluiert werden, LIMIT greift erst nach Sort
score_sort_priorityZusaetzliche Subquery mit CASE-Ausdruck auf social_profiles
Trigram-Suche (pg_trgm)+20–50% wenn Suchterm gesetzt, unabhaengig vom Sort

Admin-Workspace Optimierung

Der Admin-Workspace spiegelt alle ~40.000+ Social Profiles. Bei score_desc als Default wuerden pro Seitenaufruf ~40.000 × 19 Subqueries evaluiert, was Response-Zeiten von 10+ Sekunden verursacht. Mit created_desc als Default nutzt der Admin-Workspace den PK-Index und laed in ~30 ms. Admins koennen weiterhin per Dropdown auf jede andere Sortierung wechseln.

Location: app/Livewire/Watchers/Index.phpmount() (Default-Override), applySorting() (Sort-Logik)

Actions

MethodParameterBeschreibung
submitMultiImport()--Multi-Import starten (Text + CSV)
openMultiImport()--Import-Modal oeffnen
closeMultiImport()--Import-Modal schliessen
confirmDelete(int $id)Watcher-IDLoeschen-Bestaetigung oeffnen
delete()--Watcher loeschen (Sources + Watcher, Profil bleibt)
moveSelectedWatchers()--Ausgewaehlte Watcher in Ziel-Workspace verschieben
resetFilters()--Alle Filter zuruecksetzen
dismissImportReport()--Import-Report-Banner ausblenden
openWorkspaceEdit()--Workspace-Bearbeitung oeffnen
saveWorkspaceEdit()--Workspace-Name/Beschreibung speichern

Multi-Import

Der Import unterstuetzt mehrere Eingabewege:

  1. Textarea: URLs zeilenweise eingeben (max. 10.000 Zeilen, 750KB)
  2. CSV-Upload: Eine oder mehrere CSV-Dateien mit URLs in beliebigen Spalten
  3. Kombination: Textarea + CSV gleichzeitig

Ablauf:

URLs eingeben/hochladen
→ parseMultiImportLines() erkennt YouTube/Instagram via Parser
→ Deduplizierung innerhalb des Inputs
→ WatcherImportRun + WatcherImportItems erstellen
→ ImportWatcherFromUrl Jobs dispatchen (YouTube: imports-youtube-priority)
→ CollectorJobDispatcher fuer Instagram
→ Import-Report Banner anzeigen

Geschuetzte Workspaces (Favoriten, Admin) blockieren den Import mit Fehlermeldung.

Events

RichtungEventBeschreibung
dispatchshow-toastErfolgs-/Fehlermeldungen
dispatchworkspaces-updatedNach Workspace-Umbenennung
listen.import.progressWatcherImportProgress via Reverb

Suche

Die Suche nutzt ILIKE auf Watcher-Name und Profil-Handle. Auf PostgreSQL mit pg_trgm-Extension wird zusaetzlich Fuzzy-Matching via similarity() mit Threshold 0.3 aktiviert. SQLite-Fallback nutzt nur ILIKE.

Render-Logik

Die render()-Methode baut eine komplexe Query mit Subqueries fuer alle metrischen Felder (followers, views, videos, following, posts, score) und den Primary-Profile-Daten. Das vermeidet N+1-Queries und ermoeglicht serverseitige Sortierung ueber berechnete Spalten.