# Abgeschlossene Monate sind eingefroren Entscheidung der Kundin vom 10.09.2026, umgesetzt am selben Tag. Dieses Dokument hält fest, **warum** die Statistik so arbeitet, **was genau** eingefroren wird und **was das nicht kann**. Es löst die August-Entscheidung F7 („Abo-Bestände tagesaktuell") ab. Der Bezug zu den Audit-Befunden A04 und A12 steht in [Abschnitt 13 der Bewertung](audit-statistiken-2026-09-09-bewertung.md). ## 1. Die Regel > Am ersten Tag des Folgemonats läuft die Monatsabrechnung: Provisionen werden berechnet, > Gutschriften ausgestellt, der Monat ist kaufmännisch abgeschlossen. Ab diesem Punkt ändert sich an > diesem Monat nichts mehr — weder durch Stornos noch durch Änderungen an der Team-Struktur. Die Regel gilt damit an zwei Stellen, die vorher unabhängig voneinander gedacht waren: | Bereich | Regel | | --- | --- | | Buchungen/Stornos | Ein Storno mindert nur den Monat, in dem die Ursprungsbestellung liegt. Ist der Monat abgeschlossen, passiert nichts mehr ([Details](audit-statistiken-2026-09-09-bewertung.md#8-nachtrag-09092026--stornoregel-entschieden-und-umgesetzt)). | | Statistik/Struktur | Ein abgeschlossener Monat wird nicht mehr aus heutigen Daten gerechnet, sondern aus dem gespeicherten Monatsstand. | ## 2. Warum die Struktur der eigentliche Grund ist Die Team-Struktur ist beweglich: Teampartner kommen dazu, wechseln den Sponsor, fallen weg. Wird ein vergangener Monat weiter live gerechnet, verschiebt sich seine Auswertung mit jeder solchen Änderung. Eine Beraterin sähe dann im Oktober für den August andere Zahlen als in der Abrechnung, die sie für den August bekommen hat — und die Ursache wäre von außen nicht erkennbar. Genau das war der Auslöser für die Entscheidung. ## 3. Was eingefroren wird Der Snapshot **ist** der abgeschlossene Monat. Er enthält: - Punkte und Umsätze je Linie und in Summe - Abo-Bestände, Neupartner, „+N neu" - Führungskräfte-, Recruiter- und Top-10-Listen - **die Mitglieder je Linie** (`lines[].user_ids`) - **die Abos je Linie** (`lines[].abo_ids`, getrennt nach Team-/Kundenabos und jeweils „neu") Die letzten beiden Punkte sind neu (Payload-Version 2). Aus ihnen baut `BackofficeDrilldownService` die Detaillisten: Klickt man auf eine Zahl eines abgeschlossenen Monats, zeigt die Liste genau die Mitglieder und Abos, aus denen diese Zahl entstanden ist — auch wenn ein Abo inzwischen gekündigt oder gelöscht wurde (`withTrashed()`). **Bewusst nicht eingefroren:** Stammdaten wie Name, E-Mail oder Karrierestufe. Sie werden zur Anzeigezeit gelesen. Eine Umbenennung soll rückwirkend sichtbar sein, eine Strukturänderung nicht. ## 4. Was das nicht kann **Für Monate, die vor dem 10.09.2026 abgeschlossen wurden, gibt es keine echte historische Struktur.** Frühere Sponsor-Zuordnungen werden nirgends historisiert. Der Rebuild dieser Monate friert deshalb die Struktur des **Ausführungstags** ein, nicht die des damaligen Monatsendes. Das war die bewusste Abwägung: Einheitlichkeit über alle Monate war wichtiger als die Rekonstruktion einer Struktur, die es nicht mehr gibt. Ab dem Monatsabschluss 01.10.2026 ist der eingefrorene Stand dann der tatsächliche Monatsstand. **Das Home-Dashboard** friert für normale Berater nicht ein — Snapshots gibt es nur für die VIP-Konten (`admin` 1–3). Wer das auch für alle Berater will, braucht Snapshots für alle Konten; das ist eine eigene Entscheidung (Menge, Laufzeit, Speicher). ## 5. Betrieb ```bash # Laeuft naechtlich; legt fehlende Snapshots fuer abgeschlossene Monate an php artisan backoffice:store-statistics-snapshots # Nur bei einem Schemawechsel des Payloads: baut vorhandene Snapshots neu. # ACHTUNG: friert die Struktur des Ausfuehrungstags ein (siehe Abschnitt 4). php artisan backoffice:store-statistics-snapshots --force ``` Beim Wechsel auf Payload-Version 2 wurde `--force` einmalig ausgeführt. Snapshots mit Payload-Version 1 bleiben lesbar; ihre Detaillisten fallen auf die Live-Auswertung zurück, statt eine Genauigkeit vorzutäuschen, die sie nicht haben. ## 6. Wo es im Code steht | Datei | Rolle | | --- | --- | | `app/Services/Backoffice/BackofficeDashboardService.php` | Klassenkommentar mit der fachlichen Begründung; `PAYLOAD_VERSION`; `buildLineRow()` schreibt `user_ids` und `abo_ids` | | `app/Services/Backoffice/BackofficeDrilldownService.php` | `frozenLines()`, `frozenUserIds()`, `frozenAboIds()`, `aboScope()` | | `app/Console/Commands/BackofficeStoreStatisticsSnapshots.php` | Warnung zu `--force` | | `app/Services/BusinessPlan/SalesPointsVolume.php` | dieselbe Regel auf der Buchungsseite (`isStornoMonthOpen()`) | | `tests/Feature/BackofficeSnapshotFreezeTest.php` | Regressionen zum Einfrieren | Die beiden Tests in `BackofficeStatisticsListsTest.php`, die vorher die alte Regel („Abo-Bestände tagesaktuell", August-Entscheidung F7) festhielten, beschreiben jetzt die neue. Sie wurden umgeschrieben, nicht entfernt — die Szenarien bleiben abgedeckt.