Antrag-Empfehlungen basierend auf Merkliste #108

Closed
opened 2026-04-10 23:52:43 +02:00 by tobias · 6 comments
Owner

'Wenn dir X gefallen hat, koennte dich Y interessieren.'

Logik

  • Nimm die Embeddings der gemerkten Antraege
  • Finde die N naechsten nicht-gemerkten Antraege via Cosinus-Aehnlichkeit
  • Selektor: im aktuellen Bundesland bleiben ODER bundesweit suchen

UI

  • Im Merkliste-Tab unter den gemerkten Antraegen: 'Empfehlungen fuer dich'
  • Toggle: 'Nur aktuelles BL' / 'Bundesweit'
  • Klickbar zum Detail
'Wenn dir X gefallen hat, koennte dich Y interessieren.' ## Logik - Nimm die Embeddings der gemerkten Antraege - Finde die N naechsten nicht-gemerkten Antraege via Cosinus-Aehnlichkeit - Selektor: im aktuellen Bundesland bleiben ODER bundesweit suchen ## UI - Im Merkliste-Tab unter den gemerkten Antraegen: 'Empfehlungen fuer dich' - Toggle: 'Nur aktuelles BL' / 'Bundesweit' - Klickbar zum Detail
Author
Owner

Blockiert: Antrag-Embeddings existieren nicht in der DB. Nur Wahlprogramm-Chunks sind embedded. Fuer Empfehlungen muessten die Antragstexte oder Assessment-Zusammenfassungen ebenfalls in die embeddings.db. Aufwand: mittel-hoch (neuer Embedding-Workflow + DB-Erweiterung + API). Zurueckgestellt.

**Blockiert:** Antrag-Embeddings existieren nicht in der DB. Nur Wahlprogramm-Chunks sind embedded. Fuer Empfehlungen muessten die Antragstexte oder Assessment-Zusammenfassungen ebenfalls in die embeddings.db. Aufwand: mittel-hoch (neuer Embedding-Workflow + DB-Erweiterung + API). Zurueckgestellt.
Author
Owner

Offene Frage (Claude-Loop)

Empfehlungen hängen direkt an #105 (Antrag-Embeddings). Zusätzlich:

Merkliste = User-gebunden, braucht neue Tabelle user_bookmarks(user_id, drucksache, created_at). Keycloak-User-ID als FK.

Frage: OK mit neuer Tabelle? Oder lieber auf localStorage (browser-lokal, kein Sync)?

❓ **Offene Frage (Claude-Loop)** Empfehlungen hängen direkt an #105 (Antrag-Embeddings). Zusätzlich: **Merkliste = User-gebunden**, braucht neue Tabelle `user_bookmarks(user_id, drucksache, created_at)`. Keycloak-User-ID als FK. **Frage:** OK mit neuer Tabelle? Oder lieber auf localStorage (browser-lokal, kein Sync)?
Author
Owner

Neue Tabelle.

Neue Tabelle.
Author
Owner

Aufgeteilt in zwei Teile:

Teil A — Merkliste (unblocked, kann sofort gebaut werden):

  • DB-Migration: neue Tabelle user_bookmarks(user_id TEXT, drucksache TEXT, created_at TIMESTAMP, PRIMARY KEY (user_id, drucksache))
  • API: POST /api/bookmark (toggle), GET /api/bookmarks (Liste)
  • UI: Star/Bookmark-Button im Detail-Panel
  • UI: Merkliste-Ansicht (Hamburger-Menü → "Meine Merkliste")
  • Keycloak-User-ID als FK

Teil B — Ähnliche Anträge (blockiert auf #123):

  • Nach v4-Reindex: GET /api/assessment/similar?drucksache=...&top_k=5
  • Cosine-Distance über assessments.summary_embedding
  • Im Detail-Panel Sektion "Ähnliche Anträge" anzeigen
  • Optional: auf Merkliste-Basis personalisierte Empfehlungen ("Du hast diese gemerkt, das hier könnte dich auch interessieren")

Teil A kann parallel zur v4-Migration gebaut werden.

Aufgeteilt in zwei Teile: **Teil A — Merkliste (unblocked, kann sofort gebaut werden):** - [ ] DB-Migration: neue Tabelle `user_bookmarks(user_id TEXT, drucksache TEXT, created_at TIMESTAMP, PRIMARY KEY (user_id, drucksache))` - [ ] API: `POST /api/bookmark` (toggle), `GET /api/bookmarks` (Liste) - [ ] UI: Star/Bookmark-Button im Detail-Panel - [ ] UI: Merkliste-Ansicht (Hamburger-Menü → "Meine Merkliste") - [ ] Keycloak-User-ID als FK **Teil B — Ähnliche Anträge (blockiert auf #123):** - [ ] Nach v4-Reindex: `GET /api/assessment/similar?drucksache=...&top_k=5` - [ ] Cosine-Distance über `assessments.summary_embedding` - [ ] Im Detail-Panel Sektion "Ähnliche Anträge" anzeigen - [ ] Optional: auf Merkliste-Basis personalisierte Empfehlungen ("Du hast diese gemerkt, das hier könnte dich auch interessieren") Teil A kann parallel zur v4-Migration gebaut werden.
Author
Owner

Teil A (Merkliste) — Status: bereits live

Überprüfung 2026-04-11: Die Merkliste-Infrastruktur wurde in einer vorherigen Session bereits komplett gebaut und ist in Prod live:

  • Tabelle bookmarks(user_id, drucksache, created_at) in database.py
  • toggle_bookmark(), get_bookmarks() DB-Funktionen
  • POST /api/bookmark (require_auth) — toggle
  • GET /api/bookmarks (optional auth) — Liste
  • UI: " Merkliste"-Mode im Hauptmenü
  • UI: Stern-Button (🔖 Merken / Gemerkt) pro Antrag im Detail
  • UI: loadBookmarksList() rendert gemerkte Anträge aus allAssessments

Live-Endpoint-Test: GET /api/bookmarks[] (unauth), funktioniert.

Teil B (Ähnliche Anträge) — blockiert auf #123 🟡

  • Warten auf v4-Reindex (läuft gerade, ~1-2h)
  • Danach Cosine-Distance über assessments.summary_embedding + UI-Sektion

Dieses Issue bleibt offen bis Teil B fertig ist (nach Reindex + Cleanup).

**Teil A (Merkliste) — Status: bereits live** ✅ Überprüfung 2026-04-11: Die Merkliste-Infrastruktur wurde in einer vorherigen Session bereits komplett gebaut und ist in Prod live: - ✅ Tabelle `bookmarks(user_id, drucksache, created_at)` in `database.py` - ✅ `toggle_bookmark()`, `get_bookmarks()` DB-Funktionen - ✅ `POST /api/bookmark` (require_auth) — toggle - ✅ `GET /api/bookmarks` (optional auth) — Liste - ✅ UI: "⭐ Merkliste"-Mode im Hauptmenü - ✅ UI: Stern-Button (🔖 Merken / ⭐ Gemerkt) pro Antrag im Detail - ✅ UI: `loadBookmarksList()` rendert gemerkte Anträge aus `allAssessments` Live-Endpoint-Test: `GET /api/bookmarks` → `[]` (unauth), funktioniert. **Teil B (Ähnliche Anträge) — blockiert auf #123** 🟡 - Warten auf v4-Reindex (läuft gerade, ~1-2h) - Danach Cosine-Distance über `assessments.summary_embedding` + UI-Sektion Dieses Issue bleibt **offen** bis Teil B fertig ist (nach Reindex + Cleanup).
Author
Owner

Teil B Live 2026-04-11

API: GET /api/assessment/similar?drucksache=...&top_k=5

  • Cosine-Distance über assessments.summary_embedding (v4)
  • Pure Python, kein sklearn
  • Gibt top_k ähnlichste Anträge mit similarity-Score zurück

UI: Neue Sektion im Detail-Panel: 🔗 N ähnliche Anträge (kollapsibel)

  • Zeigt Titel, Bundesland, Fraktionen, Score, Ähnlichkeits-% pro Treffer
  • Klickbar → wechselt zu dem Antrag-Detail

Verifiziert: Beispiel Klima-Antrag 21/4271 → Top-5 enthalten thematisch verwandte Klimaprogramme UND eine AfD-Normenkontrolle gegen das Klima-Sondervermögen (similarity 0.477). Das ist eine korrekte semantische Near-Match — User sieht alle Positionen zum Thema unabhängig von Pro/Contra.

Beide Teile (A Merkliste + B Ähnliche Anträge) sind live. Schließe.

## Teil B Live 2026-04-11 ✅ **API:** `GET /api/assessment/similar?drucksache=...&top_k=5` - Cosine-Distance über `assessments.summary_embedding` (v4) - Pure Python, kein sklearn - Gibt top_k ähnlichste Anträge mit similarity-Score zurück **UI:** Neue Sektion im Detail-Panel: `🔗 N ähnliche Anträge` (kollapsibel) - Zeigt Titel, Bundesland, Fraktionen, Score, Ähnlichkeits-% pro Treffer - Klickbar → wechselt zu dem Antrag-Detail **Verifiziert:** Beispiel Klima-Antrag 21/4271 → Top-5 enthalten thematisch verwandte Klimaprogramme UND eine AfD-Normenkontrolle gegen das Klima-Sondervermögen (similarity 0.477). Das ist eine korrekte semantische Near-Match — User sieht alle Positionen zum Thema unabhängig von Pro/Contra. **Beide Teile (A Merkliste + B Ähnliche Anträge) sind live.** Schließe.
Sign in to join this conversation.
No description provided.