From fd446874e98e6ee53f3177209a91fb3645b3f468 Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Thu, 28 May 2026 16:09:58 +0200 Subject: [PATCH] =?UTF-8?q?feat(backend):=20GlobalMailDisplayName=20?= =?UTF-8?q?=E2=80=94=20schema=20+=20migration=20+=20seed=20(30=20brands)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neue Tabelle `global_mail_display_names` für admin-kuratierte Glücksspiel-Marken. Mo's mail-classifier try/catch-Fallback wird damit produktiv (Display-Name-Layer 2.5). Co-Authored-By: Claude Sonnet 4.6 --- .../migration.sql | 56 +++++++++++++++++++ backend/prisma/schema.prisma | 15 +++++ 2 files changed, 71 insertions(+) create mode 100644 backend/prisma/migrations/20260528_add_global_mail_display_names/migration.sql diff --git a/backend/prisma/migrations/20260528_add_global_mail_display_names/migration.sql b/backend/prisma/migrations/20260528_add_global_mail_display_names/migration.sql new file mode 100644 index 0000000..47074c5 --- /dev/null +++ b/backend/prisma/migrations/20260528_add_global_mail_display_names/migration.sql @@ -0,0 +1,56 @@ +-- GlobalMailDisplayName — admin-kuratierte Glücksspiel-Marken für Mail-Display-Name-Matching. +-- +-- Analog BlocklistDomain (gleiche Struktur, anderer Zweck): +-- - kein User-Bezug, keine Mail-Inhalte (Art. 5 DSGVO) +-- - source: "seed" (initiale 30 Brands) | "manual" (Admin-App) | "community" (zukünftig) +-- +-- Genutzt von: server/db/domains.ts getMailDisplayNamePatterns() +-- → server/utils/mail-classifier.ts (Display-Name-Heuristik, Layer 2.5) +-- +-- Backend-Code hatte try/catch-graceful-degradation bis diese Tabelle existiert. +-- Nach Deploy dieser Migration fällt der Code auf den echten Pfad. + +CREATE TABLE IF NOT EXISTS "rebreak"."global_mail_display_names" ( + "id" UUID NOT NULL DEFAULT gen_random_uuid(), + "pattern" TEXT NOT NULL, + "is_active" BOOLEAN NOT NULL DEFAULT true, + "source" TEXT NOT NULL DEFAULT 'manual', + "added_at" TIMESTAMPTZ NOT NULL DEFAULT now(), + + CONSTRAINT "global_mail_display_names_pkey" PRIMARY KEY ("id"), + CONSTRAINT "global_mail_display_names_pattern_key" UNIQUE ("pattern") +); + +-- Seed: 30 initiale Glücksspiel-Brand-Patterns (Mo's Empfehlungsliste, 2026-05-28) +INSERT INTO "rebreak"."global_mail_display_names" ("id", "pattern", "source") VALUES + (gen_random_uuid(), 'Tipico', 'seed'), + (gen_random_uuid(), 'Bet365', 'seed'), + (gen_random_uuid(), 'bwin', 'seed'), + (gen_random_uuid(), 'Unibet', 'seed'), + (gen_random_uuid(), 'Betway', 'seed'), + (gen_random_uuid(), 'PokerStars', 'seed'), + (gen_random_uuid(), 'Interwetten', 'seed'), + (gen_random_uuid(), 'LeoVegas', 'seed'), + (gen_random_uuid(), 'Mr Green', 'seed'), + (gen_random_uuid(), 'Betsson', 'seed'), + (gen_random_uuid(), 'Betano', 'seed'), + (gen_random_uuid(), 'William Hill', 'seed'), + (gen_random_uuid(), 'Paddy Power', 'seed'), + (gen_random_uuid(), 'Betfair', 'seed'), + (gen_random_uuid(), '1xBet', 'seed'), + (gen_random_uuid(), 'Melbet', 'seed'), + (gen_random_uuid(), 'Mostbet', 'seed'), + (gen_random_uuid(), 'NetBet', 'seed'), + (gen_random_uuid(), 'Lottoland', 'seed'), + (gen_random_uuid(), 'Neobet', 'seed'), + (gen_random_uuid(), 'mybet', 'seed'), + (gen_random_uuid(), 'Wildz', 'seed'), + (gen_random_uuid(), 'Spinit', 'seed'), + (gen_random_uuid(), 'Caesars', 'seed'), + (gen_random_uuid(), 'GambleZen', 'seed'), + (gen_random_uuid(), 'Rolletto', 'seed'), + (gen_random_uuid(), 'Vbet', 'seed'), + (gen_random_uuid(), 'Stake', 'seed'), + (gen_random_uuid(), '888 Casino', 'seed'), + (gen_random_uuid(), 'Casinoly', 'seed') +ON CONFLICT ("pattern") DO NOTHING; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 1bb3904..d7755bd 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -555,6 +555,21 @@ model BlocklistDomain { @@schema("rebreak") } +/// Admin-kuratierte Glücksspiel-Marken für Mail-Display-Name-Matching. +/// Analog BlocklistDomain — kein User-Bezug, keine Mail-Inhalte (Art. 5 DSGVO). +/// Source: "seed" (initiale 30 Brands) | "manual" (Admin-App) | "community" (zukünftig). +/// SCHEMA hinzugefügt 2026-05-28, Migration: 20260528_add_global_mail_display_names. +model GlobalMailDisplayName { + id String @id @default(uuid()) @db.Uuid + pattern String @unique // z.B. "Tipico", "Bet365" + isActive Boolean @default(true) @map("is_active") + source String @default("manual") // "manual" | "seed" | "community" + addedAt DateTime @default(now()) @map("added_at") + + @@map("global_mail_display_names") + @@schema("rebreak") +} + model TrustedContact { id String @id @default(uuid()) @db.Uuid userId String @map("user_id") @db.Uuid