-- quick-261002-kxc — Nextcloud-Status: persoenliche Benachrichtigung. -- -- Zweck: (1) neue Tabelle "NextcloudAlertSubscription" — wer fuer welche -- Cloud die Glocke eingeschaltet hat (je Benutzer und Cloud hoechstens eine -- Zeile); (2) fuenf neue Spalten an "NextcloudInstance": Zaehler und Zeitpunkt -- der aufeinanderfolgenden Fehlschlaege (Zwei-Fehlschlaege-Regel) und der -- zuletzt gemeldete Zustand ('ok' | 'red') samt Grund und Zeitpunkt. Der -- gemeldete Zustand wird VOR dem Mailversand per bedingtem Update beansprucht, -- damit mehrere API-Instanzen oder ein Neustart nie doppelt melden. -- Bestehende Zeilen starten als 'ok' ohne Fehlschlaege. -- -- Von Hand geschrieben (Vorbild 20261002150000_nextcloud_status und -- 20260929140000_reminder). -- -- Zeilenschutz: das Abonnement ist ein persoenliches Datum, deshalb -- `tenant_isolation_policy` MIT Benutzerdimension — exakt wie "Reminder" -- (ohne gesetzten Benutzer gilt nur der Mandant, mit Benutzer zusaetzlich -- "userId"). Keine `system_read_policy`: die Tabelle wird nie im -- Systemkontext gelesen, jede Abfrage laeuft an den Mandanten gebunden. Die -- neuen Spalten von "NextcloudInstance" fallen unter deren bestehende Regeln. -- -- Rechte fuer die Anwendungsrolle tessera_app kommen automatisch ueber -- ALTER DEFAULT PRIVILEGES aus 20260909130000_rls_app_role — hier nichts zu -- tun. -- -- WICHTIG: wie alle bisherigen RLS-Migrationen wirken diese Regeln erst, -- wenn die Anwendung als Rolle ohne Umgehungsrecht verbindet (Schalter -- heute AUS, siehe docs/mandantentrennung-datenbankrolle.md). -- AlterTable ALTER TABLE "NextcloudInstance" ADD COLUMN "consecutiveFailures" INTEGER NOT NULL DEFAULT 0, ADD COLUMN "firstFailureAt" TIMESTAMP(3), ADD COLUMN "alertState" TEXT NOT NULL DEFAULT 'ok', ADD COLUMN "alertReason" TEXT, ADD COLUMN "alertChangedAt" TIMESTAMP(3); -- CreateTable CREATE TABLE "NextcloudAlertSubscription" ( "id" TEXT NOT NULL, "tenantId" TEXT NOT NULL, "userId" TEXT NOT NULL, "instanceId" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "NextcloudAlertSubscription_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "NextcloudAlertSubscription_instanceId_userId_key" ON "NextcloudAlertSubscription"("instanceId", "userId"); -- CreateIndex CREATE INDEX "NextcloudAlertSubscription_tenantId_userId_idx" ON "NextcloudAlertSubscription"("tenantId", "userId"); -- AddForeignKey ALTER TABLE "NextcloudAlertSubscription" ADD CONSTRAINT "NextcloudAlertSubscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "NextcloudAlertSubscription" ADD CONSTRAINT "NextcloudAlertSubscription_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "NextcloudInstance"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- Zeilenschutz: Mandant UND Benutzer (Muster "Reminder") ALTER TABLE "NextcloudAlertSubscription" ENABLE ROW LEVEL SECURITY; ALTER TABLE "NextcloudAlertSubscription" FORCE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_policy ON "NextcloudAlertSubscription" USING ( "tenantId" = current_tenant_id() AND (current_user_id() IS NULL OR "userId" = current_user_id()) );