Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "mail_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT,
|
||||
"scope" TEXT NOT NULL DEFAULT 'tenant',
|
||||
"to" TEXT NOT NULL,
|
||||
"template" TEXT NOT NULL,
|
||||
"locale" TEXT NOT NULL DEFAULT 'de',
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"provider_message_id" TEXT,
|
||||
"error" TEXT,
|
||||
"attempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"dedupe_key" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"sent_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "mail_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notification_preferences" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"event_type" TEXT NOT NULL,
|
||||
"email" BOOLEAN NOT NULL DEFAULT true,
|
||||
"locale" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "notification_preferences_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "mail_logs_dedupe_key_key" ON "mail_logs"("dedupe_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "mail_logs_tenant_id_created_at_idx" ON "mail_logs"("tenant_id", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "mail_logs_status_idx" ON "mail_logs"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notification_preferences_tenant_id_idx" ON "notification_preferences"("tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notification_preferences_user_id_event_type_key" ON "notification_preferences"("user_id", "event_type");
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Row Level Security (SEC1)
|
||||
--
|
||||
-- Muster wie seit F-04 (20260730160000_rls_enforce): ENABLE + FORCE + Policy mit
|
||||
-- USING *und* WITH CHECK. Ohne WITH CHECK koennte die eingeschraenkte App-Rolle
|
||||
-- `isms_app` unter FORCE keine Zeilen mehr anlegen.
|
||||
--
|
||||
-- mail_logs.tenant_id ist NULLABLE (Plattform-Mails ohne Mandantenbezug). Die
|
||||
-- Policy ist trotzdem identisch zu audit_logs, das dieselbe Situation hat:
|
||||
-- Zeilen mit tenant_id = NULL erfuellen die Bedingung nie und sind fuer `isms_app`
|
||||
-- weder les- noch schreibbar. Das ist beabsichtigt — Plattform-Zeilen werden
|
||||
-- ausschliesslich ueber den rohen `prisma`-Client (Owner-Rolle, BYPASSRLS)
|
||||
-- geschrieben, genau wie writePlatformAudit().
|
||||
--
|
||||
-- GRANT ist noetig, weil die pauschalen Rechte aus 20260702095816 nur fuer die
|
||||
-- damals existierenden Tabellen galten; ALTER DEFAULT PRIVILEGES greift nur fuer
|
||||
-- Objekte, die von der dort gesetzten Rolle erzeugt werden.
|
||||
-- ============================================================================
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON "mail_logs" TO isms_app;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON "notification_preferences" TO isms_app;
|
||||
|
||||
ALTER TABLE "mail_logs" ENABLE ROW LEVEL SECURITY;
|
||||
DROP POLICY IF EXISTS tenant_isolation ON "mail_logs";
|
||||
CREATE POLICY tenant_isolation ON "mail_logs"
|
||||
USING ("tenant_id" = current_setting('app.tenant_id', true))
|
||||
WITH CHECK ("tenant_id" = current_setting('app.tenant_id', true));
|
||||
ALTER TABLE "mail_logs" FORCE ROW LEVEL SECURITY;
|
||||
|
||||
ALTER TABLE "notification_preferences" ENABLE ROW LEVEL SECURITY;
|
||||
DROP POLICY IF EXISTS tenant_isolation ON "notification_preferences";
|
||||
CREATE POLICY tenant_isolation ON "notification_preferences"
|
||||
USING ("tenant_id" = current_setting('app.tenant_id', true))
|
||||
WITH CHECK ("tenant_id" = current_setting('app.tenant_id', true));
|
||||
ALTER TABLE "notification_preferences" FORCE ROW LEVEL SECURITY;
|
||||
Reference in New Issue
Block a user