Coverbilder (bild_url) + responsives Layout für Mobil/Tablet
Teil 1 — Coverbilder: - Migration 0004_bild_url (neuheiten), 0002_bild_url (planung, archiv mit beiden Spiegel-Tabellen); nullable VARCHAR(500), SQLite↔Postgres portabel, bestehende Zeilen bleiben erhalten - BGG-Client extrahiert Cover aus der Thing-Antwort (bevorzugt <image>, sonst <thumbnail>; protokoll-relative URLs → https) - Sync-Upsert pflegt bild_url beim Update; fehlendes Bild löscht keines - Web-Quellen übernehmen img-URLs aus den Listenelementen (src/data-src, relative Pfade gegen die Seiten-URL aufgelöst); SPIEL-Essen nutzt das BILDER-Feld des JSON-Endpunkts - Verschiebung Neuheiten→Planung und Archivierung/Wiederherstellen schreiben bild_url mit - Anzeige: kleine Vorschaubilder (40x56) in den Listen, groß (max 200px) in Planung-Bearbeiten/Prüf-Dialog; Platzhalter-Div ohne Bild; Hotlinking mit loading=lazy + decoding=async Teil 2 — Responsives Layout: - Basislayout: Burger-Menü (Alpine.js) auf Mobil, Desktop-Leiste ab md: - Listen kollabieren <768px zu Karten-Ansichten (Cover links, Titel + Metadaten rechts, Status-Badge oben); Desktop behält Tabellenform - Touch-Ziele >= 44px auf Mobil, Formulare vollbreit mit Labels oben - Sync-Übersicht/Audit-Log bleiben horizontal scrollbare Tabellen Tests: 15 neue Fälle (tests/test_covers.py) — Migration inkl. Daten-Erhalt, BGG-Parsing gemockt, Quellen-Übernahme, Template-Render; 316 Tests grün. README aktualisiert.
This commit is contained in:
59
README.md
59
README.md
@@ -96,6 +96,11 @@ 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).
|
||||
Dazu die **Coverbilder-Erweiterung**: Migrationen für `bild_url` in allen
|
||||
vier Tabellen inkl. Daten-Erhalt beim ALTER TABLE, BGG-Bildextraktion
|
||||
(`<image>` bevorzugt, `<thumbnail>` als Rückfallebene, gemockte Antworten),
|
||||
Bildübernahme aus Web-Quellen, Update-Pflege des Bildes im Sync-Upsert sowie
|
||||
Template-Darstellung (`loading="lazy"`/`decoding="async"` bzw. Platzhalter).
|
||||
Dazu das **archiv**-Plugin: 12-Monats-Regel mit eingefrorener Uhr (Grenzfälle
|
||||
„genau 12 Monate“, Schaltjahr/29. Februar, UTC-Konsistenz bei
|
||||
Zeitzonen-Unterschieden), Job-Lauf mit Audit-Einträgen, Wiederherstellen
|
||||
@@ -270,7 +275,8 @@ manuelle Synchronisation für die Redaktion, deutsche sortier-/filterbare Liste.
|
||||
|
||||
### Datentabelle
|
||||
|
||||
Eigene Migration `0001_neuheiten_tabelle`, Tabelle `neuheiten`
|
||||
Eigene Migrationen `0001_neuheiten_tabelle`, `0002_bgg_id_nullable`,
|
||||
`0003_quellen_status` und `0004_bild_url`; Tabelle `neuheiten`
|
||||
(SQLite ↔ Postgres portabel):
|
||||
|
||||
| Spalte | Inhalt |
|
||||
@@ -279,6 +285,7 @@ Eigene Migration `0001_neuheiten_tabelle`, Tabelle `neuheiten`
|
||||
| `verlag` / `autor` | Verlag bzw. Autor(en), kommagetrennt |
|
||||
| `erscheinungsjahr` | Erscheinungsjahr — BGG liefert nur das Jahr, kein genaues Datum |
|
||||
| `bgg_id` | BoardGameGeek-ID, eindeutig → Merge-Kriterium des Syncs |
|
||||
| `bild_url` | URL des Coverbildes (nullable; BGG-Image/-Thumbnail oder Bild der Web-Quelle) |
|
||||
| `status` | `neuheit` (spätere Plugins: Planung/Archiv) |
|
||||
| `quelle` | Datenquelle (`boardgamegeek`) |
|
||||
| `erstellt_am` / `aktualisiert_am` | Zeitstempel |
|
||||
@@ -288,6 +295,14 @@ Eigene Migration `0001_neuheiten_tabelle`, Tabelle `neuheiten`
|
||||
Pro Suchbegriff: `/search?type=boardgame&query=…` → IDs sammeln →
|
||||
`/thing?id=…&type=boardgame` in Batches à 20 IDs.
|
||||
|
||||
**Coverbilder:** Aus der Thing-Antwort wird die Bild-URL extrahiert
|
||||
(bevorzugt das große `<image>`, sonst das kleinere `<thumbnail>`;
|
||||
protokoll-relative URLs werden auf https normalisiert) und in
|
||||
`bild_url` gespeichert. Beim Update bestehender Einträge wird das Bild
|
||||
mitgepflegt; fehlt es in einer Antwort, bleibt ein bereits gespeichertes
|
||||
Bild erhalten. Bilder werden direkt von BGG eingebettet (Hotlinking,
|
||||
kein Download) — im UI immer mit `loading="lazy"` und `decoding="async"`.
|
||||
|
||||
- **Rate-Limit:** mindestens 1 Sekunde zwischen zwei Requests.
|
||||
- **Retry mit Backoff:** exponentielles Zurückhalten bei 5xx, 429 und
|
||||
Netzwerkfehlern; HTTP 202 (BGG-Warteschlange) wird gemäß `Retry-After`
|
||||
@@ -344,7 +359,9 @@ Neben BGG crawlt das Plugin zusätzlich redaktionell gepflegte Web-Quellen
|
||||
Adapter in `plugins/neuheiten/quellen/` — mit Rate-Limit (1 Request/s),
|
||||
Retry/Backoff, konditionalen Requests (ETag/304), Fehler-Isolation pro Quelle
|
||||
und Duplikat-Gate gegen die BGG-Liste. Der Crawler arbeitet standardmäßig rein
|
||||
regelbasiert.
|
||||
regelbasiert. Liefert eine Quelle im Listenelement ein Bild (`img` mit `src`
|
||||
bzw. `data-src`), wird dessen URL in `bild_url` übernommen — sonst bleibt das
|
||||
Feld leer.
|
||||
|
||||
Optional kann eine **LLM-Hilfsstufe** (`plugins/neuheiten/quellen/ki_hilfe.py`)
|
||||
zugeschaltet werden — konsistent zur Dedup-KI über die
|
||||
@@ -452,12 +469,14 @@ laufen automatisch durch die dedup-Prüfung.
|
||||
|
||||
### Datentabelle
|
||||
|
||||
Eigene Migration `0001_planungsliste`, Tabelle `planungsliste`:
|
||||
Eigene Migrationen `0001_planungsliste` und `0002_bild_url`,
|
||||
Tabelle `planungsliste`:
|
||||
|
||||
| Spalte | Inhalt |
|
||||
|--------|--------|
|
||||
| `titel` / `verlag` / `autor` | Spieldaten |
|
||||
| `bgg_id` | BoardGameGeek-ID (Match-Kriterium der dedup-Prüfung) |
|
||||
| `bild_url` | URL des Coverbildes (nullable; wird beim Verschieben aus den Neuheiten übernommen) |
|
||||
| `ausgabe` | Magazin-Ausgabe, z. B. „3/2025“ (mehrere parallel möglich) |
|
||||
| `rezensent_id` | Zuordnung (FK auf die Benutzer-Tabelle des Kerns) |
|
||||
| `status` | `offen` → `in_bearbeitung` → `abgeschlossen` |
|
||||
@@ -501,9 +520,10 @@ unverändert zurück in die aktive Liste verschieben.
|
||||
|
||||
### Datentabellen
|
||||
|
||||
Eigene Migration `0001_archiv_tabellen` mit zwei Spiegel-Tabellen
|
||||
(SQLite ↔ Postgres portabel, ohne Fremdschlüssel — archivierte Zeilen
|
||||
überleben auch das Löschen eines Benutzers):
|
||||
Eigene Migrationen `0001_archiv_tabellen` und `0002_bild_url`
|
||||
(Spiegel-Tabellen, SQLite ↔ Postgres portabel, ohne Fremdschlüssel —
|
||||
archivierte Zeilen überleben auch das Löschen eines Benutzers;
|
||||
`bild_url` wird mit archiviert und beim Wiederherstellen zurückgeschrieben):
|
||||
|
||||
| Tabelle | Spiegel von | Besondere Spalten |
|
||||
|---------|-------------|-------------------|
|
||||
@@ -639,6 +659,31 @@ Docker/Podman Compose ist vorgesehen (Henry-Lab, danach Kundenhardware).
|
||||
Für Postgres genügt `SPIELE_DATABASE_URL`; die Migrationen sind portabel
|
||||
geschrieben.
|
||||
|
||||
## Oberfläche: Coverbilder & responsives Layout
|
||||
|
||||
**Coverbilder:** Die Listen (Neuheiten, Planung, Archiv) zeigen je Eintrag
|
||||
eine kleine Cover-Vorschau (40×56 px, `loading="lazy"`, `decoding="async"`,
|
||||
Alt-Text = Spieltitel); die Detail-/Prüf-Ansichten der Planung zeigen das
|
||||
Cover großformatig (max. 200 px Breite). Fehlt ein Bild, erscheint ein
|
||||
dezenter CSS-Platzhalter mit Spielicon-Zeichen. Eingebettet wird per
|
||||
Hotlink direkt von BGG bzw. der jeweiligen Quelle — es werden keine Bilder
|
||||
heruntergeladen oder lokal gespeichert.
|
||||
|
||||
**Responsive Verhalten:** Das Basis-Layout ist mobil-first:
|
||||
|
||||
- Navigation: Ab Tablet (`md:`) horizontale Leiste; auf Mobilgeräten ein
|
||||
Burger-Menü (Alpine.js) mit vollhöhen Touch-Zielen.
|
||||
- Listen: Auf schmalen Screens (<768 px) kollabieren Neuheiten, Planung und
|
||||
Archiv zu Karten-Ansichten — Cover links, Titel + Metadaten rechts,
|
||||
Status-Badge oben. Desktop behält die Tabellenform.
|
||||
- Formulare (Planung, Benutzerverwaltung, Einstellungen): vollbreite
|
||||
Eingabefelder mit Labels oberhalb auf Mobil.
|
||||
- Sync-Übersicht und Audit-Log bleiben Tabellen und scrollen horizontal
|
||||
(`overflow-x-auto`).
|
||||
- Buttons/Links haben auf Mobil mindestens 44 px Höhe (Touch-Ziel).
|
||||
|
||||
Getestet gegen 375 px (Smartphone), 768 px (Tablet) und Desktop.
|
||||
|
||||
## Projekt-Fortschritt
|
||||
|
||||
> Diese Tabelle ist der Live-Status. Sie wird bei jedem Push aktualisiert.
|
||||
@@ -654,7 +699,7 @@ geschrieben.
|
||||
| 7 | Plugin `archiv` (12-Monats-Autopilot, Wiederherstellen, täglicher Job) | ✅ fertig |
|
||||
| 8 | Plugin `erinnerung` (Redaktionsschluss pro Ausgabe, 4-Wochen-Erinnerung, Tages-Job) | ✅ fertig |
|
||||
| 9 | Plugin `export` (CSV + PDF via WeasyPrint) | ✅ fertig |
|
||||
| 10 | Integrationstests über alle Plugins | ✅ 217 Tests grün |
|
||||
| 10 | Integrationstests über alle Plugins | ✅ 316 Tests grün |
|
||||
| 11 | Deployment auf swen.henry.insight-it.de (Compose + Traefik, Live-Check) | ✅ live |
|
||||
|
||||
Legende: ✅ fertig · 🔄 in Arbeit · ⏳ offen · ⚠️ fertig mit offenen Punkten
|
||||
|
||||
Reference in New Issue
Block a user