# M3 SaaS-Basis Vorbereitung Stand: 2026-07-12 M3 fuehrt Mandanten, Benutzer, Mitgliedschaften und Grundeinstellungen additiv ein. Die bestehende Legacy-App bleibt dabei lauffaehig und wird noch nicht auf das neue Modell umgestellt. ## Ziel - Einen Default-Tenant fuer den aktuellen Bestand erzeugen. - Login-Benutzer und Kaffee-Teilnehmer fachlich trennen. - Rollen tenant-spezifisch vorbereiten. - Bestehende `kl_Mitarbeiter` ohne Datenverlust in `participants` spiegeln. - Die Grundlage fuer Registrierung und Login schaffen, ohne die Legacy-Auth sofort zu ersetzen. ## Nicht-Ziele fuer den ersten M3-Schritt - Kein kompletter Login-Umbau in einem Schritt. - Keine Migration von Einzahlungen und Kaffeeverbrauch nach `ledger_entries`; das gehoert zu M4. - Kein Design- oder Layout-Umbau. - Kein Billing, keine Tarife, keine E-Mail-Verifikation im ersten Schritt. - Kein produktiver Tenant-Wechsel in bestehenden Legacy-Seiten. ## Vorgeschlagene Migration Naechste Migration: ```text database/migrations/0002_saas_identity_tenants.sql ``` Tabellen: - `tenants` - `tenant_settings` - `users` - `tenant_memberships` - `participants` Wichtige Regeln: - `users` sind Login-Konten. - `participants` sind Kaffeelisten-Teilnehmer. - Ein `participant` kann optional auf einen `user` zeigen. - Rollen liegen in `tenant_memberships`, nicht in `participants`. - `participants.legacy_mitarbeiter_id` speichert die alte ID aus `kl_Mitarbeiter`. - Geldwerte in neuen Settings als Cent-Integer speichern. ## Default-Tenant Fuer den Bestand wird ein erster Tenant angelegt: ```text slug: default name: Kaffeeliste Bestand status: active timezone: Europe/Berlin locale: de-DE currency_code: EUR ``` Die Werte koennen spaeter in einer Tenant-Einstellungsseite angepasst werden. ## Backfill-Vorschlag Ein separates Skript sollte die bestehenden Mitarbeiter spiegeln: ```text scripts/backfill-default-tenant.php ``` Vorgang: 1. Default-Tenant anlegen oder laden. 2. `tenant_settings` aus `kl_config` erzeugen. 3. Fuer jede Zeile aus `kl_Mitarbeiter` einen `participant` anlegen oder aktualisieren. 4. Fuer aktive Admins optional einen `user` und eine `tenant_membership` erzeugen. 5. `admin = 1` als Rolle `admin` abbilden; ein konfigurierter erster Benutzer kann Rolle `owner` erhalten. Der Backfill muss idempotent sein und darf keine bestehenden Legacy-Daten loeschen. ## Erste Akzeptanzkriterien - Migrationen laufen mehrfach ohne Fehler. - Default-Tenant existiert genau einmal. - `tenant_settings` enthalten Preis pro Strich und bestehende PayPal-Optionen. - Jeder bestehende `kl_Mitarbeiter` hat genau einen `participant`. - `participants.legacy_mitarbeiter_id` ist gesetzt. - Admins werden als tenant-scoped Rolle abgebildet. - Golden-Master und HTTP-Smoke bleiben gruen. ## Risiken | Risiko | Gegenmassnahme | | --- | --- | | Login-User und Kaffee-Teilnehmer werden vermischt | `users` und `participants` strikt getrennt halten | | Mehrfacher Backfill erzeugt Duplikate | Eindeutige Constraints und Upsert-Logik | | Legacy-App bricht durch neue Tabellen | M3 nur additiv, keine Legacy-Queries umstellen | | Rollen werden global statt tenant-scoped | Rollen ausschliesslich in `tenant_memberships` speichern | | Falsche Owner-Zuordnung | Owner per Env-Konfiguration oder manuell dokumentierter Entscheidung setzen | ## Empfohlene Reihenfolge 1. Migration `0002_saas_identity_tenants.sql` erstellen. 2. `scripts/backfill-default-tenant.php` erstellen. 3. Backfill gegen die Dev-Datenbank ausfuehren. 4. Kontrollskript fuer Tenant/Participant/Role-Counts schreiben. 5. Golden-Master und HTTP-Smoke ausfuehren. 6. Danach Login-/Registrierungsrouten planen.