Statistiken: Review-Fixes vor Livegang (Fehldarstellungen + Test-Regression)
Ergebnis des Senior-Reviews über dev/2026-07-22 (Konzept 22.07., Feedback 24.07.,
Plan 19.08.). Rechnerisch war nichts zu korrigieren: Payline-Punkte und Provision
des Prognose-Blocks (N4) stimmen exakt mit der Provisions-Engine überein
(54.718,5 P. bzw. 3.772,88 EUR gegengerechnet an User 454). Behoben sind
Darstellungs- und Konsistenzfehler, die der Beraterin als falsche Zahlen
aufgefallen wären:
- "+N neu" schrumpfte rückwirkend, der Bestand daneben nicht: newAboCount() nutzte
weiter activeAbo(), während aboStockCount() auf das Monatsende zurückrechnet.
Beide teilen sich jetzt aboStockQuery(); die Jahres-Wachstumstabelle ebenso.
- Level-Kachel widersprach sich ("Zum nächsten Level Diamant fehlen X" über
"Karriere-Level: Diamant"): Text auf die Monats-Qualifikation umformuliert
(de/en/es/fr), Überschrift "Qualifikation in diesem Monat", Karriere-Level nur
noch bei Abweichung.
- Firstlines-Kachel zählte alle direkten Partner, "Teampartner gesamt" daneben nur
aktive (F1): Kachel nutzt jetzt isActiveConsultant(), die Detailseite listet
weiter alle und weist beide Zahlen aus.
- Neupartnerzahlen vergangener Monate sanken auf dem Home-Dashboard, sobald
Jahresgebühren ausliefen: neue User::newPartnerReferenceDate() (laufender Monat =
heute, abgeschlossener Monat = Monatsende). Dabei die drei Inline-Kopien der
Neupartner-Regel auf scopeNewPartnerIn()/isNewPartnerIn() zusammengeführt.
- Top-3-Karte ließ den Betrachter aus, obwohl "ich gehört in die Liste" in der
Juli-Runde für alle anderen Ranglisten umgesetzt wurde: zählt jetzt mit, inkl.
is_self und "ich"-Badge.
- Neues Profilfoto zeigte bis zu 6 h ein totes Bild: die URL steckt nicht mehr im
Cache, sondern entsteht beim Lesen (withProfileImages()).
- Test-Regression seit der Juli-Runde: Unit/Services/BackofficeDashboardServiceTest
fiel über die fehlende Spalte status_points (kam mit nonPaylinePoints() dazu).
- Kleinigkeiten: ProfileImageController gab die komplette Exception als
Flash-Message aus (jetzt Log + Sprachkey), BackofficeDrilldownService formatierte
Datumsangaben hart auf d.m.Y statt über Util::formatDateDB().
Tests: neuer HomeMonthlyStatsTest (buildMonthlyStats war ungetestet) plus Tests für
Stichtags-Zählung und Foto-Cache. Fünf Tests kodierten das alte Verhalten
(Betrachter zählt nicht mit, abgelaufener Account zählt nie) und wurden auf die
neue Semantik umgestellt, jeweils mit Gegenprobe. Suite: 861 grün (vorher 855),
89 rot — ausschließlich die in docs/2026-06-11-test-suite-vorbestehende-fehler.md
dokumentierten Altlasten.
Offen und bewusst nicht enthalten:
- Deploy-Schritt: backoffice:store-statistics-snapshots --force (vorher dumpen).
Kein vorhandener Snapshot enthält recruiter_ranking, Mai/Juni zusätzlich weder
non_payline_points noch die Führungskräfte-"gesamt"-Spalten; der Cron überspringt
vorhandene Snapshots ohne --force. Achtung: die Neuberechnung ist nicht
verlustfrei.
- TreeHtmlRendererTest/TreeCalcBotIntegrationTest: die Abo-Badges machten den
Renderer datenbankabhängig; die Dateien waren schon vorher rot und gehören in die
separate Test-Aufräumaufgabe.
- deleteImage bleibt ein GET-Route (gleiches Muster wie das Shop-Bild).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3f74f76819
commit
640a05945b
30 changed files with 338 additions and 133 deletions
|
|
@ -128,15 +128,19 @@ class HomeController extends Controller
|
|||
? app(PaylineForecastService::class)->levelAndCommissionForecast($user, $month, $year)
|
||||
: null;
|
||||
|
||||
$firstlineIds = User::firstlinesOf($user->id)
|
||||
->pluck('id')
|
||||
->map(fn ($id) => (int) $id)
|
||||
->all();
|
||||
|
||||
$dashboardService = app(BackofficeDashboardService::class);
|
||||
$teamOverview = app(TeamAboOverviewService::class);
|
||||
$paylineService = app(PaylineForecastService::class);
|
||||
|
||||
// Firstlines: die Neupartner-Zählung braucht alle direkten Partner (der
|
||||
// Scope filtert selbst), die Kachel zeigt aber nur aktive Berater —
|
||||
// sonst zählt sie anders als "Teampartner gesamt" daneben (F1).
|
||||
$firstlines = User::firstlinesOf($user->id)->get();
|
||||
$firstlineIds = $firstlines->pluck('id')->map(fn ($id) => (int) $id)->all();
|
||||
$activeFirstlineCount = $firstlines
|
||||
->filter(fn (User $member) => $dashboardService->isActiveConsultant($member))
|
||||
->count();
|
||||
|
||||
// Anzeige-Zählung konsistent zu "Teampartner gesamt" (F1: nur aktive
|
||||
// Berater) — die Payline-Mitgliedermenge selbst enthält auch inaktive,
|
||||
// deren Abos weiterhin in die Abo-/Punkte-Summen der Payline zählen.
|
||||
|
|
@ -159,7 +163,7 @@ class HomeController extends Controller
|
|||
'payline_forecast' => $paylineForecast,
|
||||
'commission' => app(LiveCommissionService::class)->commission($user, $month, $year),
|
||||
'direct_new_partners' => $dashboardService->newPartnersCount($firstlineIds, $month, $year),
|
||||
'firstline_count' => count($firstlineIds),
|
||||
'firstline_count' => $activeFirstlineCount,
|
||||
'team_partner_count' => count($activeTeamUserIds),
|
||||
'payline_member_count' => $activePaylineMemberCount,
|
||||
'payline_abo_count' => $paylineAboCount,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue