Zum Hauptinhalt springen

Testplan & Verifikation: v2.1.x — Larastan-Baseline-Cleanup

Zweck: Diese Datei listet auf, wie du alle Änderungen des v2.1.x-Branches (Larastan-Baseline 4.009 → 0) testen und sicherstellen kannst, dass alles Geänderte und seine Auswirkungen noch funktioniert.

Stand: 2026-06-15 · Commits 8e529d2e..d221bb64 (28 Chargen) · Deep-Audit grün.


0. TL;DR — Risikoprofil

  • 137 Dateien geändert: 134 PHP, 2 Markdown (Doku/Changelog), 1 phpstan-baseline.neon.
  • NICHT angefasst: keine Blade/Views, kein JS/CSS, keine Migrationen, keine .env, keine composer.json/package.json (keine Dependency-Änderungen).
  • Inhalt: reine Typ-Annotationen + Typ-Verengung (is_numeric/is_scalar/is_string/is_array)
    • eine Handvoll verhaltens-äquivalenter Refactorings (siehe §3).
  • Die Verengungen werfen bei unerwarteten mixed-Werten keine Exception, sondern fallen auf einen Default zurück (z. B. 0, '', null) — das ist bewusst robuster als vorher.
  • Deep-Audit-Ergebnis: composer lint:check grün (Rector/Pint/PHPStan L10, 0 Baseline-Einträge), 3.466 Tests grün (13.706 Assertions), alle verhaltens-relevanten Änderungen verifiziert.

1. Automatische Verifikation (PFLICHT — die Hauptabsicherung)

Das ist das primäre Sicherheitsnetz. Beide Befehle müssen grün sein:

# 1. Statik: Rector (Dry-Run) + Pint (Test) + PHPStan Level 10
composer lint:check
# Erwartung: Rector "[OK]", Pint "passed", PHPStan "[OK] No errors"
# WICHTIG: phpstan-baseline.neon enthält jetzt nur noch `ignoreErrors: []`.
# Jeder NEUE Type-Fehler schlägt ab sofort sofort fehl (kein Baseline-Puffer mehr).

# 2. Komplette Testsuite (PostgreSQL, nicht nur affected)
php artisan test
# Erwartung: ~3.466 Tests grün, 0 Fehler.

Hinweis Browser-Tests: tests/Browser/* (Pest v4 / Playwright) sind nicht Teil der Standard-php artisan test-Suite und brauchen npx playwright install. Der Baseline-Cleanup selbst berührt kein Frontend — die Browser-Test-Infrastruktur (BrowserTestCase, aktives Vite, echo.js-Guard) wurde aber auf demselben Branch repariert; deren Verifikation steht separat in §7.

Hinweis Cold-Cache: Für eine 100 % autoritative PHPStan-Prüfung vorher vendor/bin/phpstan clear-result-cache ausführen.

Maximal-Lauf: just all fährt zusätzlich Mutation-Testing, Coverage und Browser-Tests. Coverage/Mutation brauchen einen Treiber (Xdebug/PCOV) — Setup (inkl. Laravel Herd / Mac) in coverage-und-mutation-testing.md. Ohne Treiber überspringen die Rezepte diese Schritte sauber.


2. Deploy-Hinweise (was beim Ausrollen zu tun ist)

SchrittNötig?Begründung
php artisan migrateNeinKeine Migrationen im Diff.
.env anpassenNeinKeine neuen/geänderten env()-Variablen.
npm run build / AssetsNeinKeine Blade/JS/CSS-Änderungen.
composer installJa (Standard)Reiner PHP-Deploy; Autoload aktualisieren.
php artisan optimize:clearEmpfohlenConfig-/Route-/View-Cache nach Deploy leeren.

Reiner Code-Deploy ohne Schema- oder Config-Migration.


3. Manuelle Smoke-Tests (verhaltens-relevante Änderungen)

Diese Änderungen sind per Test abgedeckt und grün, aber hier zum bewussten Nachprüfen in Staging/Production. Reihenfolge nach abnehmendem Risiko.

3.1 Bulk-Update-Refactorings (DB-Schreibpfad geändert, Ergebnis identisch)

BereichWas prüfenWieErwartung
BackfillRotationBuckets (DB::raw(CASE)incrementEach/Gruppierung)rotation_bucket-Verteilungphp artisan profiles:backfill-rotation-buckets (ggf. erst auf Kopie)Buckets gleichmäßig verteilt, identisch zu vorher; Test BackfillRotationBucketsTest deckt das ab.
ImportWatcherFromUrl (DB::raw('col + n')incrementEach)Import-ZählerWatcher-Import über /watchers per URL anstoßenprocessed_count/added_count/already_in_workspace_count/global_reused_count/failed_count werden korrekt hochgezählt.
DiagnosePublishingHeatmap (interpoliertes SQL → gebundene ?-Parameter)JSONB-Stunden-Extraktionphp artisan youtube:diagnose-heatmap --weekday=1 --hour=14Liste der Top-Contributors + verdächtige Profile (≥50 Videos) wird angezeigt.

3.2 Recalc-Jobs (Counter-Map jetzt mapWithKeysarray<int,int>)

BereichWieErwartung
RecalculateRelatedChannelScores (YouTube)Related-Channels eines Profils neu berechnen lassen (Job dispatchen)Related-Scores plausibel, Follower/Subscriber-Counts korrekt zugeordnet.
RecalculateRelatedInstagramScoresanalog für Instagramdito.

3.3 Admin-Livewire-Seiten (render()-Rückgabetyp : View ergänzt)

Reiner Annotations-Change — Seiten müssen fehlerfrei laden. Schnell durchklicken:

  • /admin/api-management · /admin/pages · /admin/reverb-test · /admin/open-graph
  • /admin/related-channels · /admin/social-profiles · /admin/import-status
  • /admin/log-queue (Queue-Status) · /admin/rustfs-monitoring · /admin/update-status

Erwartung: alle rendern wie zuvor, keine 500er.

3.4 Explore / Public-Frontend (Trait HasSnapshotData, WithWorkspaceSelection, Show)

  • /explore · /explore/browse · /explore/trending-videos · Kategorie-Cloud
  • Profil-Detailseite (PublicExplorer/Show) — Verlaufs-Chart-Werte
  • Dashboard + Tops/Flops (gemeinsamer HasSnapshotData-Trait)
  • Workspace-Switcher (Sidebar): listet Workspaces, Favoriten zuerst — auch als Gast (leere Liste, kein Fehler).
  • „Profil zu Workspace hinzufügen"-Button in Explore (Trait WithWorkspaceSelection): Hinzufügen/„Ansehen"-Umschaltung funktioniert.

3.5 Watcher-Controller (auth()->user()-Null-Guard + abort(403))

Als eingeloggter User testen (Guards greifen nur, wenn user() null wäre — bei Auth-Routen nie):

AktionRoute/TriggerErwartung
Watcher löschenDeleteWatcherControllerWatcher weg; bei Favoriten-Workspace auch Favoriten-Marker entfernt.
YouTube-Video-Auto-Sync aktivierenEnableYouTubeVideoAutoSyncControllerSync-Eintrag mit requested_by = <user-id>.
Video-Stats anfordernRequestYouTubeVideoStatsControllerSync-Request angelegt.

3.6 Circuit-Breaker-Anzeige (getCircuitBreakerInfo-Shape neu gebaut)

  • /admin/youtube-management und /admin/google-api-usage: Circuit-Breaker-Status-Box.
  • Erwartung: „Daily Quota" / „Rate Limit"-Label + opened_at korrekt (Konsumenten nutzen ausschließlich diese beiden Keys — verifiziert).

3.7 Mail (Locale-/Betreff-Narrowing)

MailTriggerErwartung
NewsletterConfirmationNewsletter-Double-Opt-In auslösenLocale = User-Sprache; Mail kommt an.
NewUserRegisteredNeuen User registrierenAdmin-Benachrichtigung an erste Admin-Mail (String-validiert).
AdminTestMailAdmin-Test-Mail sendenAbsender-Adresse/Name korrekt.
ErrorMonitorWeeklyReportphp artisan error-monitor:weekly-reportBetreff „… KW <Nummer>" korrekt gefüllt.

3.8 Prune-/Diagnose-Commands (delete()-Rückgabe jetzt is_int-verengt)

Jeweils der angezeigte Lösch-Zähler muss stimmen:

php artisan youtube:prune-inactive-video-metrics   # Triple-Lock-Schutz beachten
php artisan youtube:prune-inactive-video-records
php artisan error-monitor:prune
# + Collector-Logs-Prune, AI-Detection-Logs-Prune

3.9 Score-/Snapshot-Pipeline (data_source_date?->toDateString())

php artisan profiles:calculate-scores      # CalculateProfileScores
php artisan youtube:calculate-video-scores # CalculateVideoScores
# + Pipeline-Step CalculateProfileMetricsBatch

Erwartung: data_source_date korrekt gesetzt; bei fehlendem Datum null statt Crash.


4. Was NICHT erneut getestet werden muss (und warum)

Audit-DimensionStatusBegründung
a11y / SEO / ResponsiveN/AKeine Blade/View/Asset-Änderung.
DB-Schema / MigrationenN/AKeine Migration im Diff; geschützte Tabelle social_profile_daily_metrics nur gelesen, nie verändert.
Dependencies (CVE)N/Acomposer.json/package.json unverändert.
Scheduled-Command-MonitoringN/AKeine neuen Commands; bestehende nur typisiert.
Securityverbessert2 DB::raw()-Stellen durch Bordmittel (incrementEach / gebundene Parameter) ersetzt; mehrere literal-string-Härtungen. Keine neuen Input-/Output-Sinks.

5. Post-Deploy-Monitoring

  1. Application-Log auf TypeError/Error nach Deploy beobachten. Hinweis: Die is_numeric/is_scalar-Verengungen werfen bei unerwarteten mixed-Werten keine Exception — sie fallen auf einen Default zurück. Auffällige Default-Werte (z. B. dauerhaft 0-Counts) wären ein Indikator für eine Fehlannahme und sollten geprüft werden.
  2. Scheduled Commands (Cron) im Admin-Monitoring beobachten: laufen alle grün durch?
  3. Admin-Dashboards (YouTube-Management, Google-API-Usage, DB-Monitoring) auf plausible Zahlen prüfen.

6. Schnell-Checkliste

  • composer lint:check grün (inkl. 0 Baseline-Einträge)
  • php artisan test grün (~3.466)
  • Admin-Seiten laden (§3.3) ohne 500er
  • Explore + Workspace-Switcher (§3.4) ok
  • Watcher-Aktionen (§3.5) als eingeloggter User ok
  • Circuit-Breaker-Anzeige (§3.6) korrekt
  • Ein Bulk-Command (§3.1) auf Kopie/Staging verifiziert
  • Post-Deploy-Logs (§5) eine Stunde beobachtet

7. Browser-Test-Infrastruktur (separat vom Baseline-Cleanup)

Auf demselben Branch wurde die Pest-v4-Browser-Test-Infrastruktur repariert. Kein Produktions-Verhalten ändert sich — betroffen sind nur Test-Setup, das just all-Rezept und ein produktions-transparenter Guard in resources/js/echo.js.

Was sich geändert hat:

  • tests/BrowserTestCase (neu) lässt Vite aktiv (shouldDisableVite()false), damit der echte Frontend-Stack (app.js/Alpine/ApexCharts) im Chromium lädt; tests/Pest.php bindet tests/Browser daran. Feature/Unit bleiben bei withoutVite().
  • tests/Browser/ScoreChartRangeBrowserTest vervollständigt (Login + Workspace/Watcher/WatcherSource, korrekte /watcher/{watcher}-Route).
  • resources/js/echo.js instanziiert window.Echo jetzt nur noch hinter dem Guard if (import.meta.env.MODE !== 'browsertest' && import.meta.env.VITE_REVERB_HOST).
  • just all baut die Browser-Test-Assets mit npm run build -- --mode browsertest — die Dead-Code-Elimination entfernt dadurch den new Echo(...)-Block, sodass pusher-js ohne laufenden Reverb-Server nicht endlos reconnectet (vorher: Seite nie networkidle → ~800 s Timeout).

Verifikation (Mac / Laravel Herd — Playwright nötig):

# einmalig: Playwright-Treiber + Browser
npm install --no-save playwright@latest && npx playwright install

# Browser-Test-Assets bauen (OHNE Echo/Reverb) + Browser-Tests fahren
rm -f public/hot
npm run build -- --mode browsertest
php artisan test --testsuite=Browser
# Erwartung: grün UND schnell (wenige Sekunden statt ~13 Min).

# bequem: alles in einem
just all

Produktions-Sicherheit (Echo bleibt in echten Builds erhalten):

# normaler Build -> Echo/Reverb voll aktiv (nur mit gesetztem VITE_REVERB_HOST)
npm run build
  • Nach einem normalen npm run build (oder Deploy) müssen Live-Updates weiter funktionieren: Notification-Center-Toasts, Admin → Tages-Pipeline-Status („Live-Updates via WebSocket"), Admin → Reverb-Test (Verbindungsstatus „connected").
  • A/B-belegt: --mode browsertest lässt den new Echo(...)-Aufruf aus dem Bundle fallen (auch bei gesetztem VITE_REVERB_HOST), der Standard-Build behält ihn samt Host. Fällt VITE_REVERB_HOST in Produktion, wird Echo bewusst nicht erzeugt (statt endlos zu reconnecten) — Reverb-Config prüfen.