13-05-2026 implementation FR
This commit is contained in:
parent
245c281541
commit
70240d2b6a
61 changed files with 4472 additions and 2 deletions
417
dev/2026-05-13-backoffice/ENTWICKLUNGSKONZEPT-BACKOFFICE.md
Normal file
417
dev/2026-05-13-backoffice/ENTWICKLUNGSKONZEPT-BACKOFFICE.md
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
# 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue