gwoe-antragspruefer/scripts/auto-fetch-news.sh

53 lines
1.9 KiB
Bash
Raw Normal View History

feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
#!/bin/bash
# Aktuelle-Themen-Dashboard: News-Aggregator-Cron (#170 Phase 1).
#
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
# Holt taeglich Headlines aus AI-erlaubenden, oeffentlich-rechtlichen
# bzw. parlamentarischen Quellen (Tagesschau-API + Bundestag-RSS),
# persistiert sie in ``news_articles`` und embeddet die neuen via
# Qwen-Embeddings-API. Idempotent (URL-PK), wiederhol-bar bei Fehlern.
feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
#
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
# Bewusst NICHT verwendet: RND.de und andere Quellen, die in robots.txt
# explizit ClaudeBot/GPTBot/CCBot bannen.
feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
#
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
# Erwartete Laufzeit: ~30 s leer (kein neuer Artikel) bis ~3 Min mit
# 100 Embeddings (Erst-Fetch / Backfill).
#
# Install als Host-Cron (taeglich 05:00 Uhr morgens, vor
# auto-ingest-protocols um 06:30):
#
# crontab -e
# 0 5 * * * /opt/gwoe-antragspruefer-dev/scripts/auto-fetch-news.sh \
# gwoe-antragspruefer-dev >> /var/log/gwoe-fetch-news.log 2>&1
#
# Manueller Aufruf (lokaler Smoketest):
# ./scripts/auto-fetch-news.sh gwoe-antragspruefer-dev
feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
set -euo pipefail
CONTAINER="${1:-gwoe-antragspruefer}"
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
# Skip wenn Container nicht laeuft (analog zu run-digest.sh).
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then
echo "$(date -Iseconds) SKIP — ${CONTAINER} is not running"
exit 0
fi
echo "$(date -Iseconds) START auto-fetch-news (container=${CONTAINER})"
feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
docker exec -i "$CONTAINER" python <<'EOF'
from app.news_aggregator import run_aggregator
stats = run_aggregator()
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
print(f" inserted={stats['inserted']} updated={stats['updated']} embedded={stats['embedded']}")
# Embeddings-Backfill: wenn der erste Run das Limit (100) gehittet hat,
# weiter embedden, bis alle pending durch sind. Pro Tag ein paar hundert
# moeglich, kein Risiko Timing-explosion.
if stats['embedded'] >= 100:
from app.news_aggregator import embed_pending_articles
backfill = embed_pending_articles(limit=500)
if backfill > 0:
print(f" embeddings_backfill={backfill}")
feat(#170): Aktuelle-Themen-Dashboard — News × Anträge × Pressemitteilungen Vollständiges 4-Phasen-Feature: **Phase 1 — News-Aggregator** (`app/news_aggregator.py`) - Tagesschau-API (`/api2u/news?ressort=...`) für inland/ausland/wirtschaft/wissen - Bundestag-RSS für aktuellethemen / pressemitteilungen / hib - DB-Tabelle `news_articles` (URL-PK, idempotent) - Embeddings via existierender qwen-v4-Pipeline - Cron-Script `scripts/auto-fetch-news.sh` - Bewusst NICHT: RND.de (robots.txt bannt explizit ClaudeBot, GPTBot, CCBot, ChatGPT-User, Google-Extended). Nur AI-erlaubende, öffentlich- rechtliche/parlamentarische Quellen - Volltexte werden NICHT persistiert (nur Titel + erster Satz) **Phase 2 — Themen × Anträge Matching** (`app/themen_matching.py`) - News-Embedding × Assessment-summary_embedding via Cosine-Similarity - `find_anträge_for_news`: pro News die Top-K passenden Anträge - `find_news_for_antrag`: pro Antrag Top-K News mit Datums-Fenster (90d) - `aggregate_top_themen`: primärer Dashboard-Endpoint - `aggregate_themen_zeitreihe`: News-Volumen pro Tag × Source **Phase 3 — Dashboard-View** (`/aktuelle-themen`) - Neuer linker Nav-Eintrag „Aktuelle Themen" - Stacked-Area-Chart News-Volumen pro Quelle (30d) - Pro News-Card: Titel + Summary + Tags + Top-3-Antrags-Match-Liste mit GWÖ-Score-Pill, Drucksache-Link, PM-Vorschlag-Button - Filter: Zeitfenster, Top-N, min_similarity - Auth-protected (require_auth) **Phase 4 — Pressemitteilungs-Generator** (`app/presse_generator.py`) - LLM-Prompt-Template (200-250 Worte, GWÖ-Sicht, JSON-Output) - Reuse von `QwenBewerter` aus app/adapters/qwen_bewerter.py - DB-Tabelle `presse_drafts` (Persistenz) - POST `/api/aktuelle-themen/generate-presse` rate-limited 5/min, auth-only (LLM-Kosten) - GET `/api/aktuelle-themen/drafts` + `/drafts/{id}` für Liste/Detail - Manueller Trigger via UI-Button, kein Auto-Versand - Modal-Anzeige des generierten Texts **Compliance:** - robots.txt-respektierend (ClaudeBot-Bann von RND vermieden, AI- erlaubende Quellen verwendet) - UI zeigt nur Titel+URL+Datum+erster Satz, keine Volltext-Reproduktion - Pressemitteilungen sind explizit Drafts, nicht Auto-Versand - LLM-Calls rate-limited, auth-only **Tests:** 43 neue Tests (19 news_aggregator + 16 themen_matching + 8 presse_generator). Suite jetzt 1048 grün. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:39:36 +02:00
EOF
feat(#170 followup): PM-Generator Idempotenz + qwen-max + Wrapper-Verbesserungen User-Feedback nach Live-Test: **1. Idempotenz** — Pressemitteilungen wurden ungespeichert generiert, doppelter Klick erzeugte doppelten Draft + LLM-Kosten. - Neuer Helper `_find_existing_draft(drucksache, news_url)` der den neuesten Draft fuer das Paar zurueckgibt - `generate_draft()` prueft per Default zuerst den Lookup, liefert existing zurueck mit `_was_existing=True` (kein LLM-Call) - `force=True` Parameter fuer bewusste Neu-Generierung - Endpoint nimmt `?force=true` Query-Param entgegen - UI: Modal zeigt klar "Bestehender Entwurf vs Neu generiert" Banner, mit "Neu generieren"-Button im existing-Banner **2. Premium-Modell statt Default** — User wollte hoehere Sprachqualitaet ("Opus oder sowas"). Da das Projekt Qwen via DashScope nutzt (kein Anthropic), Wechsel auf `settings.llm_model_premium` (qwen-max). - Tradeoff: ~3× teurer (~6 Cent statt 2 Cent) und ~2× langsamer (~30 s statt 15 s) — aber spuerbare Qualitaetsverbesserung in Pressemitteilungs-Diktion - confirm-Dialog im Frontend nennt jetzt 6 Cent + 30 s **3. Wrapper-Verbesserungen** — `auto-fetch-news.sh` aufgeraeumt: - Container-Check (skip wenn down) analog zu run-digest.sh - START/END-Timestamps - Ausfuehrliche cron-install-Doku im Header - Auto-Backfill: wenn erster Run >= 100 Embeddings (Limit gehit), wird embed_pending_articles bis zu 500 weitere nachgeholt Tests: 5 neue (idempotency, force, _find_existing_draft × 3). Suite 1053 gruen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:10:20 +02:00
echo "$(date -Iseconds) END auto-fetch-news"