Wofür das Modul gedacht ist
Projekt-Einstellungen ist Teil des aktiven Modul-Katalogs und deckt einen klaren Ausschnitt des Produktalltags ab.
Globale Projekteinstellungen, Leitplanken und Defaults steuern. Im tenantweiten Kontext sorgt der Bereich dafür, dass wiederkehrende Entscheidungen, Stammdaten oder Übersichten nicht in Nebensysteme ausweichen müssen.
Projekt-Einstellungen ist als eigenständiger Produktbaustein gedacht. Gerade deshalb lohnt sich ein Blick darauf, wie der Bereich mit Rollen, Datenkontext und angrenzenden Modulen zusammenspielt.
Typische Einsatzfälle
Diese Situationen zeigen, wann der Bereich in einem sauberen Rollout oder im laufenden Betrieb konkret Mehrwert liefert.
Tenant sauber aufsetzen
Das Modul hilft dabei, organisatorische Regeln und Stammdaten an einer kontrollierten Stelle zu pflegen.
Verantwortung eingrenzen
Governance-Bereiche sollten nur wenige Personen pflegen, damit die Struktur stabil bleibt.
Rollouts belastbar machen
Eine klare Administrationsstruktur vereinfacht Onboarding, Rechtestruktur und spätere Produkterweiterungen.
Wie das Modul mit anderen Bereichen zusammenspielt
struct-i-vio ist als zusammenhängende Plattform gedacht. Diese Module liegen fachlich am nächsten bei diesem Bereich.
Projekte
Projekte ergänzt Projekt-Einstellungen, weil beide Bereiche im Alltag direkt aufeinander aufbauen oder dieselben Verantwortlichen berühren.
DetailsBudget
Budget ergänzt Projekt-Einstellungen, weil beide Bereiche im Alltag direkt aufeinander aufbauen oder dieselben Verantwortlichen berühren.
DetailsBerechtigungen
Berechtigungen ergänzt Projekt-Einstellungen, weil beide Bereiche im Alltag direkt aufeinander aufbauen oder dieselben Verantwortlichen berühren.
DetailsBerechtigungen und Sichtbarkeit
Die öffentliche Dokumentation beschreibt die Logik auf Produktniveau - nicht als technische Policy-Liste, sondern als Rollout-Leitfaden.
Best Practices
So bleibt der Bereich bei Einführung und Nutzung anschlussfähig an den restlichen Produktfluss.
Entwickler Info
Backbone-Modul mit acht Actions, die VIER unterschiedliche Enforcement-Patterns abdecken: API-Pre-Check (create/archive/edit/set_margin), Trigger (assign_lead, set_skonto), RLS-only (delete_project), UI-Hook only (become_lead). Plus AI-Tool-Coupling auf create_project und ausgehende Cross-Modul-Backdoors über edit_project zu project_participants.
Entwickler-Info aufklappen (7)
⚠ KRITISCHTrigger-enforced: assign_lead + set_skonto
Zwei der acht Actions haben gar keinen primären API-Pre-Check, sondern werden vom Postgres-Trigger geschützt: trg_check_assign_lead_permission (auf project_members INSERT/UPDATE/DELETE wenn is_lead sich ändert) und trg_check_skonto_update (auf dim_projects UPDATE wenn default_skonto_percent sich ändert). Beide raisen EXCEPTION mit ERRCODE insufficient_privilege bzw. 42501. Konsequenz: Wer die Permission nicht hat, sieht einen 500er — nicht den klaren 403, den Pre-Checks liefern.
supabase/migrations/20260419090000_enforce_assign_lead_permission_on_project_member_delete.sqlsupabase/migrations/20251210234001_squash_baseline.sql:4045-4066 (check_skonto_update)
⚠ KRITISCHedit_project öffnet Backdoors zu project_participants
admin_projects.edit_project ist eine OR-Alternative im canManageParticipants-Check (participants.ts:88-103, [linkId].ts:53-68). Wer Projekt-Stammdaten bearbeiten darf, kann auch die Beteiligten-Liste verwalten — ohne project_participants.* zu besitzen. Beim Schließen von edit_project muss die Live-Preview project_participants.manage als mitbetroffen markieren.
pages/api/projects/[id]/participants.ts:88-103pages/api/projects/[id]/participants/[linkId].ts:53-68
⚠ KRITISCHedit_project NICHT in admin/projects/[id].ts PATCH geprüft
Der Haupt-Update-Endpoint admin/projects/[id].ts:30-47 prüft nur Modul-Visibility (can_view_module_ui), nicht edit_project. Felder wie description, address, status, project_type lassen sich also ohne edit_project ändern, solange der User das Modul sieht. Die edit_project-Permission greift nur bei den spezialisierten Endpoints (settings, images, members, participants, signed-upload-url).
pages/api/admin/projects/[id].ts:30-47
⚠ KRITISCHbecome_lead ist UI-Hook only
become_lead hat KEIN Backend-Enforcement — registriert in lib/permission-enforcement-registry.ts:85 als UI-Hook only. Die Action ist semantisch eine Levelliste ("User mit diesem Level oder niedriger dürfen als PL eingesetzt werden"), kein klassischer Toggle. Backend-Schutz erfolgt indirekt via assign_lead. Wer become_lead per direktem API-Call umgeht, kann sich nicht selbst zum PL machen — der assign_lead-Trigger blockiert.
lib/permission-enforcement-registry.ts:85pages/admin/projects.tsx
⚠ KRITISCHdelete_project ist RLS-only — kein API-Endpoint
Es gibt keinen einzigen Next.js-Endpoint, der DELETE auf dim_projects ausführt. Die Permission greift ausschließlich über RLS (squash_baseline.sql:23738). In der Standard-UI ist Löschen unerreichbar — Projekte werden archiviert. delete_project ist eine Verteidigungslinie für hypothetische zukünftige DELETE-Routen oder PostgREST-Direkt-Calls.
supabase/migrations/20251210234001_squash_baseline.sql:23738
AI-Tool-Coupling: create_project
create_project wird im AI-Assistant-Tool-Context geprüft (chat-stream.ts:2710-2711, lib/ai/toolContext.ts:965-966), bevor der AI per Tool-Call ein Projekt anlegt. Wer create_project nicht hat, kann auch den AI nicht zum Anlegen verleiten.
pages/api/ai/chat-stream.ts:2710-2711lib/ai/toolContext.ts:965-966
⚡ MERKWÜRDIGset_margin: Conditional, mit Trigger-Default-Logik
set_margin hat conditional Pre-Checks an drei Stellen (alle nur, wenn margin sich tatsächlich ändert). Plus: Beim POST in admin/projects.ts wird ohne set_margin nicht geblockt, sondern margin_percent auf null gesetzt — der DB-Trigger setzt dann den Default aus app_settings. Pragma: graceful degradation statt Hard-Fail.
