Shuffle/docs/specs/13-umsetzung.md
cschlaefke 3135ed6381 docs(db): Meldungen (KAT-04) in Datenmodell, Katalogpflege, README und Umsetzungs-Nachtrag
Refs #13

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 19:16:31 +01:00

4.6 KiB
Raw Blame History

Spec #13 – KAT-04 Fehlendes Spiel melden: Umsetzungs-Nachtrag PR 13a (Backend)

Ergänzt docs/specs/13-fehlendes-spiel-melden.md (die Spec selbst wird hier nicht geändert). Stand: 2026-11-04, Branch feature/13a-fehlendes-spiel-backend (die Spec nennt feature/13a-meldungen-backend), Migration 20261104100000_game_reports_user.sql, Tests supabase/tests/database/10_game_reports_user.test.sql.

1. Abweichungen und Präzisierungen zum Vertrag

  • Spec-F6 ist entschieden und umgesetzt (2c): game_reports.editions_cleared und die Zuweisung in admin_resolve_report stehen schon in der Migration game_reports (PR 2c). 13a legt die Spalte nicht an und ändert admin_resolve_report nicht; adopt_report_target setzt editions_cleared genauso.
  • Tageslimit gilt auch für postgres: Der Trigger game_reports_daily_limit unterscheidet nicht nach Rolle (Spec 3.2). Fixtures, die als postgres mehr als 10 Nutzer-Meldungen „von heute“ für einen Nutzer anlegen, scheitern deshalb. Folge für die Tests: 08_game_reports.test.sql schaltet den Trigger am Anfang ab (alter table … disable trigger, mit dem Rollback am Ende zurückgenommen); in 10 bekommen Fixtures für gestern/älter feste Zeitstempel. Außerdem ist created_at nach dem Anlegen unveränderlich (Trigger set_updated_at), alte Zeitstempel müssen also beim Einfügen gesetzt werden.
  • Limit-Zählung über report_day(created_at) = report_day(now()) (nicht die optionale Bereichsform aus Spec 3.2); bei höchstens 10 Zeilen je Nutzer und Tag spielt der Index (owner_id, created_at) keine Rolle.
  • Trimmen: report_missing_game trimmt Leerzeichen, Tab, CR und LF (nicht nur Leerzeichen). Titel, Verlag und Link werden vor allen Prüfungen getrimmt, Längen gelten für den getrimmten Wert.
  • find_similar_catalog_games: Der Titel wird vor der Normalisierung getrimmt und die Länge (1 bis 200) am getrimmten Wert geprüft. Ist der normalisierte Titel leer (kann nach normalize_game_title nur bei leerem Rest vorkommen), gibt es keine Treffer. Je Spiel wird der beste Kandidatentitel gewählt: gleicher Schlüssel vor Ähnlichkeit, dann Haupttitel vor alternativen Titeln, dann Schreibweise. Verlage sind nach publishers.name_search, dann name sortiert (wie in search_catalog_games). Bei gleicher Ähnlichkeit sortiert das Ergebnis nach title, dann game_id. Die Ähnlichkeit bei same_title ist immer 1.0.
  • report_provisional_in_use: Der Handler um den Insert in game_reports wertet den Namen des verletzten Index (game_reports_provisional_game_id_key) aus; andere Unique-Verletzungen laufen unverändert weiter. Über die RPC ist der Fall nicht erreichbar (jeder Aufruf legt ein frisches Spiel an); der Test lenkt ihn mit einem temporären Trigger herbei.
  • adopt_report_target: Alle Prüfungen laufen nach dem Sperren von Meldung und Spielen, in der Reihenfolge der Spec-Tabelle. Eine Meldung, die nicht dem Aufrufer gehört, wird schon beim Sperren nicht gefunden (report_not_found, p_report = null ebenso). current_user wird nirgends ausgewertet.
  • Eigentümer von adopt_report_target: Die Migration ändert den Eigentümer nicht ausdrücklich (alter function … owner to); sie läuft als postgres (lokal und per Supabase CLI). Der Test prüft proowner = postgres.
  • Testplan: 00_schema unverändert (22 Tabellen), 07/08-Fremdschlüssel-Wächter unberührt (kein neuer Fremdschlüssel), 08 nur um das Abschalten des Limit-Triggers ergänzt (Erwartungen und Beschreibungen unverändert gültig: die Spaltenrechte aus 08 waren schon auf result_seen_at und die Insert-Spalten ausgelegt).

2. Mutationsprüfung

Die Mutanten sind veränderte Kopien der Migration, jeweils in einer Transaktion zusammen mit dem Testlauf angewendet und mit dem Rollback des Tests zurückgenommen (am echten Schema bleibt nichts). Die Skripte liegen nicht im Repo. Ergebnis siehe Bericht an Chris; die überlebenden Mutanten sind entweder Doppelabsicherungen (zum Beispiel origin = 'user' in der Insert-Policy, die schon durch die Spaltenrechte gesichert ist) oder nur mit Parallelität testbar (Advisory-Lock).

3. Offene Punkte

  • Zeitpunkt des Hinweises: Klickt der Nutzer den Hinweis „abgelehnt mit Verweis“ weg (result_seen_at gesetzt) und wechselt danach auf den Zieleintrag, bleibt result_seen_at gesetzt (Spec 4.4: unverändert). Der Hinweis „Dein Eintrag zeigt jetzt auf …“ erscheint dann am Zieleintrag nicht mehr. Siehe Bericht, Frage an Chris.
  • Paralleltest des Limits (zwei psql-Sitzungen unter READ COMMITTED) ist nicht automatisiert (Spec 7.1) und gehört zu T1.