Commit graph

22 commits

Author SHA1 Message Date
05de0f0698 Doku: Protokoll September, Nachtrag Bestelldetail Herkunft
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:49:50 +00:00
b8a18b09cf Doku: Protokoll Umsetzungen September, Nachtraege 06.10.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:36:06 +00:00
2381bbe3b9 Doku: Kundeninfo Neuerungen September (Stand 25.09.)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 12:08:50 +00:00
f2aa30243f Recruiting Challenge: Firmenkonto ohne Rang und Praemie, Bedingungen Punkt 4 ergaenzt
Kundenentscheid 25.09.2026 zu den Regeln 4 bis 7:
- Firmenkonto (mivita.company_user_id) steht in keiner Rangliste und
  bekommt keine Praemie; getrackt wird weiter, damit ein ueber den
  Firmenlink registrierter Partner nach dem Umhaengen mit umzieht
- Bedingungen Punkt 4 (de/en/es/fr): auch Kunden, die Berater werden,
  zaehlen; massgeblich ist der aktuell hinterlegte Sponsor
- Test: Anmeldung ueber den Firmenlink, Umhaengen, Wertung beim neuen
  Sponsor
- Doku: Regeln 4 bis 7 entschieden

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:02:02 +00:00
e390d3b816 Doku: Bestaetigung wirkt rueckwirkend ab 09.10., keine automatische Erinnerung
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 10:53:17 +00:00
4f62ad1850 Doku: Challenge-Regeln 25.09. und Dry-Run-Befund user:cleanup
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 10:44:49 +00:00
979a12d1cb Doku: Deploy-Stand 25.09. markiert, Challenge-Start 9. Oktober
A1-A4 und E1 live seit 23.09., B2, A07, Abo-Warnung und E1-Nachtraege
live seit 25.09., Settings auf 0, Montenegro beendet. Offen: erster
user:cleanup-Lauf, Seeder fuer den Challenge-Start 09.10.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 10:28:27 +00:00
aa52b02a2a Doku: Plaene, Kundenbriefe, Log-Analyse und Ledger-Plan versioniert, Stand 23.09.
- September-Plan: B2, E1 (Gleichstand, Zahlungsdatum), A07 und die
  Abo-Warnung nachgetragen; Audit-Stand A07 erledigt.
- Bisher nur im Arbeitsbaum: Entwicklungsplan und Kundenbrief vom 07.09.
  samt PDF, Tickets vom 08.09., Log-Analyse 26.08., Ledger-Plan,
  August-Anerkennungen. E-Mail-Adressen von Kunden und Beratern durch
  Platzhalter bzw. Namen ersetzt.

Nicht versioniert (personenbezogene Daten): Kundenliste CSV/XLSX und die
Produktions-Logs in dev/2026-08-26-logs/*.log.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:45:10 +00:00
0b8f8abeeb Berater faellt aus (B2): pausieren nach 2 Tagen, Rueckgabe bei Zahlung, harter Cut am 28. Tag
Entwicklungsplan September, B2 (Protokoll 08.09., Rueckmeldung 14.09., R3):
- Ablauftag + 2 Kalendertage (Nachtlauf): Team, Kunden, Kundenabos und
  Portal-Logins gehen umkehrbar an den naechsten aktiven Sponsor, jede
  Umhaengung in consultant_suspension_transfers protokolliert. Kurzinfo
  an den Sponsor ohne Listen, keine Mail an das Firmenkonto.
- Zahlung bis Tag 27: Berater aktiv, Team und Kundendaten zurueck (nur
  was noch beim Sponsor liegt); Umsaetze der Zwischenzeit bleiben dort.
- Tag 28: was noch am Berater haengt geht endgueltig an den Sponsor,
  Berater wird dessen Kunde (ohne Duplikat) und geloescht; Listen-Mail
  mit Vorname, Nachname, Telefon, E-Mail an jeden haltenden Sponsor.
- Cron, Zahlungseingang und Admin-Ablaufdatum laufen ueber
  ConsultantSuspensionService; user:cleanup --dry-run listet beide Stufen.
- Mail 35 und Dashboard nennen Pausentag und Frist; Fristen in
  config/mivita.php (cleanup_suspend_days, cleanup_delete_days).
- Nebenbefunde: Kernel referenziert UserCleanUp, user:restore aus der
  User-Bereinigung laeuft nur noch einmal.
- Testschema: shopping_users.auth_user_id nullable wie auf Produktion
  (Migration aendert nur, wo die Spalte noch NOT NULL ist).
- Uebersicht fuer die Kundin: dev/_tickets/2026-09-23-mitgliedschaft-
  ablauf-uebersicht.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:44:45 +00:00
d21d94a060 Newsletter-Listen: Empfaengerlisten filtern, speichern und exportieren
Admin-Bereich "Newsletter-Listen" (Plan dev/_tickets/entwicklungsplan-
newsletter-listen.md): Berater und Kunden nach Filtern zusammenstellen,
als Liste speichern und wieder laden, Export als XLSX/CSV. Jeder Export
wird protokolliert (newsletter_list_exports).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:44:09 +00:00
2f24a35efa Incentive (E1): Titelbild der Challenge, Dashboard-Karte mit einem Button, VIP-Sichtbarkeit auf dem Dashboard getestet
Titelbild liegt unter public/img/incentive/recruiting-challenge-2026-27/,
der Seeder traegt den Dateinamen ein. Die Dashboard-Karte verlinkt nur
noch auf die eine Incentive-Seite, der Ranglisten-Button entfaellt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 14:06:15 +00:00
b83b43ef4c Incentive (E1): Teaser und Rangliste zu einer Incentive-Seite zusammengefasst
Eine Seite unter /incentive/{slug}: oben Teilnahme-Block mit Bedingungen
(oder fuer bestaetigte Teilnehmer der Kopf mit Rang, Punkten, Praemie und
Bedingungen zum Aufklappen), darunter Titelbild, Text, Kacheln, "So
funktioniert es", Galerie und das Live-Ranking mit Sprungmarke #ranking.
Die alte URL /incentive/{slug}/ranking leitet dorthin um, Dashboard und
Detailseite verlinken auf die Sprungmarke, show.blade.php entfaellt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 13:11:10 +00:00
f340d0de3d Incentive (E1): Bilder je Incentive, Teaser mit Call to Action oben, Praemie je Teampartner statt Punkte
Titelbild und Galerie liegen jetzt in public/img/incentive/<slug>/, der
Hauptordner ist nur noch Fallback fuers Titelbild. Damit erscheinen die
Montenegro-Impressionen nicht mehr unter der Challenge; die Fotos sind in
montenegro-incentive-2026/ verschoben.

Teaser: Call to Action "Bist du bereit fuer die Challenge?" mit Button ganz
oben. Bei Geldpraemie zeigen die Kacheln "Deine Praemie" (50 EUR je neuem
Teampartner) und "Top 3 Bonus" statt Incentive-Punkte, darunter der Abschnitt
"So funktioniert die Challenge". Rangliste: Button "Jetzt teilnehmen" wieder
in der Sekundaerfarbe.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 12:37:58 +00:00
3341c929eb Incentive (E1): "Nur fuer VIP sichtbar" und Ranglisten-Seite mit Teilnahme-Block oben
Haken vip_only am Incentive: aktives Incentive erscheint dann nur fuer
VIP-Konten in Sidenav, Dashboard, Teaser, Rangliste und Details, andere
Berater bekommen 404; das Tracking laeuft fuer alle weiter. Seeder setzt den
Haken fuer die Abstimmung der Recruiting Challenge.

Ranglisten-Seite: solange die Teilnahme nicht bestaetigt ist, steht der
Teilnahme-Block mit Praemien-Chips, Checkbox, Button und aufklappbaren
Bedingungen ganz oben, darunter Trennlinie, Titel, Untertitel, Bild,
Beschreibung und die Info-Kacheln. Ueberschriften vergroessert, Abo-Bloecke
nur wenn Abos zaehlen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 11:11:33 +00:00
4e4b58e90e Incentive (E1): Recruiting Challenge mit finalen Texten als Seeder, Abstimmungsvorlage aktualisiert
Seeder legt die Challenge als Entwurf mit Beschreibung, Bedingungen und den
Werten 50 EUR je Neupartner sowie 500/300/200 EUR Bonus an; ein zweiter Lauf
aktualisiert nur die Texte. Vorlage ohne Gedankenstriche, Bonus entschieden,
offene Regelfragen mit den in den Bedingungen hinterlegten Vorschlaegen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:19:03 +00:00
1f55e2c966 Doku: Inhaltsvorschlag und Abstimmungsfragen zur Recruiting-Challenge (E1)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 12:37:48 +00:00
e3efa2f5f0 Incentive (E1): Recruiting-Challenge mit Geldpraemie, Auszahlungs-Export und parallelen Incentives
Neue Felder amount_per_partner, bonus_rank_1..3 und include_sales_points an
incentives. Mit ausgeschalteten Umsatzpunkten zaehlt die Wertung nur die
Einmalpunkte je Neupartner, die Rangliste entspricht damit der Anzahl
Neupartner mit Starterpaket. IncentivePayoutService rechnet Neupartner mal
Betrag plus Rang-Bonus fuer qualifizierte Gewinner; Admin-Detailseite bekommt
Praemienspalte, Summen und XLSX-Export fuer die Auszahlung.

Sidenav und Dashboard zeigen alle aktiven Incentives, damit Montenegro und
die Challenge parallel laufen koennen. Teaser, Rangliste und Details zeigen
bei Geldpraemie die Praemien-Kachel und "Deine Praemie bisher" und blenden
Abo-Bloecke aus, wenn Abos keine Rolle spielen. Montenegro bleibt unveraendert.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 12:10:27 +00:00
03416b0afe Audit 18.09.: Zahlungsdatum nur bei Zahlung, Neupartner-IDs im Snapshot, Pausenende folgt dem Termin
F1: partner_paid_at wird beim Rechnungskauf (paymentStatusPaidAction mit
paid=false) nicht mehr gesetzt, sondern erst bei der Rechnungszahlung; der
Backfill nimmt das Aktivierungsdatum nur noch ohne jede
Registrierungsbestellung (offene Rechnung bleibt leer).
F2: Snapshots speichern je Linie new_partner_ids, die Neupartner-Liste zeigt
genau diese; aeltere Snapshots ohne IDs rechnen mit der damaligen Regel
(Registrierungsmonat, scopeNewPartnerInByActiveDate), damit Kachel und Liste
uebereinstimmen. Keine Payload-Versionsaenderung, kein Neuaufbau noetig.
F3: Liefertag-/Termin-Aenderung waehrend einer Pause zieht paused_until mit;
eine Ausfuehrung loescht auch den paused_by_*-Grund.
F4: expiredCount der Firstlines-Seite (Controller, View, Sprachen) zum bereits
committeten Test nachgezogen.
F5: Backfills schreiben ohne updated_at (toBase()->update, timestamps=false).
Kuendigungsbestaetigung abo_cancel_confirm wird im Selfservice serverseitig
verlangt. AboStatusExplainer laedt die Historie je Abo und Aktion nur einmal.

Stellungnahme und Deploy-Folgen im Audit-Dokument, Regressionstests je Befund.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 08:59:45 +00:00
cf0311afc1 Abo (A1+A2): Liefertag frei waehlbar 1-31, Aenderung nur nach vorn, Sperre erst am Ausfuehrungstag
A1: Jeder Monatstag ist als Liefertag erlaubt (UserAbo::allowedDeliveryDays),
Tage 29-31 liefern in kuerzeren Monaten am letzten Tag. Eine Stelle
AboHelper::dateForDayInMonth klammert; setNextDate, Erstausfuehrung,
Admin-Termin und Pause rechnen darueber, der Folgemonat immer aus dem
Liefertag (31.01 -> 28.02 -> 31.03). Liefertag-Aenderung gilt fuer den
laufenden Zyklus und nur nach vorn: ist der Tag im Referenzmonat vorbei,
wird abgelehnt, der Monat verschiebt sich nie (Rueckfrage R1).
Admin-Filter "naechste Ausfuehrung" als Datumsbereich. Prognose-Kacheln
bekommen die Kachel Monatsende, Team-Abos rechnen bis Monatsende.

A2: Sperrfristen Default 0, Setting 0 ist ausdruecklich 0 (fiel bisher auf
den Default zurueck). Bedingung Kalendertage <= Sperre, zentral in
AboHelper::isWithinLock: am Ausfuehrungstag ab 0:00 Uhr fixiert, Vortag bis
23:59 Uhr frei, fuer Liefertag, Produkte, Pause und Kuendigung (R2). Texte
mit _zero-Varianten ueber AboHelper::lockMessage.

Sprachdateien de/en/es/fr, neuer AboDeliveryDayTest, bestehende Tests
angepasst, Plan-Status mit Deploy-Schritt (Settings auf 0).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 11:28:55 +00:00
d6efe56cd4 Abo (A3): Status und Grund eines Abos sichtbar machen
Neue Spalten user_abos.status_reason / paused_until und
user_abo_orders.error_message. Der Grund wird zentral am Model gepflegt
(saving-Event): Zahlungsfehler, Kuendigung/Deaktivierung mit Akteur aus dem
Formular-Kanal, Loeschen beim Zurueckkehren in den Lauf; die Pause setzt
paused_until und paused_by_*. Cron- und Retry-Zahlung schreiben den Fehlertext
des Anbieters an die Abo-Bestellung.

AboStatusExplainer uebersetzt das in einen Satz ("Pausiert bis ... vom Kunden
am ...", "Zahlung am ... fehlgeschlagen - Grund: ...", "Gekuendigt am ... vom
Berater"), Partial _status_explain in Abo-Detail (CRM, Portal, Admin),
Abo-Uebersicht, Kundenabo-Liste, Team-Kundenabos und Admin-Datatable; dort
neuer Filter "Zustand" (pausiert / Zahlung fehlgeschlagen). Backfill-Kommando
abo:backfill-status-reasons fuer Bestandsdaten, Fallback ueber das
Statusprotokoll und die Pausenfelder.

Sprachdateien de/en/es/fr, Tests in AboStatusExplainTest, Plan-Status.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:24:18 +00:00
e8057f9f7b Abo (A4): Abschnitt "Abo pausieren oder kuendigen" mit Kuendigungs-Hinweis
Eigener Abschnitt auf der Abo-Seite (CRM me/ot und Kundenportal) mit
Fortschritt zur Mindestlaufzeit, Pause und Kuendigung. Die Kuendigung laeuft
ueber ein Modal, das die Folgen nennt (Abo endet, Konditionen entfallen, ein
neues Abo hat wieder 6 Pflichtlieferungen), die Pause als Alternative anbietet
und erst nach Bestaetigungs-Checkbox freigibt. Innerhalb der Sperrfrist vor
der Ausfuehrung erscheint statt der Buttons ein Hinweis
(AboHelper::isPauseCancelLocked). Das Einstellungs-Modal verweist nur noch
auf den Abschnitt. Die Kuendigung im Repository ist jetzt wie die Pause eine
eigenstaendige Aktion: Erfolgsmeldung statt Liefertermin-Hinweis, next_date
bleibt unangetastet.

Sprachdateien de/en/es/fr, Tests in AboPauseCancelSectionTest, Plan-Status.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:14:51 +00:00
96545364f1 Team-Statistik = Team-Struktur (Provisionsbaum, Umschalter) und Laufstand-Fix in user_sales_volumes
K11 aus dem September-Protokoll (Tickets C1 und C2 im Entwicklungsplan), live seit 14.09.2026.

C1 – Statistik rechnet wie die Provision
- Standard-Baum ist der Provisionsbaum (Mitglieder wie TreeCalcBot: Mitgliedsebene,
  Abrechnungskonto, active_date; ausgefilterte Knoten kappen ihren Unterbaum, max. 21 Linien).
  Gesamte Downline bleibt per Umschalter erreichbar, Wahl in der Session.
- Punkte-Definition: Provisionspunkte (TP + Shop), reine Karrierepunkte ausgewiesen statt
  eingerechnet, negative Monatssalden je User wie in der Provision auf 0 gekappt.
- Abgeschlossene Monate nehmen die Mitglieder je Linie aus dem gespeicherten Provisionslauf
  (user_businesses), Snapshots je Baum-Definition (Payload-Version 3, Migration).
- Struktur-Modal: Gesamt aus den Linien-Punkten mit Dezimalen statt der int-Spalte total_pp.
- Messlauf statistics:compare-trees (Downline / Provisionsbaum / Struktur je VIP, Laufstand-Drift).

C2 – Laufstand-Race (Provision zu niedrig bei zeitgleichen Buchungen)
- Neuberechnung liest die Zeilen des Beraters sperrend (FOR UPDATE), Index (user_id, year, month).
- Paid-Pfad der Payone- und Stripe-Webhooks als DB::transaction mit 3 Anlaeufen; Deadlock und
  Lock-Timeout aus der Rechnungserstellung werden nicht mehr geschluckt.
- Sicherheitsnetz sales:repair-running-totals taeglich 02:45 vor dem Provisionslauf;
  abgeschlossene Monate werden nicht angefasst (Entscheid 14.09.: keine Nachzahlung fuer 06/08).

Doku: Entwicklungsplan zum Protokoll, Deploy-Notiz 14.09. (inkl. Migrations-Stolperstein:
Migrationen tragen Werte als Literale, nicht als Konstanten aus dem Anwendungscode).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 15:31:32 +00:00