Plugins dedup + planung: Prüf-API, Verzahnung mit Benachrichtigung und Audit-Log
Plugin dedup: - Öffentliche Prüf-API check_titel(titel, verlag, bgg_id, user) mit strukturiertem PruefErgebnis (Konflikte, Verlagsauswahl, Titel-Empfehlung) - Vier Prüfungen: Verlags-Konflikt, Titel-Varianten (deutsche Version bevorzugt: Umlaut-/Wort-Heuristik + BGG Alternate-Names), Spiel oder Vorgänger bereits besprochen (BGG boardgameexpansion-Relation + rapidfuzz-Fuzzy-Match), Titel in fremder Planungsliste - BGG-Hilfsclient mit Rate-Limit, netzwerkfrei testbar, degradiert defensiv - Eigene Migration (Prüfprotokoll dedup_pruefungen) + Prüfseite /dedup - Fremde Plugin-Tabellen werden nur lesend über die gemeinsame Metadata gelesen — keine Import-Abhängigkeiten zwischen Plugins Plugin planung: - Migration planungsliste: Titel, Verlag, Ausgabe, Rezensent, Status (offen/in_bearbeitung/abgeschlossen), Quelle, Prüf-Befund (JSON) - Beide Eintragswege durch die dedup-Prüfung: Verschiebung aus den Neuheiten (Button „→ Zur Planung“, Neuheit wechselt auf Status planung) und händisches Nachtragen im Formular - Bei Treffern: send_notification an den eintragenden Rezensenten (benachrichtigung-Plugin) + Audit-Log-Eintrag (audit-log-Plugin) - Verlags-Konflikt → Auswahl-Dialog „Welcher Verlag wird geführt?“, Entscheidung wird auditiert - Planungsliste mit Zuordnung, Statuswechsel, Bearbeiten/Löschen; Rezensenten nur eigene Einträge, Admin/Redakteur alle Tests: 45 neue Tests (Heuristik, alle vier Prüfungen mit Fake-BGG-Client, Protokoll, beide Eintragswege mit Stub-gemockten Abhängigkeiten, Rollen, Integration mit echten Plugins) — 141 Tests grün.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
<th class="px-4 py-3 font-medium">Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
@@ -34,10 +35,18 @@
|
||||
<td class="px-4 py-3 whitespace-nowrap text-slate-500">
|
||||
{{ eintrag.aktualisiert_am.strftime('%d.%m.%Y %H:%M') if eintrag.aktualisiert_am else '—' }}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
{% if eintrag.status == 'neuheit' %}
|
||||
<form method="post" action="/planung/uebernehmen/{{ eintrag.id }}">
|
||||
<button type="submit" title="In die Planungsliste verschieben (läuft durch die dedup-Prüfung)"
|
||||
class="text-xs bg-emerald-600 hover:bg-emerald-700 text-white px-2 py-1 rounded-lg whitespace-nowrap">→ Zur Planung</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="px-4 py-8 text-center text-slate-400">
|
||||
<td colspan="7" class="px-4 py-8 text-center text-slate-400">
|
||||
Keine Einträge gefunden.
|
||||
{% if ist_redaktion %}Nutze „Jetzt synchronisieren“, um die Liste aus BoardGameGeek zu befüllen.{% endif %}
|
||||
</td>
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
{{ meldung }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if fehler %}
|
||||
<div class="mb-4 px-4 py-3 rounded-lg border bg-red-50 border-red-200 text-red-700 text-sm">{{ fehler }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex flex-wrap items-end gap-3 mb-4">
|
||||
{% if ist_redaktion %}
|
||||
|
||||
Reference in New Issue
Block a user