Plugin erinnerung: Redaktionsschluss pro Ausgabe, 4-Wochen-Erinnerung
- Ausgaben (Name + Redaktionsschluss-Datum) verwalten, mehrere parallel, Anlegen/Bearbeiten/Löschen nur für Admin, mit Audit-Log-Einträgen - Erinnerung 28 Tage vor dem Redaktionsschluss an alle aktiven Rezensenten mit offener (oder fehlender) Planung, Versand über das benachrichtigung- Plugin je Kanal-Präferenz, Audit als System/benachrichtigt - Täglicher APScheduler-Job (SPIELE_ERINNERUNG_JOB_UHRZEIT, abschaltbar) plus manuelle Sofort-Prüfung in der Admin-Ansicht - Doppelschutz: Protokolltabelle mit Unique (Ausgabe, Benutzer) - Admin-UI: Ausgabenliste mit Restzeit-Badges, Erinnerungsstatus (wer wurde wann über welche Kanäle erinnert), deutsche Templates - Tests mit eingefrorener Uhr (freezegun): Fenster-Grenzen, kein Versand vor Frist/nach Schluss, Empfänger-/Rollenregeln, keine Duplikate, Scheduler-Konfiguration; Integrationstest mit den echten Plugins (167 Tests grün)
This commit is contained in:
68
README.md
68
README.md
@@ -4,7 +4,7 @@
|
||||
modularer Plugin-Architektur. Lauffähiger Kern mit Plugin-System,
|
||||
Authentifizierung/Rollen und Migrationen; vollständig implementiert sind
|
||||
bisher **Audit-Log**, **Benachrichtigung**, **Neuheiten (BGG-Sync)**,
|
||||
**Dedup-Prüfung** und **Planungsliste**.
|
||||
**Dedup-Prüfung**, **Planungsliste** und **Erinnerungen**.
|
||||
|
||||
## Stack
|
||||
|
||||
@@ -54,6 +54,8 @@ Beim ersten Start wird automatisch ein Admin-Konto angelegt:
|
||||
| `SPIELE_BGG_SUCHBEGRIFFE` | `brettspiel` | Komma-getrennte Suchbegriffe für den regelmäßigen Sync |
|
||||
| `SPIELE_BGG_MAX_TREFFER_PRO_SUCHE` | `25` | Obergrenze Treffer je Suchbegriff (schont das BGG-Rate-Limit) |
|
||||
| `SPIELE_DEDUP_BGG_AKTIV` | `1` | BGG-Zusatzdaten für die Dedup-Prüfung an (`1`) oder aus (`0`): Alternate-Names und Erweiterungs-Relationen |
|
||||
| `SPIELE_ERINNERUNG_JOB_AKTIV` | `1` | Täglicher Erinnerungs-Check an (`1`) oder aus (`0`) |
|
||||
| `SPIELE_ERINNERUNG_JOB_UHRZEIT` | `08:00` | Uhrzeit (HH:MM) des täglichen Erinnerungs-Checks |
|
||||
|
||||
|
||||
## Tests
|
||||
@@ -75,6 +77,12 @@ Fake-BGG-Client, Prüfprotokoll, Prüfseite) und **planung** (beide Eintragswege
|
||||
mit Stub-gemockter dedup-/Benachrichtigungs-/Audit-API, Verlags-Auswahl-
|
||||
Dialog, Statuswechsel, Bearbeiten/Löschen, Rechte pro Rolle) plus ein
|
||||
Integrationstest mit den echten Plugins (In-App-Nachricht + Audit-Eintrag).
|
||||
Das Plugin **erinnerung** ist abgedeckt mit: Ausgaben-CRUD (nur Admin, mit
|
||||
Audit), Erinnerungslogik mit eingefrorener Uhr (freezegun) — 4-Wochen-Grenze
|
||||
(28 Tage exakt), kein Versand vor der Frist und nach dem Redaktionsschluss,
|
||||
Empfängerregeln (offene oder fehlende Planung, Rollen-Filter), Doppelschutz
|
||||
pro Ausgabe+Benutzer, manuelle Prüfung, Scheduler-Lifecycle/Uhrzeit-Konfiguration
|
||||
— wiederum plus ein Integrationstest mit den echten Plugins.
|
||||
|
||||
## Architektur
|
||||
|
||||
@@ -94,7 +102,8 @@ plugins/ ein Ordner pro Funktion, ladbar über den Plugin-Load
|
||||
├── benachrichtigung/ VOLL IMPLEMENTIERT: E-Mail/Telegram/In-App
|
||||
├── dedup/ VOLL IMPLEMENTIERT: check_titel-API, Heuristik, Protokoll
|
||||
├── planung/ VOLL IMPLEMENTIERT: Planungsliste, Verschiebung, Dialoge
|
||||
├── archiv/ erinnerung/ export/ (Stubs, ladbar)
|
||||
├── erinnerung/ VOLL IMPLEMENTIERT: Ausgaben, 4-Wochen-Erinnerung, Tages-Job
|
||||
├── archiv/ export/ (Stubs, ladbar)
|
||||
└── … je __init__.py + templates/<name>/
|
||||
```
|
||||
|
||||
@@ -363,6 +372,58 @@ Rezensenten können **nur ihre eigenen Einträge** bearbeiten (Statuswechsel,
|
||||
Bearbeiten, Löschen); Admins und Redakteure alle. Jede Änderung wird im
|
||||
Audit-Log protokolliert (`erstellt`/`verschoben`/`geaendert`/`geloescht`).
|
||||
|
||||
## Plugin „erinnerung“ (implementiert)
|
||||
|
||||
Redaktionsschluss pro Ausgabe mit automatischer 4-Wochen-Erinnerung an alle
|
||||
Rezensenten — mehrere Ausgaben laufen parallel.
|
||||
|
||||
### Datentabellen
|
||||
|
||||
Eigene Migration `0001_ausgaben_und_protokoll`, zwei Tabellen
|
||||
(SQLite ↔ Postgres portabel):
|
||||
|
||||
| Tabelle | Spalten | Zweck |
|
||||
|---------|---------|-------|
|
||||
| `erinnerung_ausgabe` | `name` (z. B. „3/2025“), `redaktionsschluss` (Datum), Zeitstempel | Eine Magazin-Ausgabe; Anlegen/Bearbeiten/Löschen nur für Rolle **Admin** |
|
||||
| `erinnerung_protokoll` | `ausgabe_id`, `user_id`, `kanaele`, `erstellt_am` | Jede versendete Erinnerung; **eindeutig** über (Ausgabe, Benutzer) → keine Doppelerinnerung |
|
||||
|
||||
### Erinnerungslogik
|
||||
|
||||
- **Fenster:** 28 Tage (4 Wochen) vor dem Redaktionsschluss bis zum
|
||||
Redaktionsschluss selbst (jeweils inklusive). Davor und danach wird nicht
|
||||
erinnert.
|
||||
- **Empfänger:** alle aktiven Rezensenten, die noch offene Planungseinträge
|
||||
haben (Status ≠ „abgeschlossen“, also „offen“ oder „in Bearbeitung“) oder
|
||||
gar keine Einträge. Wer alles abgeschlossen hat, wird nicht erinnert;
|
||||
Admins und Redakteure nie.
|
||||
- **Versand:** über `send_notification` des benachrichtigung-Plugins
|
||||
(Kategorie `erinnerung`) — die Kanäle richten sich nach der Präferenz des
|
||||
Benutzers. Ohne Partner-Plugin wird kein Protokoll geschrieben, damit der
|
||||
nächste Lauf es erneut versucht.
|
||||
- **Doppelschutz:** pro (Ausgabe, Benutzer) wird genau einmal erinnert; der
|
||||
Versand steht in `erinnerung_protokoll`. Auch ein späteres Bearbeiten des
|
||||
Redaktionsschlusses löst keine zweite Erinnerung aus.
|
||||
- **Audit:** jede Erinnerung als `System`/`benachrichtigt` (Objekttyp
|
||||
`erinnerung`), jede Ausgaben-Änderung als `erstellt`/`geaendert`/
|
||||
`geloescht` (Objekttyp `ausgabe`).
|
||||
|
||||
### Geplanter Job & manuelle Prüfung
|
||||
|
||||
APScheduler prüft **täglich** (Standard 08:00 Uhr, konfigurierbar über
|
||||
`SPIELE_ERINNERUNG_JOB_UHRZEIT`, abschaltbar über
|
||||
`SPIELE_ERINNERUNG_JOB_AKTIV=0`). Unter **Erinnerungen → „Jetzt prüfen und
|
||||
erinnern“** führt ein Admin denselben Check sofort aus; das Ergebnis
|
||||
erscheint als Banner. Die Uhr liegt zentral in `dienst.heute()` — Tests
|
||||
frieren sie mit freezegun ein.
|
||||
|
||||
### UI
|
||||
|
||||
Unter **Erinnerungen** (`/erinnerung`) sehen alle angemeldeten Benutzer die
|
||||
Ausgaben mit Redaktionsschluss und Restzeit-Badge. Admins verwalten zusätzlich
|
||||
die Ausgaben (anlegen/bearbeiten/löschen), starten den Sofort-Check und
|
||||
sehen den **Erinnerungsstatus**: wer wurde für welche Ausgabe wann über
|
||||
welche Kanäle erinnert.
|
||||
|
||||
## Deployment (später)
|
||||
|
||||
Docker/Podman Compose ist vorgesehen (Henry-Lab, danach Kundenhardware).
|
||||
@@ -382,7 +443,7 @@ geschrieben.
|
||||
| 5 | Plugin `dedup` (Verlags-Konflikt, deutsche Version, Vorgänger-/Planungs-Check) | ✅ fertig (141 Tests grün) |
|
||||
| 6 | Plugin `planung` (Verschiebung, händischer Eintrag + Prüfungen + Benachrichtigung) | ✅ fertig (141 Tests grün) |
|
||||
| 7 | Plugin `archiv` (12-Monats-Autopilot) | ⏳ offen |
|
||||
| 8 | Plugin `erinnerung` (Redaktionsschluss pro Ausgabe, 4-Wochen-Erinnerung) | ⏳ offen |
|
||||
| 8 | Plugin `erinnerung` (Redaktionsschluss pro Ausgabe, 4-Wochen-Erinnerung, Tages-Job) | ✅ fertig (167 Tests grün) |
|
||||
| 9 | Plugin `export` (CSV + PDF via WeasyPrint) | ⏳ offen |
|
||||
| 10 | Integrationstests über alle Plugins | ⏳ offen |
|
||||
| 11 | Deployment auf swen.henry.insight-it.de (Compose + Traefik, Live-Check) | ⏳ offen |
|
||||
@@ -392,6 +453,5 @@ Legende: ✅ fertig · 🔄 in Arbeit · ⏳ offen · ⚠️ fertig mit offenen
|
||||
## Offene Punkte (nicht Teil von Phase 1)
|
||||
|
||||
- CSRF-Schutz für Formulare (aktuell SameSite=Lax-Cookie als Basisschutz)
|
||||
- Hintergrund-Jobs (APScheduler) für Erinnerungen
|
||||
- WeasyPrint für PDF-Export (Systemabhängigkeiten im Container)
|
||||
- Tailwind via CDN nur für Dev; für Produktion lokal gehostete Assets
|
||||
|
||||
Reference in New Issue
Block a user