- Neue Seite Anerkennungen (/user/recognitions, Menue unter News Archiv) fuer
alle Berater mit aktivem Konto: oben die Anerkennungen des Vormonats in den
fuenf Kategorien der Monatsmail, Filter zurueck bis Januar 2026; darunter
Live-Ranglisten (Top 10 je Kategorie) des laufenden Monats, 15 Min. Cache.
- Kategorien: Top-Recruiter (ab 2 Neupartnern), neue Kunden-Abos,
Kundenabo-Punkte, Kunden-Abos gesamt, Gesamtpunkte (1.000-Punkte-Shop,
mit Platz 4). Regeln wie TopResultsService/VIP-Statistik, nur firmenweit.
- Firmenkonto (6) und Grosskundin (3) nie aufgefuehrt:
config mivita.recognition_excluded_user_ids.
- Abgeschlossene Monate sind bis zum 3. des Folgemonats vorlaeufig und werden
dann eingefroren: neue Tabelle recognition_snapshots, Command
recognitions:freeze (taeglich 06:15, idempotent, holt offene Monate nach).
- September-Anerkennungen firmenweit geprueft und korrigiert.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Kontaktformular: keine Mail mehr an die eingegebene Adresse (wurde als
Spam-Versender missbraucht); Anfrage nur an Kontakt-Adresse + Berater (BCC),
Reply-To = Absender; Eingaben in der Mail escaped
- Kontakt + Registrierung: Cloudflare Turnstile statt reCAPTCHA (Schluessel
aus dem Code in die .env), Rate-Limits, Honeypot + Mindest-Ausfuellzeit,
Namensregel (lateinische Schrift, max. 50 Zeichen), Form Requests
- Registrierung: Partner-Nummer nur fuer aktive Berater (vorher ungeprueft)
- CRM: POST /register abgeschaltet (legte ohne Captcha Benutzer an)
- Passwort-Mindestlaenge systemweit 8 Zeichen ueber Password::defaults()
- Log abgefangener Anfragen: storage/logs/form-spam-*.log
- Doku und Protokoll: dev/2026-10-09-spam/README.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- sentry/sentry-laravel 4.28; config/sentry.php gehaertet (keine PII,
keine Request-Bodys, before_send ErrorReportScrubber)
- Handler: Integration::captureUnhandledException, CommandNotFoundException
nicht melden
- ReportErrorSignals (global): toter interner Link (nach Pfad wegen
Catch-all-Route), 403/429 fuer Angemeldete, 419; gedrosselt
- Browser: selbst gehostetes SDK (esbuild-Bundle 11.5.0), Loader ohne
Build-Schritt und ohne Regex-Lookbehind, in 7 Layouts mit area-Tag
- phpunit.xml: DSNs und ntfy-URL leer, CACHE_DRIVER=array (Tests schrieben
bisher in den lokalen Datei-Cache)
- dev/glitch-tip/README.md mit Instanz, Org, Projekt-IDs, API-Auswertung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- HealthProbe: Datenbank, Cache, Queue (sync / database / Horizon),
fehlgeschlagene Jobs (24 h), Scheduler-Herzschlag, Plattenplatz
- /health auf jeder Domain, ohne web-Gruppe, nur mit MONITORING_HEALTH_TOKEN
- monitoring:heartbeat minuetlich im Scheduler
- Sysadmin -> Systemstatus (my.mivita.care/sysadmin/status) mit Version,
Umgebung und zuletzt fehlgeschlagenen Jobs
- Anleitung Abschnitt G
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Supervisor bedient alle Queues der Jobs (high-priority, default, dhl-*),
production mit 3 statt 10 Prozessen
- Redis-Queue mit after_commit: der Stripe-Paid-Pfad plant den
Rechnungsnummer-Sync innerhalb der Transaktion ein
- /horizon nur fuer System-Admins (admin >= 4)
- horizon:snapshot alle 5 Minuten, queue:prune-failed nach 30 Tagen
- deploy.sh: QUEUE_WORKER (horizon | none), Anleitung Abschnitt F
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- dev/betrieb/deploy.sh: Tag auschecken, composer, Caches leeren (bewusst
kein route:/config:cache wegen hostabhaengiger Routen und env()-Aufrufen),
horizon:terminate, FPM-Reload, Worker-Pruefung am Ende
- dev/betrieb/README.md: Einrichtung Server, Umstellung des Live-Verzeichnisses,
Release, Deploy, Rollback
- config('app.version') aus RELEASE, php artisan about --only=mivita
- monitoring:queue-probe prueft nach dem Deploy, ob Horizon Jobs abholt
- Vorlage dev/git-deploy-monitoring aus Pressekonto
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Log-Analyse 26.08. (P0-2, P1-5, P2-3):
- Produktcode fuer DHL Paket International ist V53WPAK; mit V53PAK wurde
kein einziges Auslandslabel erzeugt. Alte Codes werden gemappt
(LEGACY_PRODUCT_CODE_ALIASES), Abrechnungsnummer und Masse suchen auch
unter den alten Setting-Schluesseln (dhl_account_v53pak) und Env-Namen.
- Zu lange Felder (Name, Stadt, Telefon, Referenz) werden auf die
DHL-Grenzen gekuerzt bzw. bereinigt statt den Versand abzulehnen; refNo
mindestens 8 Zeichen, sonst die Bestellreferenz.
- Tracking wiederholt bei HTTP 5xx der Unified-API bis zu dreimal.
Zolldaten fuer die Schweiz (P0-3) sind nicht Teil dieses Commits.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Öffentliches Widerrufsformular /widerruf mit Bestell-Lookup (throttled)
- Bestätigungsmail an Kunde + Weiterleitung an bestellungen@ (config app.withdrawal_mail)
- Admin-Übersicht/-Detail unter /admin/withdrawals inkl. Sidenav-Eintrag
- Widerruf-Button in Portal-Bestellansicht und Footer-Links
- Model OrderWithdrawal + Migration + Factory + Tests
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Neuer schlanker DHL-Info-Button (getDhlShippingButton) in den Order- und
Shop-Sales-Datatables, oeffnet ein Read-only-Modal (modal_dhl_shipping_info)
mit den Tracking-Daten; dhlShipments wird dafuer eager geladen.
Absenderadresse in config/dhl.php aktualisiert, plus kleinere Fixes in
DhlShipmentController/Service/DataHelper und CreateReturnLabelJob.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>