Files
kaffeekasse-saas/docs/saas-umstrukturierungsplan.md
T
clemens 5824b066f4 Public-Auth-Seiten in Landingpage-Stil integrieren
- gemeinsames Public-CSS fuer Landingpage und Auth-Seiten ergaenzen
- Login, Registrierung und Passwort-/E-Mail-Seiten vom App-Layout trennen
- App-Sidebar von Public-Login- und Registrierungslinks bereinigen
- Webspace- und Subdomain-Strategie dokumentieren
2026-07-14 19:01:57 +02:00

23 KiB

SaaS-Umstrukturierungsplan Kaffeeliste

Stand: 2026-07-13

Dieses Dokument beschreibt den geplanten Umbau der bestehenden Kaffeelisten-App zu einer mehrkundenfaehigen SaaS-Anwendung mit oeffentlicher Landingpage, Kundenregistrierung und geschuetzter App. Die bestehende Bedienlogik und das visuelle Grunddesign sollen bewusst erhalten bleiben.

Zielbild

  • Mehrere Kunden koennen eigene Kaffeelisten betreiben.
  • Jeder Kunde hat isolierte Daten, Einstellungen, Mitglieder und Buchungen.
  • Neue Kunden koennen sich ueber eine oeffentliche Landingpage registrieren.
  • Die operative App bleibt optisch nah am aktuellen Bestand: Sidebar, Tabellen, schlichte Formulare, HTML5-UP-Anmutung.
  • Authentifizierung, Rollen, Mandantenkontext und Sicherheitspruefungen werden zentralisiert.
  • Finanznahe Vorgaenge werden nachvollziehbar und revisionsfreundlich gespeichert.

Nicht-Ziele fuer den ersten Umbau

  • Kein kompletter Design-Relaunch.
  • Keine verspielte Marketing-App statt der bestehenden Arbeitsoberflaeche.
  • Kein gleichzeitiger Neubau aller Randmodule, wenn diese fuer den MVP nicht benoetigt werden.
  • Kein Dual-Write zwischen Legacy und neuer App als Standardbetrieb.
  • Keine Mandanten-ID aus Formularfeldern oder URL-Parametern als alleinige Sicherheitsbasis.

Ist-Zustand

Die aktuelle App ist eine flache PHP/sqlsrv-Legacy-App im Webroot.

Wichtige Bereiche:

  • index.php: persoenliches Dashboard.
  • stricheintragen.php: Sammelerfassung von Kaffee-Strichen.
  • einzahlung.php: Sammelerfassung von Einzahlungen.
  • kaffeeliste.php: Gesamtuebersicht.
  • mitarbeiterverwalten.php: Mitglieder- und Adminpflege.
  • letzteneintraege.php: Korrektur beziehungsweise Loeschung letzter Buchungen.
  • csvupload.php: Zahlungsimport.
  • exportKaffeeliste.php: PDF-/Listenexport.
  • mailversenden.php: Massenmail.
  • hinweise.php: Hinweise.
  • faq.php: FAQ.

Zentrale technische Beobachtungen:

  • Authentifizierung haengt an Windows/IIS AUTH_USER und LDAP.
  • Die Mailadresse des Nutzers wird in functionsLDAP.php ermittelt.
  • Rollen liegen als Boolean admin direkt auf kl_Mitarbeiter.
  • Datenzugriff findet direkt in den einzelnen PHP-Seiten per sqlsrv_query statt.
  • Es gibt kein sichtbares Migrationssystem und kein DB-Schema im Repository.
  • Fachliche Tabellen haben aktuell keinen Mandantenbezug.
  • Das Design kommt vor allem aus assets/css/main.css und dem HTML5-UP-Layout.
  • Die App-Navigation sitzt faktisch in footer.php; nav.php ist leer.

Grundsatzentscheidung

Der Umbau sollte nicht mit einer rein kosmetischen Landingpage starten, sondern mit einem stabilen SaaS-Fundament:

  1. Bestand dokumentieren und fachliche Ergebnisse einfrieren.
  2. Mandantenmodell, Auth und Rollen sauber aufbauen.
  3. Bestehende Fachlogik schrittweise tenant-sicher uebernehmen.
  4. Landingpage und App-Shell trennen, ohne das App-Design neu zu erfinden.

So bleibt die vertraute Kaffeelisten-Oberflaeche erhalten, waehrend die Datenbasis und Sicherheit SaaS-faehig werden.

Zielarchitektur

Public-Bereich

Der Public-Bereich ist ohne Login erreichbar und laedt keine Mandantendaten.

Empfohlene Routen:

  • /: Landingpage.
  • /preise oder spaeter /pricing: optional, falls Tarife eingefuehrt werden.
  • /faq: oeffentliche FAQ oder FAQ-Auszug.
  • /registrieren beziehungsweise aktuell register.php: Kundenregistrierung.
  • /login beziehungsweise aktuell login.php: Login.
  • /passwort-vergessen beziehungsweise aktuell passwort-vergessen.php: Passwort-Reset.

Landingpage-Inhalte:

  • Hero mit Name Kaffeeliste und kurzer Nutzenbeschreibung.
  • Drei Kernablaeufe: Kaffee nehmen, Strich setzen, bei Bedarf bezahlen.
  • Kurzer Blick auf Funktionen: Mitglieder, Guthaben, Einzahlungen, Export, Hinweise.
  • App-Screenshot oder Demo-Ansicht im bestehenden Stil.
  • FAQ-Auszug.
  • Call-to-Action zu Registrierung und Login.

Geschuetzte App

Die geschuetzte App bleibt die operative Arbeitsoberflaeche.

Empfohlene Routen:

  • /app: Dashboard oder Weiterleitung auf /app/dashboard.
  • /app/dashboard: Meine Kaffeeliste.
  • /app/striche: Eigene Striche erfassen, falls erlaubt.
  • /app/einzahlungen: Zahlungen und PayPal-Optionen.
  • /app/mitglieder: Mitgliederverwaltung.
  • /app/liste: Gesamtuebersicht.
  • /app/buchungen: Letzte Eintraege und Korrekturen.
  • /app/importe: CSV-Importe.
  • /app/export/pdf: PDF-/Listenexport.
  • /app/hinweise: Hinweise.
  • /app/einstellungen: Tenant-Einstellungen.

Die App sollte eine Sidebar behalten, aber besser gruppiert werden:

  • Persoenlich: Meine Kaffeeliste, Namensanpassung, FAQ.
  • Erfassung: Striche, Einzahlungen.
  • Auswertung: Kaffeeliste, Buchungen, Export.
  • Administration: Mitglieder, Hinweise, Einstellungen, Importe.
  • Konto: Kundenkonto und Logout. Public-Links wie Login und Registrierung gehoeren nicht in die App-Sidebar.

Webspace- und Host-Strategie

Empfohlen fuer den Start:

  • kaffeeliste.de oder www.kaffeeliste.de fuer Landingpage, Registrierung und Login.
  • app.kaffeeliste.de fuer die geschuetzte App.
  • Keine Wildcard-Subdomains fuer Kunden.
  • Mandantenauswahl nach Login ueber Session und tenant_memberships.
  • Kundeneigene feste Domains oder Subdomains erst spaeter gezielt einrichten, wenn DNS und Zertifikat pro Domain sauber geprueft sind.

Damit bleibt der Betrieb webspace-tauglich: Fuer den Start reichen zwei feste Hosts mit normalen Let's-Encrypt-Zertifikaten. Die fachliche Tenant-Aufloesung ist in M3 vorbereitet; produktive Host-Rewrites, Cookie-Domain und Zertifikats- Details gehoeren zur M8-Betriebshaertung.

Datenmodell

Empfohlen wird ein Shared-Database/Shared-Schema-Modell mit verpflichtendem tenant_id auf allen fachlichen Tabellen.

Kernschema:

tenants(
  id, slug, name, status, timezone, locale, currency_code,
  created_at, updated_at
)

tenant_settings(
  tenant_id, mark_price_cents, self_entry_enabled, paypal_enabled,
  paypal_url_template, sheet_window_days, negative_warning_cents,
  positive_highlight_cents, branding_json, updated_by_user_id
)

users(
  id, email_norm, password_hash, name, email_verified_at,
  mfa_enabled, disabled_at, last_login_at, created_at, updated_at
)

tenant_memberships(
  id, tenant_id, user_id, role, status, invited_at, joined_at,
  created_at, updated_at,
  UNIQUE(tenant_id, user_id)
)

participants(
  id, tenant_id, user_id NULL, display_name, email_norm NULL,
  paypal_name NULL, active, legacy_mitarbeiter_id,
  created_at, updated_at,
  UNIQUE(tenant_id, email_norm)
)

ledger_entries(
  id, tenant_id, participant_id, type, amount_cents, marks_count,
  unit_price_cents, booked_at, source, note, created_by_user_id,
  import_batch_id NULL, legacy_table, legacy_id,
  voided_at NULL, reversal_of_entry_id NULL,
  created_at
)

notices(
  id, tenant_id, message, valid_from, valid_until,
  created_by_user_id, deleted_at, created_at, updated_at
)

payment_import_batches(
  id, tenant_id, original_filename, checksum, status,
  created_by_user_id, created_at
)

payment_import_rows(
  id, batch_id, row_number, participant_id NULL, raw_name,
  amount_cents, booked_at, status, raw_json
)

audit_log(
  id, tenant_id, actor_user_id, action, subject_type, subject_id,
  metadata_json, ip, created_at
)

outbound_emails(
  id, tenant_id, participant_id, template, subject, status,
  sent_at, error, created_at
)

Wichtige Modellierungsregeln:

  • users sind Login-Konten.
  • participants sind Kaffee-Teilnehmer.
  • Ein Teilnehmer kann, muss aber nicht, ein Login-Konto haben.
  • Rollen gehoeren in tenant_memberships, nicht direkt auf Teilnehmer.
  • Buchungen sollten nicht hart geloescht werden.
  • Korrekturen laufen ueber Storno- oder Reversal-Eintraege.
  • Legacy-IDs werden bei Migration gespeichert, damit Ergebnisse vergleichbar bleiben.
  • Geldwerte sollten als Cent-Integer gespeichert werden, nicht als Float.

Rollenmodell

Empfohlene Rollen:

  • owner: Kunde verwalten, Billing, Admins, Loeschung, Grundeinstellungen.
  • admin: Mitglieder, Hinweise, fachliche Einstellungen, Auswertungen.
  • treasurer: Zahlungen, CSV-Import, Korrekturen, Exporte, Mails.
  • member: eigenes Dashboard, eigene Striche, eigener Anzeigename.
  • viewer: lesende Auswertungen.

Alle Rollen sind tenant-scoped. Ein User kann also bei Kunde A Admin und bei Kunde B nur Mitglied sein.

Authentifizierung und Sicherheit

SaaS-Basis:

  • E-Mail/Passwort-Login mit password_hash.
  • E-Mail-Verifikation.
  • Passwort-Reset.
  • Sichere Session-Cookies.
  • CSRF-Schutz fuer alle schreibenden Aktionen.
  • Rate-Limits fuer Login, Registrierung und Passwort-Reset.
  • Zentrale Funktionen oder Middleware: requireLogin, requireTenant, requireRole, csrfToken.

Tenant-Aufloesung:

  • Primaer serverseitig aus Subdomain, Custom Domain oder tenantgebundener Auswahl nach Login.
  • Nicht allein aus Hidden Inputs oder frei manipulierbaren IDs.
  • Jede fachliche Query braucht einen Tenant-Scope.

Spaeter moeglich:

  • LDAP/AD oder SSO pro Kunde als optionaler Identity Provider.
  • MFA fuer Owner/Admins.
  • Row-Level-Security in der Datenbank.

Design-Leitplanken

Das bestehende Design soll erhalten bleiben.

Beibehalten:

  • Gruener Akzent #38761d.
  • Weiss/Grau als ruhige Grundflaeche.
  • Roboto Slab fuer Ueberschriften.
  • Open Sans fuer Fliesstext.
  • Sidebar fuer die geschuetzte App.
  • Tabellen als primaere Darstellung fuer operative Daten.
  • Schlichte Formularfelder und Buttons.

Verbessern ohne Relaunch:

  • Hinweise als wiederverwendbare Komponente statt Inline-Style.
  • Einheitliche Erfolgs-, Fehler- und Warnmeldungen.
  • Dashboardwerte als kompakte Statusbereiche.
  • Aktionsleisten ueber Tabellen.
  • Sidebar-Gruppierung und aktive Navigation.
  • FAQ strukturieren, aber Inhalte nicht stark veraendern.

Nicht tun:

  • Kein komplett neues Farbsystem.
  • Keine dekorative Marketingoptik in der App.
  • Keine App-Tabellen in Kartenlandschaften aufloesen.
  • Keine Navigationsstruktur, die die heutigen Kernablaeufe versteckt.

Meilensteinplan

Uebersicht:

Meilenstein Schwerpunkt Hauptergebnis
M0 Baseline Bestand, Sicherheit und Designreferenz sind dokumentiert
M1 Golden Master Legacy-Ergebnisse sind als Vergleichsbasis eingefroren; HTTP-Smoke prueft sichere Seiten
M2 Technisches Fundament Abgeschlossen: Migrationen, Bootstrap, Session, CSRF-Helper und Legacy-Schreibseitenschutz stehen
M3 SaaS-Basis Abgeschlossen: Tenants, User, Registrierung, Login, Rollen, Mail-Links und zentrale Mandantenauswahl funktionieren
M4 Datenmigration Gestartet: Ledger-Tabelle, Legacy-Backfill, Paritaetscheck und Ledger-Service sind umgesetzt
M5 App-Kern Dashboard, Striche, Einzahlungen, Mitglieder und Liste laufen
M6 Betriebsflows Import, Export, Mail und Jahresprozesse sind auditierbar
M7 Landingpage Public-Seite und Auth-Seiten sind im gemeinsamen Stil nutzbar; spaetere Ausbaustufen folgen
M8 Haertung Betrieb, Datenschutz, Monitoring und Isolation sind geprueft
M9 Cutover Produktivumstellung ist vorbereitet und Legacy ist read-only

M0: Planungs- und Sicherheitsbaseline

Ziel: Den aktuellen Zustand verlaesslich dokumentieren, bevor umgebaut wird.

Arbeitsartefakte:

  • docs/m0/README.md
  • docs/m0/code-inventory.md
  • docs/m0/security-baseline.md
  • docs/m0/schema-export.sql
  • docs/m0/golden-master-queries.sql
  • docs/m0/screenshot-checklist.md

Schritte:

  • Live-DB-Schema exportieren.
  • Tabellen, Spalten, Indizes und Constraints dokumentieren.
  • Bekannte Jobs/Skripte erfassen, zum Beispiel Mailversand und Jahresauswertung.
  • Secrets inventarisieren und rotieren, insbesondere hart codierte Zugangsdaten.
  • Bestehende Seiten und UI-Zustaende per Screenshots festhalten.
  • Fachliche Kernregeln dokumentieren: Saldo, Jahreswerte, Preis pro Strich, 100-Tage-Listen, CSV-Deduplizierung, PDF-Ausgabe.

Ergebnis:

  • Datenkatalog.
  • Prozesslandkarte.
  • Designreferenz.
  • Liste kritischer Sicherheitsrisiken.

Abhaengigkeiten:

  • Zugriff auf echte oder anonymisierte Datenbank.
  • Kenntnis der Produktivumgebung.

M1: Golden-Master-Validierung

Ziel: Sicherstellen, dass spaetere neue Berechnungen dieselben Ergebnisse wie der Bestand liefern.

Schritte:

  • Referenzdatensatz aus Legacy erzeugen. Erledigt als rekonstruierter Golden Master in der MySQL-Dev-Datenbank.
  • Pro Mitglied berechnen: Gesamteinzahlungen, Gesamtausgaben, Gesamtstriche, aktueller Stand, Jahreswerte. Erledigt mit scripts/check-golden-master.php.
  • CSV-Importfaelle sammeln: Treffer, Dubletten, unbekannte Namen. Erledigt im Golden-Master-Check.
  • Testfaelle fuer Guthaben, Schulden, Nullsaldo und inaktive Teilnehmer anlegen. Erledigt.
  • Sichere GET-Seiten per HTTP-Smoke pruefen. Erledigt mit scripts/http-smoke.php.
  • PDF-/Export-Summen als Referenz sichern. Offen, weil die TCPDF-Kopie im Repo unvollstaendig ist.

Ergebnis:

  • Golden-Master-Daten.
  • Vergleichsqueries oder Vergleichsskript.
  • HTTP-Smoke-Test fuer sichere UI-Seiten.
  • Akzeptanzkriterien fuer Migration und neue App.
  • Dokumentierte offene Punkte: PDF-Export/TCPDF, PHPMailer-Abhaengigkeit, GET-Nebenwirkungen bei Mailversand und Jahresauswertung.

Abhaengigkeiten:

  • M0 abgeschlossen.
  • PDF-/Mail-/Jahresprozesse werden in M6 gezielt neu gestaltet, statt sie in M1 per GET-Smoke auszufuehren.

M2: Technisches Fundament

Ziel: Eine saubere Basis fuer App, Public-Seiten, Auth und Mandanten schaffen.

Schritte:

  • Projektstruktur festlegen: Public-Routes, App-Routes, Views/Templates, Services/Repositories.
  • Zentrales Bootstrap fuer Config, DB-Verbindung, Session und Fehlerbehandlung. Begonnen mit app/bootstrap.php.
  • Versionierte Migrationen einfuehren. Begonnen mit database/migrations/0001_legacy_mysql_baseline.sql und scripts/migrate.php.
  • Layouts trennen: Public-Layout und App-Layout. Noch offen; Header/Footer bleiben vorerst Legacy-Wrapper.
  • Bestehende Assets weiterverwenden.
  • CSRF- und Session-Basis einziehen. Session und CSRF-Helper sind vorhanden; globale Erzwingung erfolgt schrittweise pro POST-Seite. Erste Seiten sind abgesichert: hinweise.php, mitarbeiterverwalten.php, namenanpassen.php, index.php, stricheintragen.php, einzahlung.php, letzteneintraege.php, csvupload.php.
  • CSV-Upload ausserhalb des Webroots speichern. In M2 als Legacy-Haertung umgesetzt: temporaer unter var/uploads, Dateityp-/Groessenpruefung und Loeschung nach Verarbeitung.
  • Konfigurationswerte aus Code in Umgebung oder Settings verschieben.

Ergebnis:

  • Grundgeruest fuer neue SaaS-App.
  • Kein fachlicher Rewrite, aber klare Struktur fuer die Migration.
  • Dokumentation: docs/m2-technical-foundation.md.
  • Status: abgeschlossen fuer den M2-Scope.

Abhaengigkeiten:

  • Entscheidung, ob PHP nativ weitergefuehrt oder ein Framework genutzt wird.
  • M2 bleibt bewusst ohne Tenant-/User-/Rollen-Tabellen; diese starten in M3.

M3: Mandanten, Registrierung und Login

Ziel: Mehrkundenfaehigkeit und Kunden-Onboarding technisch aktivieren.

Schritte:

  • Tabellen fuer tenants, users, tenant_memberships und tenant_settings anlegen. Vorbereitung dokumentiert in docs/m3-saas-basis-vorbereitung.md: erster Schritt erledigt.
  • Zusaetzlich participants als getrennte Kaffee-Teilnehmer-Tabelle anlegen: erledigt.
  • Default-Tenant fuer den aktuellen Bestand anlegen: erledigt.
  • Bestehende kl_Mitarbeiter idempotent in participants spiegeln: erledigt.
  • Registrierung: Tenant + Owner-User + Default-Settings erzeugen: erster Flow erledigt.
  • Login und Logout bauen: erster Flow erledigt.
  • Passwort-Reset und E-Mail-Verifikation bauen: Dev-Flow mit Single-Use-Tokens und Mail-Transport-Abstraktion erledigt.
  • Tenant-Aufloesung definieren: zentrale App-Domain mit Session-Kontext und Mandantenauswahl erledigt; feste Domains vorbereitet, keine Wildcards.
  • Rollenpruefung zentralisieren: erster Owner/Admin-Check erledigt.
  • Erste Admin-/Owner-Seite fuer Grundeinstellungen: erledigt.
  • Erste Public-Landingpage mit CTA zu Login und Registrierung: erledigt.
  • Login, Registrierung, Passwort-Reset und E-Mail-Verifikation im Public-Stil: erledigt.
  • App-Sidebar ohne Public-Login-/Registrierungslinks: erledigt.

Ergebnis:

  • Ein neuer Kunde kann sich registrieren und in seine eigene App gelangen.
  • Rollen und Tenant-Kontext sind serverseitig verfuegbar.
  • Reset- und Verifikationslinks koennen im Dev-Modus geloggt und produktiv ueber einen konfigurierten Mail-Transport versendet werden.
  • Status: abgeschlossen fuer den M3-Scope.

Abhaengigkeiten:

  • M2 abgeschlossen.

M4: Migration des fachlichen Kerns

Ziel: Bestehende Kaffeelisten-Daten tenant-sicher uebernehmen.

Schritte:

  • Initialen Tenant fuer den bisherigen Bestand anlegen: erledigt in M3.
  • kl_Mitarbeiter nach participants migrieren: erledigt in M3.
  • admin-Informationen in tenant_memberships oder Admin-Rollen ueberfuehren: erledigt in M3.
  • kl_config nach tenant_settings migrieren: erledigt in M3.
  • ledger_entries als tenant-sichere Buchungstabelle anlegen: erledigt.
  • kl_Einzahlungen und kl_Kaffeeverbrauch additiv nach ledger_entries spiegeln: erster Backfill erledigt.
  • Legacy-IDs speichern: erledigt ueber legacy_table und legacy_id.
  • Salden gegen Golden-Master vergleichen: Kontrollskript erledigt.
  • Ledger-Service fuer Tenant-Summen, Teilnehmer-Summen und letzte Buchungen: erledigt.

Ergebnis:

  • Bestehender Datenbestand kann im neuen Modell abgebildet werden.
  • Saldenparitaet ist ueber scripts/check-m4-ledger-migration.php nachweisbar.
  • Erste App-Abfragen koennen ueber app/ledger.php tenant-sicher aus dem neuen Modell lesen.
  • Dokumentation: docs/m4-data-migration.md.

Abhaengigkeiten:

  • M1 und M3 abgeschlossen.

M5: Geschuetzte App-Funktionen

Ziel: Die operativen Kernseiten im neuen Modell bereitstellen.

Schritte:

  • Dashboard Meine Kaffeeliste umsetzen.
  • Eigene Stricherfassung umsetzen.
  • Zahlungs-/PayPal-Bereich umsetzen.
  • Mitgliederverwaltung tenant- und rollenbasiert umsetzen.
  • Gesamtuebersicht umsetzen.
  • Letzte Eintraege und Korrekturen als Storno statt Delete umsetzen.
  • Hinweise als tenant-spezifische Notices umsetzen.

Ergebnis:

  • Ein Kunde kann seine Kaffeeliste operativ nutzen.
  • App sieht weiterhin nach bestehender Kaffeeliste aus.

Abhaengigkeiten:

  • M4 abgeschlossen.

M6: Import, Export und Mail

Ziel: Admin- und Treasurer-Flows produktionsreif machen.

Schritte:

  • CSV-Import mit Vorschau, Dublettenpruefung und Audit bauen.
  • Uploads ausserhalb des Webroots speichern.
  • PDF-/Listenexport aus neuem Datenmodell bauen.
  • Mailversand als nachvollziehbaren Versandjob mit Dry-Run und Versandlog gestalten.
  • Jahresauswertung beziehungsweise Jahresbuchungen tenant-sicher abbilden.

Ergebnis:

  • Kassenverwaltung ist fuer reale Betriebsablaeufe vollstaendig.
  • Import/Export/Mail sind auditierbar.

Abhaengigkeiten:

  • M5 fuer die Kernansichten.

M7: Oeffentliche Landingpage

Ziel: Werbliche Einstiegseite und Registrierung verfuegbar machen, ohne die App-Optik zu verwischen.

Schritte:

  • Public-Layout mit bestehender Typografie und gruenem Akzent bauen. Erster Stand als landing.php und assets/css/public.css erledigt.
  • Landingpage-Inhalte erstellen. Erster Stand erledigt.
  • Demo-Screenshot oder Demo-Ansicht einbinden.
  • CTA zu Registrierung und Login. Erledigt.
  • Login, Registrierung und Passwort-Reset in den Public-Stil integrieren. Erledigt.
  • App-Sidebar von Public-Links trennen. Erledigt.
  • FAQ-Auszug strukturieren.
  • Keine App-Sidebar im Public-Bereich.

Ergebnis:

  • Interessenten verstehen das Produkt und koennen sich registrieren.
  • Bestehende App bleibt optisch eigenstaendig und arbeitsorientiert.

Abhaengigkeiten:

  • M3 fuer Registrierung.
  • M5 fuer echte App-Screens oder Demo.

M8: Haertung, Datenschutz und Betrieb

Ziel: Die SaaS-App fuer mehrere Kunden sicher betreiben.

Schritte:

  • Backups und Restore-Prozess definieren.
  • Monitoring und Fehlerlogging einrichten.
  • Audit-Log fuer Admin-Aktionen pruefen.
  • Datenexport pro Tenant.
  • Loesch-/Anonymisierungsprozess fuer Teilnehmer und Kunden.
  • Rate-Limits und Security Headers.
  • Mandanten-Isolation testen.
  • Rollenmatrix testen.

Ergebnis:

  • SaaS ist betrieblich und datenschutzseitig belastbarer.

Abhaengigkeiten:

  • M3 bis M6.

M9: Cutover und Legacy-Archiv

Ziel: Produktive Umstellung ohne Datenverlust.

Schritte:

  • Legacy fuer Schreibzugriffe sperren.
  • Finalen Delta-Export ziehen.
  • Migration ausfuehren.
  • Rowcounts, Salden, PDF-Stichproben und Importhistorie pruefen.
  • DNS oder Reverse Proxy umschalten.
  • Legacy 30 bis 90 Tage read-only als Archiv behalten.
  • Rollback-Fenster und Vorgehen dokumentieren.

Ergebnis:

  • Neuer SaaS-Betrieb ist live.
  • Alter Bestand bleibt fuer Rueckfragen lesbar.

Abhaengigkeiten:

  • M8 abgeschlossen.

Empfohlene MVP-Reihenfolge

Fuer den ersten produktnahen MVP sollten nicht alle Randmodule gleichzeitig umgebaut werden.

MVP-Paket:

  1. Tenant, User, Login, Registrierung.
  2. Mail-Links, zentrale Mandantenauswahl und erste Landingpage.
  3. Teilnehmer, Settings, Ledger.
  4. Dashboard, Striche, Einzahlungen, Gesamtuebersicht.
  5. Mitgliederverwaltung.
  6. Hinweise.
  7. CSV-Import, Export.

Spaeter:

  • Umfrage-Modul.
  • SSO/LDAP pro Kunde.
  • Billing/Tarife.
  • MFA.
  • Custom Domains.
  • Erweiterte Mandanten-Branding-Optionen.

Validierung

Fachliche Pruefungen:

  • Saldo je Teilnehmer alt gegen neu.
  • Jahreswerte alt gegen neu.
  • Gesamtstriche alt gegen neu.
  • Einzahlungen alt gegen neu.
  • Export-Summen alt gegen neu.
  • CSV-Import: identische Treffer- und Dublettenlogik.

Sicherheitspruefungen:

  • Fremde Tenant-IDs liefern keine Daten.
  • Fremde Teilnehmer-IDs liefern keine Daten.
  • Admin-Funktionen sind ohne Rolle blockiert.
  • Alle POST-Aktionen brauchen CSRF.
  • Uploads sind nicht direkt ausfuehrbar.
  • Ausgabe von Namen, Mails und Hinweisen ist escaped.

UX-Pruefungen:

  • Kernseiten bleiben optisch wiedererkennbar.
  • Sidebar bleibt fuer App-Nutzer vertraut.
  • Landingpage zeigt keine App-Adminnavigation.
  • Mobile Darstellung bleibt bedienbar.
  • Tabellen bleiben lesbar.

Risiken und Gegenmassnahmen

Risiko Gegenmassnahme
Tenant-Leak durch vergessene Query-Filter Zentrale Repository-/Query-Schicht, Tests mit zwei Tenants
Falsche Salden nach Migration Golden-Master-Vergleich vor Cutover
Harte Deletes verlieren Audit-Historie Storno-/Reversal-Modell fuer Buchungen
Login und Teilnehmer werden vermischt users und participants strikt trennen
Bestehendes Design driftet weg Designreferenz und App-Komponenten definieren
CSV-Upload unsicher Upload ausserhalb Webroot, Dateityppruefung, Importvorschau
Mailversand nicht nachvollziehbar Versandlog, Dry-Run, Job-Status
Unvollstaendige Vendor-Kopien fuer PDF/Mail Dependencies sauber vendoren oder ersetzen, Smoke-Tests danach erweitern
AD/LDAP blockiert SaaS-Onboarding E-Mail/Passwort als Basis, SSO spaeter optional
Kein DB-Schema im Repo Schema exportieren und Migrationen einfuehren

Offene Entscheidungen

  • Soll die neue App weiterhin nativ in PHP entstehen oder mit einem Framework?
  • Soll SQL Server bleiben oder mittelfristig eine andere Datenbank genutzt werden?
  • Wie sollen Kunden-Tenants adressiert werden: Subdomain, Pfad oder Auswahl nach Login?
  • Welche Rolle soll treasurer haben: eigene Rolle oder Teil von admin?
  • Wird das Umfrage-Modul Teil des SaaS-Produkts oder nur archiviert?
  • Braucht der MVP schon Tarife/Billing oder erstmal nur Registrierung?
  • Sollen bestehende Kunden per Einladung oder per Self-Service onboarden?

Naechster konkreter Arbeitsschritt

Als naechstes sollte M0 gestartet werden:

  1. Produktiv-/Testdatenbankschema exportieren.
  2. Screenshot-Referenz der wichtigsten Seiten erstellen.
  3. Golden-Master-Auswertungen definieren.
  4. Entscheidung treffen, ob der neue SaaS-Kern im bestehenden PHP-Stil oder mit einem Framework aufgebaut wird.