feat(backend): GlobalMailDisplayName — schema + migration + seed (30 brands)

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 <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-05-28 16:09:58 +02:00
parent 807847381f
commit fd446874e9
2 changed files with 71 additions and 0 deletions

View File

@ -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;

View File

@ -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