Files
kaffeekasse-saas/docs/m2-technical-foundation.md
T
clemens 1aa4a4989e M4 Ledger-Preview als read-only App-Seite ergaenzen
- neue ledger-preview.php mit Tenant-Summen und letzten Ledger-Buchungen bauen
- Admin-Navigation und HTTP-Smoke um Ledger-Preview erweitern
- M4- und Meilenstein-Doku auf Preview-Stand aktualisieren
2026-07-14 20:13:44 +02:00

7.3 KiB

M2 Technisches Fundament

Stand: 2026-07-13

M2 fuehrt die technischen Grundbausteine fuer den SaaS-Umbau ein, ohne das Legacy-Verhalten oder das bestehende Design zu veraendern.

Status: abgeschlossen fuer den M2-Scope. Bewusst ausgelagerte Themen sind unten als Grenzen und M3-/M6-Uebergabe dokumentiert.

Ziel

  • Versionierte Datenbankmigrationen statt loser Schema-Ausfuehrung.
  • Zentrales Bootstrap fuer Umgebung, Session und CSRF-Helper.
  • Bestehende Legacy-Seiten bleiben kompatibel.
  • Layout-Trennung wird vorbereitet, aber noch nicht in bestehende Seiten hineingezogen.

Umgesetzte Bausteine

Bootstrap

  • app/bootstrap.php definiert zentrale Helfer:
    • app_env()
    • app_is_dev()
    • app_start_session()
    • app_csrf_token()
    • app_csrf_field()
    • app_verify_csrf()
    • app_require_csrf()
  • config.php laedt den Bootstrap und startet die Session mit sicheren Cookie-Optionen.
  • Sessions werden standardmaessig unter var/sessions abgelegt, weil die lokale PHP-Umgebung keinen beschreibbaren Systempfad garantiert. var/ ist von Git ignoriert. Der Pfad kann ueber APP_SESSION_PATH ueberschrieben werden.
  • CSRF ist bewusst noch nicht global erzwungen. Die vorhandenen POST-Seiten werden spaeter einzeln umgestellt, damit keine Formulare oder Spezialflows brechen.

CSRF-Rollout

Erste Legacy-POST-Seiten sind opt-in abgesichert:

  • hinweise.php: Hinweis anlegen und Hinweis loeschen. Der bisherige GET-Loeschlink wurde durch ein POST-Formular mit CSRF-Token ersetzt.
  • mitarbeiterverwalten.php: Mitglied anlegen, Bearbeitungsformular oeffnen, Mitglied speichern, aktivieren und deaktivieren.
  • namenanpassen.php: Anzeigenamen aktualisieren.
  • index.php: eigene Web-Striche eintragen.
  • stricheintragen.php: Sammelerfassung von Strichen.
  • einzahlung.php: Sammelerfassung von Einzahlungen.
  • letzteneintraege.php: letzte Einzahlungen und Strich-Eintraege loeschen.
  • csvupload.php: CSV-Zahlungsimport.

Noch offen:

  • Spezialprozesse: mailversenden.php, jahresauswertung.php.

CSV-Upload-Haertung

  • csvupload.php nutzt jetzt CSRF.
  • Uploads werden unter var/uploads gespeichert und nach der Verarbeitung geloescht. Damit liegen importierte Dateien nicht mehr im Webroot.
  • Dateiendung, Dateigroesse und MIME-Typ werden vor der Verarbeitung geprueft.
  • Hochgeladene Dateien bekommen serverseitig erzeugte Zufallsnamen.
  • CSV-Auswertungswerte werden HTML-escaped ausgegeben.
  • Die PayPal-Namenssuche nutzt Name und paypalname mit expliziter Parameterbindung.

Offen fuer M6:

  • Importvorschau vor dem Schreiben.
  • Import-Batch/Audit-Log.
  • Saubere Fehlerberichte je CSV-Zeile.

Migrationen

  • database/migrations/0001_legacy_mysql_baseline.sql bildet die bisherige MySQL-Dev-Baseline als erste versionierte Migration ab.
  • scripts/dev-db.php verwaltet schema_migrations und fuehrt neue Migrationen idempotent aus.
  • scripts/migrate.php ist der direkte Runner fuer Migrationen.
  • scripts/init-mysql-dev.php nutzt ab jetzt ebenfalls die Migrationslogik.

Layout

  • header.php und footer.php bleiben vorerst Legacy-Wrapper.
  • Die spaetere Trennung in Public-Layout und App-Layout wird erst umgesetzt, wenn die neue Route-/View-Struktur steht.
  • Die bestehende HTML5-UP-Struktur, Sidebar und Assets bleiben unveraendert.

Ausfuehrung

Mit normaler PHP-CLI:

php scripts/migrate.php
php scripts/init-mysql-dev.php
php scripts/check-golden-master.php
php scripts/http-smoke.php

In der aktuellen lokalen Umgebung:

LD_LIBRARY_PATH="$PWD/.local/php/usr/lib/x86_64-linux-gnu:$PWD/.local/php/usr/lib/x86_64-linux-gnu/sasl2" \
  "$PWD/.local/php/usr/bin/php8.3" \
  -c "$PWD/.local/php-dev.ini" \
  scripts/migrate.php

Die Skripte erwarten die bekannten Dev-Umgebungsvariablen DB_HOST, DB_NAME, DB_USER und DB_PASS. scripts/init-mysql-dev.php braucht zusaetzlich DEV_AUTH_EMAIL.

Aktueller Pruefstatus

  • Migration 0001_legacy_mysql_baseline.sql erfolgreich angewendet.
  • Zweiter Migrationslauf meldet: Datenbank ist aktuell.
  • PHP-Syntax fuer Bootstrap, Migrationen, Init-Skript und Config ist sauber.
  • Session-Start laeuft in der lokalen Dev-Umgebung ohne PHP-Warnings ueber var/sessions.
  • CSRF negative Tests: hinweise.php, mitarbeiterverwalten.php und namenanpassen.php liefern bei POST ohne Token HTTP 419.
  • CSRF positive Tests: gueltige Token funktionieren fuer Hinweis-Anlage, Mitglieder-Bearbeitungsformular und Namensanpassung. Der temporaere Testhinweis wurde wieder entfernt.
  • CSRF negative Tests fuer Buchungsflows: index.php, stricheintragen.php und einzahlung.php liefern bei POST ohne Token HTTP 419.
  • CSRF positive Tests fuer Buchungsflows: gueltige Token funktionieren fuer eigene Web-Striche, Sammelstriche und Sammeleinzahlungen. Die temporaeren Testbuchungen wurden wieder entfernt.
  • CSRF negative Tests fuer Korrektur-/Loeschflows: letzteneintraege.php liefert bei POST ohne Token HTTP 419.
  • CSRF positive Tests fuer Korrektur-/Loeschflows: gueltige Token funktionieren fuer das Loeschen temporaerer Einzahlungs- und Strich-Testeintraege.
  • CSRF negative Test fuer CSV-Upload: POST ohne Token liefert HTTP 419.
  • CSV-Upload positive Tests: gueltiges Token verarbeitet eine CSV-Datei, erkennt eine PayPal-Alias-Dublette und hinterlaesst keine Datei in var/uploads.
  • CSV-Upload negative Tests: Nicht-CSV-Dateien werden abgewiesen.
  • Golden Master weiterhin gruen mit 104 Assertions.
  • HTTP-Smoke weiterhin gruen mit 23 sicheren Seiten inklusive Landingpage, Login, Registrierung, Passwort-Reset, E-Mail-Verifikation und geschuetzter Mandant-Einstellungen, geschuetzter Mandantenauswahl sowie Ledger-Preview.

Bewusste Grenzen

  • Keine Tenant-/User-/Rollen-Tabellen in M2. Diese gehoeren zu M3.
  • Keine globale CSRF-Erzwingung fuer Spezialprozesse. mailversenden.php und jahresauswertung.php werden in M6 als Jobs mit Dry-Run, Audit und Versandlog neu betrachtet.
  • Kein Layout-Umbau in M2. Die visuelle Struktur bleibt stabil; Public-/App- Layouts werden mit der M3-/M7-Struktur vorbereitet.
  • PDF-/Mail-/Jahresprozesse bleiben als M6-Themen offen.

Abschlusskriterien

  • Migrationsrunner ist vorhanden und idempotent.
  • Bootstrap, Session und CSRF-Helper sind zentral verfuegbar.
  • Die relevanten Legacy-Schreibseiten sind CSRF-geschuetzt.
  • CSV-Uploads liegen nicht mehr im Webroot.
  • Bestehende Legacy-Seiten bleiben per HTTP-Smoke erreichbar.
  • Golden-Master-Fachwerte bleiben unveraendert.

Uebergabe an M3

M3 startet mit additiven SaaS-Tabellen und einer Default-Tenant-Abbildung. Die Legacy-Seiten sollen dabei weiterhin ueber die bestehenden Tabellen laufen, bis der fachliche Kern in M4/M5 schrittweise auf das Zielmodell umgestellt wird.

M3 wurde inzwischen gestartet. Umgesetzte Details stehen in docs/m3-saas-basis-vorbereitung.md. Der urspruengliche Startpunkt war:

  1. tenants, tenant_settings, users, tenant_memberships und participants als neue Migration anlegen.
  2. Einen Default-Tenant fuer die bestehende Kaffeeliste definieren.
  3. Bestehende kl_Mitarbeiter in participants spiegeln, inklusive legacy_mitarbeiter_id.
  4. Admins aus kl_Mitarbeiter.admin als tenant_memberships.role = 'admin' beziehungsweise fuer den ersten Hauptnutzer als owner abbilden.
  5. Erst danach Login/Registrierung und Public-/App-Routen anschliessen.