M5: Hinweise auf tenant-scoped Notices umziehen, Mitgliederzugang auf Rollen umstellen
Hinweise: - Neue Tabelle notices (tenant-scoped, Soft-Delete via deleted_at) loest die global unscoped kl_hinweise als aktive Datenquelle ab; Migration uebernimmt einmalig aktuell gueltige kl_hinweise-Eintraege fuer den Default-Mandanten. kl_hinweise bleibt als Golden-Master-Referenz stehen. - hinweise.php und der Banner in header.php sind tenant-scoped umgestellt. Mitgliederverwaltung: - mitarbeiterverwalten.php verwaltet jetzt participants (tenant-scoped) statt der global unscoped kl_Mitarbeiter-Tabelle als primaere Quelle. Das behebt nebenbei ein Mandanten-Datenleck: jeder SaaS-Mandant mit Owner/Admin-Rolle haette zuvor die komplette Default-Mandanten- Mitgliederliste sehen und bearbeiten koennen. - Fuer den Default-Mandanten bleibt Dual-Write nach kl_Mitarbeiter bestehen, damit stricheintragen.php/einzahlung.php weiter funktionieren; andere Mandanten werden rein participant-nativ verwaltet. - Die Legacy-Administrator-Checkbox ist raus. Stattdessen kann ein Admin je Mitglied unabhaengig von Name/E-Mail einen Login-Zugang mit Rolle (member/treasurer/admin) gewaehren oder entziehen (saas_grant_participant_access / saas_revoke_participant_access). Einladung laeuft ueber den bestehenden Passwort-Reset-Mechanismus, Entzug setzt die Mitgliedschaft auf revoked statt sie zu loeschen. - Kompletter Flow live getestet: anlegen, Zugang gewaehren, Einladungsmail, Passwort setzen, Login, Rollenschutz, Zugang entziehen, Login-Sperre. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+92
-3
@@ -167,13 +167,98 @@ Bewusst nicht umgesetzt:
|
||||
Admin-Rollen für neue SaaS-Nutzer laufen bis dahin weiter über
|
||||
`scripts/backfill-default-tenant.php` oder die Registrierung.
|
||||
|
||||
## Fortsetzung: Hinweise und rollenbasierter Zugang
|
||||
|
||||
Umgesetzte Dateien:
|
||||
|
||||
```text
|
||||
database/migrations/0007_saas_notices.sql
|
||||
app/notices.php
|
||||
hinweise.php
|
||||
header.php
|
||||
mitarbeiterverwalten.php (grundlegend neu)
|
||||
app/ledger.php (Participant-CRUD)
|
||||
app/saas-auth.php (Zugangsvergabe/-entzug)
|
||||
app/saas-mail.php (Einladungsmail)
|
||||
```
|
||||
|
||||
### Hinweise auf Notices umgezogen
|
||||
|
||||
- Neue Tabelle `notices` (tenant-scoped, mit `deleted_at` für Soft-Delete)
|
||||
ersetzt `kl_hinweise` als aktive Datenquelle. `kl_hinweise` bleibt
|
||||
unangetastet als Golden-Master-Referenz.
|
||||
- Die Migration übernimmt einmalig alle zum Migrationszeitpunkt noch
|
||||
gültigen `kl_hinweise`-Einträge in `notices` des Default-Mandanten, damit
|
||||
keine sichtbaren Banner verloren gehen.
|
||||
- `hinweise.php` liest/schreibt jetzt ausschließlich `notices`, tenant-scoped
|
||||
mit dem gleichen Rollen-/Legacy-Fallback-Muster wie andere Admin-Seiten.
|
||||
Löschen ist ein Soft-Delete (`deleted_at`), kein Hard-Delete.
|
||||
- `header.php` (Banner-Anzeige auf allen App-Seiten) löst den Mandanten
|
||||
jetzt selbst auf (SaaS-Session oder Default-Tenant-Fallback) und zeigt den
|
||||
aktuell gültigen Hinweis dieses Mandanten statt eines global-legacy
|
||||
Hinweises.
|
||||
|
||||
### Mitgliederverwaltung: participant-nativ mit Rollen-Zugang
|
||||
|
||||
`mitarbeiterverwalten.php` wurde grundlegend umgebaut, nicht mehr additiv
|
||||
gepatcht:
|
||||
|
||||
- Datenquelle ist jetzt `participants` (tenant-scoped), nicht mehr die
|
||||
global unscoped `kl_Mitarbeiter`-Tabelle. Das behebt nebenbei ein
|
||||
Datenleck: Da `kl_Mitarbeiter` keine `tenant_id` hat, hätte jeder
|
||||
SaaS-Mandant mit Owner/Admin-Rolle über die vorherige Version dieser
|
||||
Seite die komplette Mitgliederliste des Default-Mandanten sehen und
|
||||
bearbeiten können.
|
||||
- Für den Default-Mandanten wird weiterhin dual-write nach
|
||||
`kl_Mitarbeiter` betrieben (`ledger_create_participant()`,
|
||||
`ledger_update_participant()`, `ledger_set_participant_active()`), damit
|
||||
`stricheintragen.php` und `einzahlung.php` (deren Mitarbeiter-Picker
|
||||
weiterhin direkt aus `kl_Mitarbeiter` liest) neue Mitglieder sofort
|
||||
anzeigen. Andere Mandanten haben keine Legacy-Schattentabelle und werden
|
||||
rein participant-nativ verwaltet.
|
||||
- Die Legacy-„Administrator"-Checkbox ist aus dem Anlegen-/Bearbeiten-
|
||||
Formular entfernt. Stattdessen gibt es je Mitglied eine eigene
|
||||
„Zugang"-Spalte: Rolle wählen (`member`, `treasurer`, `admin`) und
|
||||
„Zugang gewähren", oder bei bestehendem Zugang Rolle ändern beziehungsweise
|
||||
„Zugang entziehen". `owner` ist über diese UI nicht vergebbar oder
|
||||
entziehbar (nur bei Registrierung gesetzt).
|
||||
- Name und E-Mail eines Mitglieds (`participants.display_name`/`email`)
|
||||
bleiben unabhängig vom Login: Ein Mitglied kann ohne jeden Zugang
|
||||
existieren (nur für Kaffeeliste/Benachrichtigung), und ein Zugang kann
|
||||
jederzeit gewährt oder entzogen werden, ohne den Mitgliedsdatensatz zu
|
||||
berühren.
|
||||
- Zugangsvergabe (`saas_grant_participant_access()`) legt bei Bedarf einen
|
||||
`users`-Datensatz ohne Passwort an, setzt/aktualisiert die
|
||||
`tenant_memberships`-Rolle und verknüpft `participants.user_id`.
|
||||
Anschließend wird ein Einladungslink über den bestehenden
|
||||
Passwort-Reset-Mechanismus verschickt (`saas_send_invite_mail()`, gleicher
|
||||
Token-Typ `password_reset`, gleiche Zielseite
|
||||
`passwort-zuruecksetzen.php` wie beim regulären Passwort-Reset).
|
||||
- Zugangsentzug (`saas_revoke_participant_access()`) setzt die
|
||||
`tenant_memberships`-Zeile auf `status = 'revoked'`, statt sie zu löschen
|
||||
oder den `user_id`-Verweis zu entfernen. Der Zugang kann später erneut
|
||||
gewährt werden, ohne den Account neu anzulegen. Der Login prüft bereits
|
||||
überall auf `tm.status = 'active'`, wodurch ein entzogener Zugang sofort
|
||||
wirkt.
|
||||
- Live gegen die Dev-Datenbank getestet: Mitglied anlegen (inklusive
|
||||
Dual-Write-Check), Zugang mit Rolle `treasurer` gewähren, Einladungsmail
|
||||
geprüft, Passwort über den Einladungslink gesetzt, erfolgreicher Login,
|
||||
Rollenschutz geprüft (kein Zugriff auf `mitarbeiterverwalten.php`, Zugriff
|
||||
auf `kaffeeliste.php`), Zugang entzogen, anschließender Login-Versuch
|
||||
korrekt mit „kein aktiver Mandant" abgelehnt.
|
||||
|
||||
## Noch offen
|
||||
|
||||
- Eigene PayPal-/Zahlungsbereich als eigenständiger App-Screen (aktuell nur im
|
||||
Dashboard integriert).
|
||||
- Einladungs-Flow, um bestehenden Teilnehmern nachträglich einen
|
||||
Login-Account mit `tenant_memberships`-Rolle zuzuweisen.
|
||||
- Hinweise als tenant-spezifische Notices umsetzen.
|
||||
- `stricheintragen.php` und `einzahlung.php` lesen ihre Mitarbeiter-Picker
|
||||
weiterhin aus der global unscoped `kl_Mitarbeiter`-Tabelle. Für den
|
||||
Default-Mandanten funktioniert das unverändert; für jeden anderen Mandanten
|
||||
ist die Liste faktisch leer beziehungsweise zeigt (nur lesend, Schreiben
|
||||
schlägt dank Tenant-Scope in `ledger_mirror_legacy_*` sicher fehl) die
|
||||
Namen der Default-Mandanten-Mitglieder an. Das ist ein bestehendes,
|
||||
eigenständiges Scope-Thema für eine spätere Iteration, keine Regression
|
||||
dieser Session.
|
||||
- Export, Mail und Jahresprozesse bleiben M6-Themen.
|
||||
|
||||
## Aktueller Prüfstatus
|
||||
@@ -187,3 +272,7 @@ Bewusst nicht umgesetzt:
|
||||
- Live-Test der Mitgliederverwaltung gegen die Dev-DB: Anlegen (inklusive
|
||||
XSS-Payload-Check), Deaktivieren, participants-Spiegelung erfolgreich
|
||||
geprüft.
|
||||
- Live-Test Hinweise/Notices: Carry-over-Migration, Anlegen mit HTML-Payload
|
||||
(korrekt escaped), Soft-Delete, Banner-Anzeige auf Mandant geprüft.
|
||||
- Live-Test Zugangsvergabe/-entzug: kompletter Flow von Einladung bis
|
||||
Login-Sperre nach Entzug erfolgreich geprüft (siehe oben).
|
||||
|
||||
Reference in New Issue
Block a user