chahinebrini 265859467a feat(vip): Curated-Domain-Vorschläge — Suggest-Backend
User können länderspezifische Glücksspielseiten für die kuratierte
VIP-Layer-2-Liste vorschlagen — wichtig für Länder mit kurzer
Starter-Liste (z.B. TN).

- Schema: CuratedDomain (domain, country, status, suggestedByUserId);
  Migration 20260522_curated_domains
- webcontent-domains.get.ts komponiert jetzt JSON-Basis + DB-approved
  Curated-Domains pro Land
- POST /api/curated-domains/suggest legt einen suggested-Eintrag an

Admin-Approve (Endpoint + Admin-App-View) folgt als nächster Block.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 21:09:00 +02:00

56 lines
2.0 KiB
TypeScript

import { usePrisma } from "../../utils/prisma";
// Domain muss mindestens eine TLD haben (z.B. "mbet216.com").
const DOMAIN_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/;
// Unterstützte VIP-Länder — muss zu COUNTRY_KEYS in webcontent-domains.get.ts passen.
const VALID_COUNTRIES = ["DE", "GB", "FR", "TN"];
/**
* POST /api/curated-domains/suggest
*
* Ein User schlägt eine länderspezifische Glücksspielseite für die kuratierte
* VIP-Layer-2-Liste seines Landes vor. Der Eintrag landet als `suggested` in
* der curated_domains-Tabelle; ein ReBreak-Admin gibt ihn frei (`approved`) —
* erst dann komponiert ihn der webcontent-domains-Endpoint in die Länderliste.
*
* Body: { domain: string, country: string (ISO-2) }
*/
export default defineEventHandler(async (event) => {
const user = await requireUser(event);
const body = await readBody(event);
// Domain normalisieren — lowercase, Schema/Pfad/www. strippen.
const domain = (typeof body?.domain === "string" ? body.domain : "")
.trim()
.toLowerCase()
.replace(/^https?:\/\//, "")
.replace(/\/.*$/, "")
.replace(/^www\./, "");
const country =
typeof body?.country === "string" ? body.country.toUpperCase() : "";
if (!domain || domain.length > 253 || !DOMAIN_RE.test(domain)) {
throw createError({ statusCode: 400, data: { error: "INVALID_DOMAIN" } });
}
if (!VALID_COUNTRIES.includes(country)) {
throw createError({ statusCode: 400, data: { error: "INVALID_COUNTRY" } });
}
const db = usePrisma();
// Schon vorhanden (egal welcher Status)? Dann nicht doppelt anlegen.
const existing = await db.curatedDomain.findUnique({
where: { country_domain: { country, domain } },
select: { status: true },
});
if (existing) {
return { ok: false, alreadyExists: true, status: existing.status };
}
await db.curatedDomain.create({
data: { domain, country, status: "suggested", suggestedByUserId: user.id },
});
return { ok: true };
});