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, keinecomposer.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:checkgrü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 brauchennpx 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-cacheausführen.
Maximal-Lauf:
just allfährt zusätzlich Mutation-Testing, Coverage und Browser-Tests. Coverage/Mutation brauchen einen Treiber (Xdebug/PCOV) — Setup (inkl. Laravel Herd / Mac) incoverage-und-mutation-testing.md. Ohne Treiber überspringen die Rezepte diese Schritte sauber.
2. Deploy-Hinweise (was beim Ausrollen zu tun ist)
| Schritt | Nötig? | Begründung |
|---|---|---|
php artisan migrate | Nein | Keine Migrationen im Diff. |
.env anpassen | Nein | Keine neuen/geänderten env()-Variablen. |
npm run build / Assets | Nein | Keine Blade/JS/CSS-Änderungen. |
composer install | Ja (Standard) | Reiner PHP-Deploy; Autoload aktualisieren. |
php artisan optimize:clear | Empfohlen | Config-/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)
| Bereich | Was prüfen | Wie | Erwartung |
|---|---|---|---|
BackfillRotationBuckets (DB::raw(CASE) → incrementEach/Gruppierung) | rotation_bucket-Verteilung | php 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ähler | Watcher-Import über /watchers per URL anstoßen | processed_count/added_count/already_in_workspace_count/global_reused_count/failed_count werden korrekt hochgezählt. |
DiagnosePublishingHeatmap (interpoliertes SQL → gebundene ?-Parameter) | JSONB-Stunden-Extraktion | php artisan youtube:diagnose-heatmap --weekday=1 --hour=14 | Liste der Top-Contributors + verdächtige Profile (≥50 Videos) wird angezeigt. |
3.2 Recalc-Jobs (Counter-Map jetzt mapWithKeys → array<int,int>)
| Bereich | Wie | Erwartung |
|---|---|---|
RecalculateRelatedChannelScores (YouTube) | Related-Channels eines Profils neu berechnen lassen (Job dispatchen) | Related-Scores plausibel, Follower/Subscriber-Counts korrekt zugeordnet. |
RecalculateRelatedInstagramScores | analog für Instagram | dito. |
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):
| Aktion | Route/Trigger | Erwartung |
|---|---|---|
| Watcher löschen | DeleteWatcherController | Watcher weg; bei Favoriten-Workspace auch Favoriten-Marker entfernt. |
| YouTube-Video-Auto-Sync aktivieren | EnableYouTubeVideoAutoSyncController | Sync-Eintrag mit requested_by = <user-id>. |
| Video-Stats anfordern | RequestYouTubeVideoStatsController | Sync-Request angelegt. |
3.6 Circuit-Breaker-Anzeige (getCircuitBreakerInfo-Shape neu gebaut)
/admin/youtube-managementund/admin/google-api-usage: Circuit-Breaker-Status-Box.- Erwartung: „Daily Quota" / „Rate Limit"-Label +
opened_atkorrekt (Konsumenten nutzen ausschließlich diese beiden Keys — verifiziert).
3.7 Mail (Locale-/Betreff-Narrowing)
| Trigger | Erwartung | |
|---|---|---|
NewsletterConfirmation | Newsletter-Double-Opt-In auslösen | Locale = User-Sprache; Mail kommt an. |
NewUserRegistered | Neuen User registrieren | Admin-Benachrichtigung an erste Admin-Mail (String-validiert). |
AdminTestMail | Admin-Test-Mail senden | Absender-Adresse/Name korrekt. |
ErrorMonitorWeeklyReport | php artisan error-monitor:weekly-report | Betreff „… 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-Dimension | Status | Begründung |
|---|---|---|
| a11y / SEO / Responsive | N/A | Keine Blade/View/Asset-Änderung. |
| DB-Schema / Migrationen | N/A | Keine Migration im Diff; geschützte Tabelle social_profile_daily_metrics nur gelesen, nie verändert. |
| Dependencies (CVE) | N/A | composer.json/package.json unverändert. |
| Scheduled-Command-Monitoring | N/A | Keine neuen Commands; bestehende nur typisiert. |
| Security | verbessert | 2 DB::raw()-Stellen durch Bordmittel (incrementEach / gebundene Parameter) ersetzt; mehrere literal-string-Härtungen. Keine neuen Input-/Output-Sinks. |
5. Post-Deploy-Monitoring
- Application-Log auf
TypeError/Errornach Deploy beobachten. Hinweis: Dieis_numeric/is_scalar-Verengungen werfen bei unerwartetenmixed-Werten keine Exception — sie fallen auf einen Default zurück. Auffällige Default-Werte (z. B. dauerhaft0-Counts) wären ein Indikator für eine Fehlannahme und sollten geprüft werden. - Scheduled Commands (Cron) im Admin-Monitoring beobachten: laufen alle grün durch?
- Admin-Dashboards (YouTube-Management, Google-API-Usage, DB-Monitoring) auf plausible Zahlen prüfen.
6. Schnell-Checkliste
-
composer lint:checkgrün (inkl. 0 Baseline-Einträge) -
php artisan testgrü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 inresources/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.phpbindettests/Browserdaran. Feature/Unit bleiben beiwithoutVite().tests/Browser/ScoreChartRangeBrowserTestvervollständigt (Login + Workspace/Watcher/WatcherSource, korrekte/watcher/{watcher}-Route).resources/js/echo.jsinstanziiertwindow.Echojetzt nur noch hinter dem Guardif (import.meta.env.MODE !== 'browsertest' && import.meta.env.VITE_REVERB_HOST).just allbaut die Browser-Test-Assets mitnpm run build -- --mode browsertest— die Dead-Code-Elimination entfernt dadurch dennew Echo(...)-Block, sodasspusher-jsohne laufenden Reverb-Server nicht endlos reconnectet (vorher: Seite nienetworkidle→ ~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 browsertestlässt dennew Echo(...)-Aufruf aus dem Bundle fallen (auch bei gesetztemVITE_REVERB_HOST), der Standard-Build behält ihn samt Host. FälltVITE_REVERB_HOSTin Produktion, wird Echo bewusst nicht erzeugt (statt endlos zu reconnecten) — Reverb-Config prüfen.