test(11-05): add failing TenderTriageService spec + TenderTriage schema/migration
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>
This commit is contained in:
@@ -290,6 +290,30 @@ model Tender {
|
||||
@@index([bundesland]) // FILTER-02: post-backfill Bundesland-Filter-Performance
|
||||
@@index([cpvDivisions], type: Gin) // FILTER-03: post-backfill CPV-Divisions-Filter-Performance (hasSome)
|
||||
// Deliberately NO tenant column and NO tenant index — this is global data (D-03)
|
||||
triage TenderTriage[]
|
||||
}
|
||||
|
||||
// UI-03/04 — per-user Triage-Zustand pro Tender (gelesen/ungelesen, Favorit).
|
||||
// Scoping-Muster wie FavoriteLink (T-08-06, Pitfall 4): userId-Scoping im
|
||||
// Service, KEIN forTenant()/RLS — RLS existiert nur für Auth-Kerntabellen.
|
||||
// tenantId wird zusätzlich mitgeführt (spätere Tenant-Isolation, T-11-12),
|
||||
// ist aber NICHT das Scoping-Feld — jede Query filtert auf userId.
|
||||
model TenderTriage {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
tenantId String
|
||||
tenderId String
|
||||
isRead Boolean @default(false)
|
||||
isFavorite Boolean @default(false)
|
||||
readAt DateTime?
|
||||
favoritedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
tender Tender @relation(fields: [tenderId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, tenderId]) // Upsert-Target (setTriage); ein Triage-Row je (user,tender)
|
||||
@@index([userId])
|
||||
@@index([tenderId])
|
||||
}
|
||||
|
||||
// Singleton-per-source admin poll config (INGEST-06 foundation).
|
||||
|
||||
Reference in New Issue
Block a user