Die Migration in participants/ledger_entries ist abgeschlossen: kein
Teilnehmer traegt noch eine legacy_mitarbeiter_id, kein Journaleintrag eine
legacy_table. Damit war der jeweils zweite Zweig ("Default-Mandant schreibt
zusaetzlich nach kl_Einzahlungen/kl_Kaffeeverbrauch/kl_Mitarbeiter") in
sechs Dateien nicht mehr erreichbar - er musste aber bei jeder Aenderung
mitgepflegt werden, zuletzt bei der Bemerkung fuer Einzahlungen.
Entfernt:
- Dual-Write beim Buchen: einzahlung.php, stricheintragen.php, index.php,
jahresauswertung.php, app/imports.php, app/paypal-inbox.php
- Dual-Write in der Mitgliederverwaltung: ledger_create_participant,
ledger_update_participant, ledger_set_participant_active,
ledger_anonymize_participant
- die verwaisten Spiegelfunktionen ledger_mirror_legacy_payment,
ledger_mirror_legacy_consumption und ledger_void_entry_by_legacy_id
Nebenbei behoben: kaffeeliste.php hat die Teilnehmer-Detailseite nur fuer
Mitglieder mit legacy_mitarbeiter_id verlinkt - die hat seit der Migration
niemand mehr, die Seite war also fuer alle unerreichbar. Verlinkt und
adressiert wird jetzt ueber participant_id; "user_id" bleibt als Alias
erhalten. Der Mandanten-Isolationstest prueft jetzt ledger_void_entry, also
den Pfad, den letzteneintraege.php tatsaechlich nutzt.
Pruefskripte unveraendert gegenueber der Baseline vor dem Umbau
(http-smoke 27/6, role-matrix 55/0); die Isolationspruefung steigt von
9 auf 11 PASS bei gleichem vorbestehendem Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher gab es nur PayPal. Jetzt sind pro Mandant drei unabhaengig
aktivierbare Zahlungswege konfigurierbar (mandant-einstellungen.php):
- Barzahlung mit frei waehlbarem Ansprechpartner.
- PayPal wie bisher, mit Zahlungslink.
- Ueberweisung mit Kontoinhaber und IBAN (Format wird geprueft,
Leerzeichen werden normalisiert).
Das Mitglieder-Dashboard (index.php) zeigt unter "Bezahlen" alle
aktivierten Methoden mit dem jeweils offenen Betrag; die IBAN wird zur
besseren Lesbarkeit in Viererbloecken angezeigt.
Neue tenant_settings-Spalten via Migration 0021 (cash_enabled,
cash_contact, bank_transfer_enabled, bank_account_holder, bank_iban).
Bugfixes aus dem Code-Review:
- XSS: unescaptes $_SERVER['PHP_SELF'] in csvupload.php und
letzteneintraege.php durch feste Seitennamen ersetzt.
- Stripe-Webhook: Event-Deduplizierung (neue Tabelle stripe_webhook_events)
gegen doppelte Verarbeitung/Dolibarr-Rechnungen bei Retry-Zustellung.
- Stripe-Webhook: Tarifwechsel aus dem Kundenportal wird lokal nachgezogen
(plan_code aus dem Preis-lookup_key bei subscription.updated).
- Post-Redirect-Get fuer jahresauswertung, mailversenden und die
Selbst-Stricheintragung - verhindert Doppelbuchung/Doppelversand per
Browser-Refresh.
- Jahresbonus: Mails erst nach erfolgreichem Commit; Restcent-Ausgleich
beim letzten Empfaenger, damit die Summe exakt stimmt.
- Verschachtelte HTML-Dokumente in csvupload/einzahlung/stricheintragen
entfernt (Layout kommt aus header.php).
- Rate-Limit fuer den Versand von E-Mail-Verifizierungslinks.
Neue Funktionen:
- Mitglieder koennen ihren zuletzt selbst eingetragenen Strich wieder
stornieren (nur eigene Web-Eintraege, Kassenwart-Eintraege bleiben).
- Monatsuebersicht des eigenen Verbrauchs im Mitglieder-Dashboard.
- Automatische Zahlungserinnerung: opt-in pro Mandant ab der
Warnschwelle, mit Intervall; Cron-Skript scripts/send-payment-reminders.php.
- CSV-Import fuer Mitgliederlisten inkl. herunterladbarer Vorlage
(mitglieder-vorlage.php), Semikolon-/Komma- und BOM-Erkennung.
- Logo als PDF-Wasserzeichen pro Mandant (Upload in den Mandant-
Einstellungen, geschuetzt unter var/tenant_logos/, ersetzt den
Text-Wasserzeichen im Ausdruck).
Robusterer Teilnehmer-Lookup im Dashboard ueber user_id (Fallback E-Mail).
- index.php zeigt bei abweichendem Host (APP_HOST-Env) die Landingpage
statt des Dashboards, damit kaffeeliste.de und app.kaffeeliste.de aus
demselben Webspace bedient werden koennen. Ohne gesetztes APP_HOST
(lokale Entwicklung) unveraendertes Verhalten.
- landing.php verlinkt Login/Registrierung ueber APP_HOST fest auf die
App-Domain, damit Besucher der Marketingdomain dort landen.
- functionsLDAP.php entfernt (nur ueber die tote IIS/AUTH_USER-Branch
erreichbar, vollstaendig durch app/saas-auth.php ersetzt); zugehoerige
tote AD/LDAP-Variablen aus config.php und der AUTH_USER-Zweig aus
functions.php entfernt.
- mailausgebe.php, umfrage.php, umfrageergebnisse.php entfernt: aus der
Navigation nicht erreichbare Debug-/Einzweck-Seiten ohne echte
Berechtigungspruefung (mailausgebe.php dumpte alle Mitglieder-E-Mails,
umfrageergebnisse.php hatte nur einen auskommentierten Basic-Auth-
Block). scripts/http-smoke.php entsprechend bereinigt.