Merge branch 'feat/sap-om-org-model'
This commit is contained in:
34
README.md
34
README.md
@@ -54,14 +54,18 @@ Liste. Kurzfassung:
|
||||
|
||||
| Variable | Sichtbarkeit | Zweck |
|
||||
|---|---|---|
|
||||
| `NEXT_PUBLIC_SUPABASE_URL` | Browser + Server | Supabase-Projekt-URL |
|
||||
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Browser + Server | Anon-Key, RLS-gebunden |
|
||||
| `SUPABASE_SERVICE_ROLE_KEY` | **Nur Server** | Umgeht RLS vollständig — niemals im Browser-Bundle, niemals loggen |
|
||||
| `DATABASE_URL` | Nur Server | PostgreSQL-Verbindung. Die Rolle darf **kein** `BYPASSRLS` haben |
|
||||
| `DATABASE_SSL` | Nur Server | `false` für lokal/CI ohne TLS |
|
||||
| `AUTH_SECRET` | Nur Server | Signiert und verschlüsselt das Sitzungscookie |
|
||||
| `AUTH_MICROSOFT_ENTRA_ID_ID` | Nur Server | Anwendungs-ID der Entra-Registrierung |
|
||||
| `AUTH_MICROSOFT_ENTRA_ID_SECRET` | Nur Server | Client-Geheimnis dazu |
|
||||
| `AUTH_MICROSOFT_ENTRA_ID_ISSUER` | Nur Server | Aussteller mit Mandanten-ID — nicht `common` |
|
||||
| `CRON_SECRET` | Nur Server | Schützt `/api/cron/apply-pending-changes` |
|
||||
|
||||
`NEXT_PUBLIC_*`-Werte werden beim Build in das Client-Bundle eingebacken —
|
||||
eine Änderung erfordert einen Rebuild, nicht nur einen Neustart (relevant
|
||||
für Docker-Deployments, siehe unten).
|
||||
**Es gibt keine `NEXT_PUBLIC_*`-Variablen mehr.** Nichts wird in das
|
||||
Browser-Bundle eingebacken, weil der Browser mit nichts ausser der Anwendung
|
||||
selbst spricht. Ein Docker-Abbild ist damit umgebungsneutral: einmal gebaut,
|
||||
überall dasselbe — vorher brauchte jede Umgebung ihr eigenes.
|
||||
|
||||
## Scripts
|
||||
|
||||
@@ -84,11 +88,16 @@ für Docker-Deployments, siehe unten).
|
||||
Ersatzkontrolle.
|
||||
- **Ein Rollenmodell:** `profiles.role = 'hr'` + `profiles.is_active = true`,
|
||||
geprüft über die SQL-Funktion `is_hr_user()`. Kein Sub-Rollensystem —
|
||||
siehe [`docs/data-model.md`](docs/data-model.md#zugriffsmodell).
|
||||
- **Service-Role-Key ist server-only.** Einzige Verwendung:
|
||||
`lib/supabase/admin.ts`, geschützt durch `import "server-only"` (macht
|
||||
einen versehentlichen Client-Import zu einem Build-Fehler statt einem
|
||||
Laufzeitproblem).
|
||||
siehe [`docs/datenkatalog.md`](docs/datenkatalog.md#zugriffsschutz).
|
||||
- **Es gibt keinen privilegierten Zugang mehr.** Der Dienstschlüssel, der RLS
|
||||
aushebelte, ist ersatzlos entfallen; auch der nächtliche Lauf benutzt
|
||||
dieselbe Rolle ohne `BYPASSRLS`. Was ohne angemeldete Person laufen muss,
|
||||
steht als `SECURITY DEFINER`-Funktion in der Datenbank und prüft dort
|
||||
selbst, was es tut.
|
||||
- **Jede Abfrage läuft in einer Transaktion mit gesetztem Sitzungskontext.**
|
||||
Die Kysely-Instanz wird nicht exportiert — der einzige Weg an die Datenbank
|
||||
ist `withUser()` (`lib/db/index.ts`), und eine ESLint-Regel verbietet den
|
||||
Import von `pg` ausserhalb von `lib/db/`.
|
||||
- **Audit-Log ist transaktional in der Datenbank**, nicht im App-Code: jede
|
||||
mutierende SQL-Funktion schreibt ihren `audit_log`-Eintrag in derselben
|
||||
Transaktion wie die Änderung selbst. Details und Prüfung siehe
|
||||
@@ -113,7 +122,8 @@ für Docker-Deployments, siehe unten).
|
||||
## Supabase-Hinweise
|
||||
|
||||
- Schema-Quelle der Wahrheit: `supabase/migrations/`. Menschlich lesbare
|
||||
Zusammenfassung: [`docs/data-model.md`](docs/data-model.md).
|
||||
Fassung, aus der laufenden Datenbank erzeugt:
|
||||
[`docs/datenkatalog.md`](docs/datenkatalog.md).
|
||||
- Migrationen einspielen: `supabase db push` (gegen das verlinkte Projekt)
|
||||
bzw. `supabase start` + automatische Anwendung für lokale Entwicklung.
|
||||
- `supabase/seed.ts` und `.env.test.local` sind nur für lokale
|
||||
|
||||
Reference in New Issue
Block a user