Rollen, Rechte & Modul-Zugriffe
Drei DB-Rollen plus Modul-Zugriff pro Person bilden das Berechtigungsmodell ab. Erzwungen auf Datenbank-Ebene über Row Level Security — versteckte UI-Buttons sind nie die einzige Verteidigung.
Jede Person in einem Restaurant trägt genau eine Rolle. Auf diese Rolle wird die Modul-Zugriffsliste pro Person draufgelegt — so können zwei Manager unterschiedliche Module sehen, je nach Workspace-Konfiguration.
DB-Rollen
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| admin | role | — | — | Volle operative Macht im Restaurant. Sieht alle Module, verwaltet Team und Reservierungsregeln. Beim ersten Setup wird der Workspace-Inhaber automatisch admin in seinem Restaurant. |
| manager | role | — | — | Wie admin, aber ohne Zugriff auf Abrechnung und einige Konfigurations-Pfade. Typisch für stellvertretende Leitung oder Schichtleitung mit Verwaltungs-Verantwortung. |
| employee | role | — | — | Operative Rolle. Sieht standardmäßig nur ihre zugewiesenen Module — z.B. Service-Personal nur Reservierungen, Wissen und Chat. Modul-Zugriff wird pro Person feinjustiert. |
Onboards eigene Support-Rolle. CEO/Platform-Admins sind weder Mitarbeiter eines Restaurants noch sehen sie es im Tagesgeschäft — sie können aber für Support-Zwecke standortübergreifend zugreifen. Jede Aktion eines platform_admin wird im Audit-Log gesondert markiert.
Modul-Zugriff
Zusätzlich zur Rolle bekommt jede Person eine Liste von Modulen, auf die sie zugreifen darf. Die Liste wird beim Einladen vorbelegt — Manager bekommen alles, Mitarbeiter nichts —, und Admins können sie pro Person anpassen. Beispiel: Ein Bartender sieht „Reservierungen" und „Chat", aber nicht „Berichte". Eine Verwaltungsfachkraft sieht „Berichte" und „Gutscheine", aber nicht „Schichten".
Wie Zugriff erzwungen wird
Modul-Zugriff wird in drei Schichten geprüft, die alle übereinstimmen müssen:
- Middleware. Lehnt RSC-Requests auf Modul-URLs ab, für die der Nutzer keinen Zugriff hat. Verhindert direkte Page-Hits.
- Server-side guard. Jede modulgebundene Server-Komponente ruft
assertModuleAccess(). Schließt static-generation und fetch-Bypasses ab. - Datenbank-RLS. Postgres-Policies prüfen restaurant_id und role aus dem JWT. Selbst wenn Middleware und Guard fehlschlagen würden, gibt die Datenbank keine Cross-Tenant-Zeile heraus.
Mehrere Standorte
Bei mehreren Standorten kann eine Person pro Standort eine eigene Rolle haben — Admin im Stammhaus, Manager in der Filiale, gar keine Rolle in der Bar. Die Daten sind pro Standort isoliert; RLS-Policies erzwingen das auf Datenbank-Ebene. Mehr zur Standort-Trennung.