mivita/dev/2026-05-13-backoffice/ENTWICKLUNGSKONZEPT-BACKOFFICE.md

16 KiB

Entwicklungskonzept: Backoffice Dashboard & Interaktivität

Datum: 13.05.2026

Quelle: docs/salescenter/Todos Backoffice.md

Zielbild

Das Partner-Backoffice soll von einer statischen Monats-Kachelansicht zu einer klickbaren, linienbasierten Statistik ausgebaut werden. Führungskräfte sollen von der Gesamtübersicht über Linien und Generationen bis zu einzelnen Kunden, Partnern und Abos navigieren können.

Kernziel ist eine einheitliche Datenbasis für:

  • Dashboard-Kennzahlen pro Linie 1 bis 8 inklusive Summenzeile
  • Detailansichten je Linie, Firstline und Kennzahl
  • Kundenabos, Teamabos, Kundenabos im Team, Umsatz und Punkte
  • neue Spezial-Kennzahl "1000 Punkte Shop"
  • saubere Begrifflichkeit und rechtssichere Sichtbarkeit in Incentive-Ranglisten

Bestandsaufnahme im System

Dashboard

Aktueller Einstieg:

  • Route: GET /home
  • Controller: App\Http\Controllers\HomeController@show
  • View: resources/views/home.blade.php
  • Statistik-Partial: resources/views/dashboard/_statistics.blade.php

Die aktuelle Statistik wird direkt im Blade-Partial berechnet. Sie nutzt unter anderem:

  • App\Models\UserBusiness für gespeicherte Monatswerte und Payline-Punkte
  • App\Models\UserSalesVolume für Kunden-/Shop-Punkte
  • App\Models\UserAbo für eigene Abos, Kundenabos und Teamabos
  • rekursive Sponsor-Abfragen über users.m_sponsor

Bewertung:

  • Die vorhandene Ansicht ist ein guter Einstieg, aber fachlich zu grob.
  • Es gibt noch keine Linien 1 bis 8, keine Summenzeile und keine Drill-down-Routen.
  • Die Kennzahl "Kundenabos" vermischt aktuell eigene Abos und Kundenabos.
  • "Team-Abos" zählt aktuell Beraterabos im Team, aber nicht die separat geforderten Kundenabos im Team.

Team- und Abo-Bereich

Relevante Routen und Controller:

  • User\TeamController@structure für Strukturansicht
  • User\TeamController@show und datatableOptimized für Teamliste
  • User\TeamController@showAbos für Team-Beraterabos
  • User\TeamController@showTeamCustomerAbos für Kundenabos im Team
  • User\TeamController@detailAbo für Abo-Details

Relevante Daten:

  • UserAbo::is_for = 'me' bedeutet Berater-/Eigenabo
  • UserAbo::is_for = 'ot' bedeutet Kundenabo
  • UserAbo::user_id ist der Bestell-/Abo-User
  • UserAbo::member_id ist der zugeordnete Berater
  • UserAbo::next_date liefert die nächste Abo-Ausführung
  • UserAbo::getTotalPoints() berechnet Punkte aus Abo-Items und Produkten
  • AboHelper::getTeamUserIds() liefert Downline-User-IDs
  • AboHelper::getMonthlyAboCounts() kennt bereits die Scopes team_abos und team_cust_abos

Bewertung:

  • Viele Datenquellen für die geforderten Listen existieren bereits.
  • Die Logik ist aber auf mehrere Controller, Blades und Helper verteilt.
  • Für das neue Dashboard sollte die Logik zentralisiert werden, statt weitere Berechnungen in Blade-Dateien zu ergänzen.

Business- und Punkteberechnung

Relevante Bausteine:

  • App\Services\BusinessPlan\TreeCalcBotOptimized
  • App\Models\UserBusiness
  • App\Models\UserSalesVolume
  • App\Services\BusinessPlan\SalesPointsVolume

Bewertung:

  • Für Monats- und Teamwerte sollte bevorzugt auf gespeicherte Businessdaten zurückgegriffen werden.
  • Live-Berechnung über TreeCalcBot ist als Fallback sinnvoll, darf aber nicht bei jedem Seitenaufruf ungefiltert große Strukturen neu berechnen.
  • Die neue Drill-down-Logik benötigt klare Regeln, ob sie Live-Daten oder gespeicherte Monats-Snapshots zeigt.

Incentives

Relevante Dateien:

  • App\Http\Controllers\User\IncentiveController
  • resources/views/user/incentive/show.blade.php
  • App\Models\IncentiveParticipant
  • App\Services\Incentive\IncentiveTracker

Status:

  • Teilnahme-Opt-in existiert über accepted_terms_at.
  • Ranking wird aktuell mit paginate(100) angezeigt.
  • Nicht zustimmende Teilnehmer werden für normale User anonymisiert.
  • VIP-Ansicht sieht zusätzliche Hinweise zur Zustimmung.

Lücke zum Briefing:

  • Es gibt noch keine separate Zustimmung "Name/Fotos/Land in Rangliste sichtbar".
  • Foto und Land sind in der aktuellen Rangliste nicht als sichtbare Standardspalten umgesetzt.
  • Rechtliche Freigabe muss fachlich vor der technischen Umsetzung geklärt werden.

Checkout-Herkunft

Relevante Dateien:

  • App\Http\Controllers\Web\CheckoutController
  • App\Repositories\CheckoutRepository
  • App\Models\ShoppingUser

Status:

  • CheckoutController::validateCheckoutData() validiert Basisdaten, aber keine Pflichtfrage "Von wem hast du von Mivita erfahren?"
  • ShoppingUser nutzt is_from für den technischen Ursprung wie shopping, homeparty oder collection.
  • Ein fachliches Herkunfts-/Empfehlungsfeld existiert nicht als sauber getrennte Datenquelle.

Storno und Punkterückführung

Relevante Dateien:

  • App\Repositories\InvoiceRepository
  • App\Services\BusinessPlan\SalesPointsVolume
  • App\Services\Incentive\IncentiveTracker

Status:

  • Beim Erstellen einer Stornorechnung ruft InvoiceRepository::createCancellation() die Punktekorrektur auf.
  • SalesPointsVolume::cancelSalesPointsVolume() erstellt einen negativen UserSalesVolume-Eintrag mit Status 6.
  • Danach wird der Monat neu berechnet und IncentiveTracker::trackStorno() informiert.

Risiken:

  • Wenn zur Originalrechnung kein UserSalesVolume existiert, wird nur geloggt und keine Punktekorrektur erstellt.
  • Der negative Storno-Eintrag wird aktuell dem aktuellen Monat zugeordnet, nicht zwingend dem ursprünglichen Umsatzmonat.
  • Fachlich muss entschieden werden, ob Stornos im Stornomonat oder im Ursprungsmonat wirken sollen.

Fachliche Prüfung der To-dos

1. Überarbeitetes Dashboard & KPI-Übersicht

Umsetzung sinnvoll, aber nicht als Erweiterung des bestehenden Blade-Partials. Benötigt wird ein dedizierter Service, der die Kennzahlen pro Linie liefert.

Vorgeschlagene Tabelle Stufe 1:

  • Linie
  • Anzahl Berater
  • Umsatz gesamt
  • Eigen-/Beraterabos im Team
  • eigene Kundenabos
  • Kundenabos im Team
  • Neupartner
  • 1000 Punkte Shop
  • Summe

Wichtig:

  • "Teamkundenabos" sollte als Begriff für Kundenabos der Downline verwendet werden.
  • "Teamabos" sollte nur für Berater-/Eigenabos im Team verwendet werden.
  • Eigene Abos dürfen nicht in Kundenabos eingerechnet werden.

2. Interaktivität & Deep Dive

Umsetzung über eigene Backoffice-Statistik-Routen statt über große Modals im Dashboard.

Vorgeschlagene Stufen:

  • Stufe 1: Linienübersicht /user/backoffice/statistics
  • Stufe 2: Linien-/Firstline-Detail /user/backoffice/statistics/line/{line}
  • Stufe 3: Kennzahlenliste /user/backoffice/statistics/details?line=...&metric=...&user=...

Jede Zahl erhält einen Link auf eine gefilterte Detailansicht. Die Detailansicht sollte die Query-Parameter sichtbar halten, damit Support und Fachbereich Ergebnisse reproduzieren können.

3. Spezial-Kennzahl "1000 Punkte Shop"

Definition muss vor Umsetzung final geklärt werden.

Vorschlag für Version 1:

  • Zeitraum: gewählter Monat/Jahr des Dashboards
  • Personenkreis: Downline des eingeloggten Users
  • Schwelle: UserSalesVolume Shop-/KP-Summe pro Partner >= 1000 Punkte
  • Sortierung: Volumen absteigend
  • Detailspalten: Name, Account, Linie/Generation, Shop-Punkte, Gesamt-KP, Umsatz netto

Offene Fachfrage:

  • Meint "Kundenumsatz" nur Shop-Umsatz (month_shop_points) oder alle Kundenpunkte inklusive Abo-/Beraterkontext?

4. Bestellformular: "Von wem hast du von Mivita erfahren?"

Technisch sollte ein neues fachliches Feld eingeführt werden, nicht is_from zweckentfremdet werden.

Vorschlag:

  • Migration für shopping_users.referral_source_name oder ähnliches Feld
  • optional zusätzlich auf shopping_orders, wenn die Information revisionssicher pro Bestellung eingefroren werden soll
  • Pflichtvalidierung in CheckoutController::validateCheckoutData()
  • Anzeige im Checkout-Formular und optional im Admin-/Bestelldetail
  • später exportierbar für Marketingauswertung

Zu klären:

  • Freitext oder Auswahl plus Freitext?
  • Pflicht nur im Webshop/Bestelllink oder auch bei Salescenter-, Homeparty- und Collection-Flows?
  • Soll eine konkrete Beraterzuordnung daraus entstehen oder nur Tracking?

5. Stornoprozess

Die Grundlogik existiert. Vor einer fachlichen Freigabe braucht es Tests und eine Periodenentscheidung.

Prüfpunkte:

  • Storno einer Beraterbestellung erzeugt negative Punkte beim richtigen Berater.
  • Storno einer Kunden-/Shopbestellung erzeugt negative Punkte im richtigen Umsatztyp.
  • Storno einer Abo-Bestellung wirkt korrekt auf Incentive-Logs.
  • Storno ohne vorhandenen UserSalesVolume ist sichtbar und lösbar, nicht nur ein Log-Eintrag.
  • Businessdaten nach Storno werden für betroffenen Monat/Jahr aktualisiert oder als neu zu berechnen markiert.

6. Rechtliches & Sichtbarkeit in Incentives

Die bestehende Teilnahmezustimmung sollte nicht automatisch als Freigabe für öffentliche Namens-/Fotoanzeige interpretiert werden.

Vorschlag:

  • eigenes Feld auf incentive_participants, z. B. ranking_visibility_accepted_at
  • Button/Checkbox in der Incentive-Seite: "Ich stimme zu, dass mein Name, Foto und Land in der Rangliste sichtbar sind"
  • Anzeige von Name, Foto und Land nur, wenn die Zustimmung vorliegt oder ein Admin/VIP die Ansicht nutzt
  • nach juristischer Klärung kann die Regel angepasst werden

Technische Ergänzungen:

  • Ranking um Foto und Land erweitern
  • Pagination/Limit bewusst definieren: alle Teilnehmer anzeigen, aber paginiert
  • Übersetzungen in resources/lang/*/incentive.php ergänzen

7. Multimedia-Bereich / Event-Archiv

Es gibt bereits Dashboard-News und ein News-Archiv. Für Events sind zwei Varianten möglich:

Variante A: DashboardNews um Typ "event" erweitern

  • weniger Aufwand
  • bestehendes Admin-Modul kann wiederverwendet werden
  • geeignet, wenn Events im gleichen Format wie News funktionieren

Variante B: eigenes Event-Modul

  • sauberere Trennung
  • eigene Felder für Galerie, Eventdatum, Call-/Foto-Typ
  • sinnvoll, wenn Uploads, mehrere Bilder pro Event oder Kategorien benötigt werden

Empfehlung: Variante A als MVP, falls keine komplexe Galerieverwaltung benötigt wird.

Technisches Zielkonzept

Neue zentrale Services

Empfohlen:

  • App\Services\Backoffice\BackofficeDashboardService
  • App\Services\Backoffice\BackofficeDrilldownService

Aufgaben BackofficeDashboardService:

  • Zeitraum normalisieren
  • Downline pro Linie aufbauen
  • Summen pro Linie berechnen
  • Daten für Stufe 1 und Stufe 2 liefern
  • Caching-/Snapshot-Strategie kapseln

Aufgaben BackofficeDrilldownService:

  • Kennzahlenfilter aus Request validieren
  • Personen-/Abo-/Umsatzlisten erzeugen
  • Berechtigungen gegen Downline prüfen
  • einheitliche Summary für Listen liefern

Controller und Views

Empfohlen:

  • App\Http\Controllers\User\BackofficeStatisticsController
  • Views unter resources/views/user/backoffice/statistics/

Geplante Actions:

  • index() für Stufe 1
  • line(int $line) für Stufe 2
  • details() für Stufe 3
  • optional export() für CSV/Excel später

Die vorhandenen Team-Views bleiben bestehen. Das neue Dashboard verweist für Detailseiten aber auf eigene, schlankere Statistik-Views.

Datenmodell und Definitionen

Einheitliche Metriken:

  • consultants: aktive Berater in Linie
  • own_abos: eigene Beraterabos des eingeloggten Users
  • team_partner_abos: Beraterabos im Team (is_for = 'me')
  • direct_customer_abos: Kundenabos des betrachteten Beraters (member_id = user_id, is_for = 'ot')
  • team_customer_abos: Kundenabos der Downline-Berater (member_id in teamUserIds, is_for = 'ot')
  • new_partners: neue aktive Partner im Zeitraum
  • turnover_points: Punkte aus UserSalesVolume/UserBusiness
  • turnover_net: Netto-Umsatz aus UserSalesVolume/UserBusiness
  • shop_1000: Partner mit Kunden-/Shop-Punkten >= 1000

Berechtigungen

Jede Detailansicht muss sicherstellen:

  • Der eingeloggte User sieht nur eigene Downline-Daten.
  • Ein direkt angefragter user_id muss per Sponsor-Hierarchie im Team liegen.
  • Kundenabos werden nur in dem Umfang angezeigt, der fachlich für Berater vorgesehen ist.
  • Datenschutzrelevante Kundendaten sollten auf das notwendige Minimum reduziert werden.

Umsetzungsphasen

Phase 1: Begriffe, Datenbasis und MVP Dashboard

  • Fachliche Definitionen finalisieren
  • BackofficeDashboardService erstellen
  • Stufe-1-Linienübersicht mit Linien 1 bis 8 und Summenzeile bauen
  • bestehende Dashboard-Kachel durch Link auf neue Statistikseite ergänzen oder neue Seite im Menü aufnehmen
  • Kennzahlen noch ohne vollständigen Deep Dive, aber bereits sauber berechnet

Phase 2: Drill-down Stufe 2 und Stufe 3

  • Linien-Detailansicht pro Firstline bauen
  • Detailansichten je Kennzahl bauen
  • Abo-Listen mit Name, Punktewert, nächster Ausführung und Anzahl Lieferungen anzeigen
  • Links aus jeder Kennzahl setzen
  • leere Zustände und Summenzeilen ergänzen

Phase 3: 1000 Punkte Shop

  • fachliche Definition final bestätigen
  • Query und Summary implementieren
  • Widget in Übersicht ergänzen
  • Detailansicht mit Sortierung nach Volumen absteigend bauen

Phase 4: Herkunftsabfrage im Checkout

  • Migration und Model-Fillable ergänzen
  • Checkout-Formular erweitern
  • Validierung und Speicherung ergänzen
  • Admin-/Bestelldetail oder Export um Feld erweitern

Phase 5: Storno-Qualitätssicherung

  • Tests für vorhandene Storno-Punktepfade ergänzen
  • Fachentscheidung zur Periodenlogik dokumentieren
  • Fehlerfall ohne Original-UserSalesVolume sichtbar machen
  • ggf. Businessdaten-Neuberechnung nach Storno anstoßen

Phase 6: Incentive-Sichtbarkeit und Event-Archiv

  • rechtliche Entscheidung einarbeiten
  • separates Ranking-Sichtbarkeits-Opt-in ergänzen
  • Foto/Land im Ranking anzeigen
  • Event-Archiv als DashboardNews-Typ oder eigenes Modul umsetzen

Teststrategie

Feature-Tests:

  • Dashboard zeigt nur Daten der eigenen Downline.
  • Linien 1 bis 8 werden korrekt gruppiert.
  • Summenzeile entspricht Summe der Linien.
  • Klick auf Teamabos zeigt nur is_for = 'me' in der Downline.
  • Klick auf Kundenabos im Team zeigt nur is_for = 'ot' mit member_id in der Downline.
  • 1000-Punkte-Shop listet nur Partner über Schwelle und sortiert absteigend.
  • Checkout verlangt die Herkunftsabfrage und speichert sie.
  • Storno erzeugt negativen UserSalesVolume-Eintrag und aktualisiert Monatswerte.
  • Incentive-Ranking zeigt Name/Foto/Land nur nach passender Zustimmung.

Unit-Tests:

  • Service aggregiert Linien korrekt.
  • Service verhindert Zugriff auf fremde Team-User.
  • Metrikdefinitionen liefern stabile Counts bei aktiven, gekündigten und zukünftigen Abos.

Regressionsprüfung:

  • bestehende Teamseiten user.team.*
  • bestehende Abo-Seiten
  • bestehendes Incentive-Ranking
  • Checkout für Webshop, Bestelllink und Salescenter-Flows

Offene Fachfragen

  1. Soll die neue Statistik die aktuelle Monatslogik nutzen oder standardmäßig den letzten abgeschlossenen Monat zeigen?
  2. Sollen Stornos im Stornomonat oder im ursprünglichen Umsatzmonat gegengerechnet werden?
  3. Wie genau wird "1000 Punkte Shop" definiert: nur Shop-Punkte, alle Kundenpunkte oder Kundenabos plus Einzelbestellungen?
  4. Welche Kundendaten dürfen Berater in Deep-Dive-Listen sehen?
  5. Ist die Herkunftsabfrage Freitext, Auswahlfeld oder Kombination?
  6. Gilt die Herkunftsabfrage für alle Checkout-Flows oder nur für externe Kundenbestellungen?
  7. Darf eine Incentive-Teilnahme bereits Name/Foto/Land freigeben oder braucht es ein separates Opt-in?
  8. Soll das Event-Archiv nur Bilder und Texte enthalten oder eine echte Galerie mit Mehrfachuploads?

Empfehlung

Die Backoffice-Statistik sollte als eigenes kleines Modul im User-Bereich umgesetzt werden, nicht als weitere Logik in dashboard/_statistics.blade.php. Die vorhandenen Datenquellen sind ausreichend für ein MVP, aber sie müssen zentral aggregiert, fachlich sauber benannt und über berechtigte Drill-down-Routen zugänglich gemacht werden.

Priorität für die erste Umsetzung:

  1. Daten- und Begriffsdefinitionen finalisieren
  2. zentrale Services und Stufe-1-Linienübersicht
  3. Drill-down für Abos und Neupartner
  4. 1000-Punkte-Shop
  5. Checkout-Herkunft und Storno-Tests
  6. Incentive-Sichtbarkeit und Event-Archiv