7bb695d37a
RED phase (TDD) for UI-03/04 per-user triage (gelesen/ungelesen, Favorit). Adds the TenderTriage Prisma model (userId-scoped, onDelete: Cascade to Tender per Pitfall 6) and its migration, plus a failing spec proving upsert idempotency, strict userId scoping (V4/IDOR, T-11-10), and cascade consistency — service implementation follows in the GREEN commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
33 lines
1.4 KiB
SQL
33 lines
1.4 KiB
SQL
-- CreateTable
|
|
-- UI-03/04 (D-09/D-10/D-11) — per-user Triage-Zustand (gelesen/ungelesen,
|
|
-- Favorit) pro Tender. Scoping-Muster wie FavoriteLink (T-08-06, Pitfall 4):
|
|
-- userId-Scoping im Service, KEIN forTenant()/RLS. tenantId wird zusätzlich
|
|
-- mitgeführt (T-11-12, spätere Tenant-Isolation), ist aber nicht das
|
|
-- Scoping-Feld. ON DELETE CASCADE stellt sicher, dass Retention-Löschungen
|
|
-- (Phase 10, 90 Tage) keine verwaisten Triage-Zeilen hinterlassen (Pitfall 6).
|
|
CREATE TABLE IF NOT EXISTS "TenderTriage" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"tenderId" TEXT NOT NULL,
|
|
"isRead" BOOLEAN NOT NULL DEFAULT false,
|
|
"isFavorite" BOOLEAN NOT NULL DEFAULT false,
|
|
"readAt" TIMESTAMP(3),
|
|
"favoritedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "TenderTriage_pkey" PRIMARY KEY ("id"),
|
|
CONSTRAINT "TenderTriage_tenderId_fkey" FOREIGN KEY ("tenderId") REFERENCES "Tender"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
);
|
|
|
|
-- CreateIndex
|
|
-- Upsert-Target für setTriage (@@unique([userId,tenderId])).
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "TenderTriage_userId_tenderId_key" ON "TenderTriage"("userId", "tenderId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX IF NOT EXISTS "TenderTriage_userId_idx" ON "TenderTriage"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX IF NOT EXISTS "TenderTriage_tenderId_idx" ON "TenderTriage"("tenderId");
|