rss-news/backend
Oliver Giertz 4282759b2c
feat(categorize): close rule gaps found on scheduled posts
The first pass only covered published posts, so 137 scheduled ones were
still uncategorised. Seven of them matched no rule at all and exposed
real gaps: the regions Pfalz and Erzgebirge, and the gear nouns in
"Duschzelte", "Outdoor-Messer" and "Outdoor-Stuhl", which the existing
compound keywords could not reach because the noun sits at the end.

Adding those flipped two discount posts ("Lidl Zelt im Angebot", "Aldi
Relax-Stuhl") into the gear category, because the new product keywords
outweighed the weaker "lidl"/"aldi" signals. Both retailers only ever
appear in discount posts here, so they now carry enough weight to
trigger the offer override themselves.

Region keywords are weight 2, not 3: at 3 they outranked an explicit
"Campingplatz" in the title and pulled campsite articles into
"Reiseziele". Bare "pfalz" is weight 1 because it double-counts inside
"rheinland-pfalz".

Scheduled posts now match a rule 136 of 137 times. Ten published posts
change category as a result and were updated in WordPress to keep the
archive and the rules in sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:21:46 +02:00
..
app feat(categorize): close rule gaps found on scheduled posts 2026-07-31 08:21:46 +02:00
data chore: finalize current state and prepare next wordpress-focused roadmap 2026-02-18 11:11:49 +01:00
static feat(admin): add feed/source management, rewrite editor, reopen flow, and WP block output 2026-02-21 14:03:49 +01:00
templates feat(admin): bulk-editable article list with WP ID inline editing 2026-04-10 09:00:25 +00:00
tests feat(wordpress): set post category from title and tag rules 2026-07-31 08:00:32 +02:00
.env.example Use four fixed daily publish slots 2026-07-24 10:38:04 +02:00
__init__.py feat: rebuild rss-news backend, admin ui, and legal extraction pipeline 2026-02-18 09:52:36 +01:00
README.md feat: rebuild rss-news backend, admin ui, and legal extraction pipeline 2026-02-18 09:52:36 +01:00
requirements-test.txt feat: rebuild rss-news backend, admin ui, and legal extraction pipeline 2026-02-18 09:52:36 +01:00
requirements.txt feat: rebuild rss-news backend, admin ui, and legal extraction pipeline 2026-02-18 09:52:36 +01:00

Backend Skeleton (FastAPI)

Dieses Verzeichnis enthaelt das technische Grundgeruest fuer den Rebuild von rss-news.

Start (lokal)

python -m venv .venv
source .venv/bin/activate
pip install -r backend/requirements.txt
uvicorn backend.app.main:app --reload --port 8501

Admin UI

  • Login: http://127.0.0.1:8501/admin/login
  • Dashboard: http://127.0.0.1:8501/admin/dashboard

Environment

  • Datei: backend/.env
  • Vorlage: backend/.env.example

Endpoints

  • GET /health - Healthcheck
  • POST /auth/login - Login mit Admin-User
  • POST /auth/logout - Logout
  • GET /auth/me - Aktiver User
  • GET /api/protected - Geschuetzter Test-Endpoint
  • GET /api/pipeline/status - Basisstatus inkl. Datensatzzaehler
  • GET /api/sources - Quellenliste
  • POST /api/sources - Quelle anlegen
  • GET /api/sources/{source_id}/policy-check - Policy-Pruefung fuer Quelle
  • GET /api/feeds - Feedliste
  • POST /api/feeds - Feed anlegen
  • GET /api/feeds/{feed_id}/policy-check - Policy-Pruefung fuer Feed
  • GET /api/runs - Import-/Job-Runs anzeigen
  • GET /api/runs/{run_id} - Detailansicht eines Runs
  • POST /api/runs - Run starten
  • POST /api/runs/{run_id}/finish - Run abschliessen
  • GET /api/articles - Artikel anzeigen
  • GET /api/articles/{article_id} - Artikeldetail
  • POST /api/articles/upsert - Artikel idempotent anlegen/aktualisieren
  • POST /api/articles/{article_id}/transition - Statuswechsel nach Workflow-Regeln
  • POST /api/articles/{article_id}/review - Review-Entscheidung (approve/reject)
  • POST /api/ingestion/run - Feed-Ingestion starten (optional pro Feed)

Datenbank

  • SQLite-Datei unter backend/data/rss_news.db
  • Tabellen werden beim App-Start initialisiert.
  • Tabellen: sources, feeds, runs, articles
  • Dedupe-Strategie Artikel: source_url -> (feed_id, source_article_id) -> source_hash

Policy-Enforcement

  • Ingestion blockiert Feeds automatisch, wenn die zugeordnete Quelle nicht policy-konform ist.
  • Mindestanforderungen: risk_level=green, terms_url, license_name, last_reviewed_at, is_enabled=1.
  • Pro importiertem Artikel wird ein attribution-Block in meta_json gespeichert.

Review-Workflow

  • Statuskette: new -> review -> approved -> published
  • Ablehnung im Review setzt auf rewrite
  • Ungueltige Statuswechsel werden per API blockiert

Verifikation

python -m unittest backend.tests.test_db_repositories
python -m unittest backend.tests.test_ingestion
python -m unittest backend.tests.test_api_auth

CI / Online-Auswertung

  • GitHub Actions Workflow: .github/workflows/test.yml
  • Fuehrt Tests inkl. Coverage auf Push/PR gegen main aus.

Hetzner Smoketest

BASE_URL="https://news.vanityontour.de" \
APP_ADMIN_USERNAME="admin" \
APP_ADMIN_PASSWORD="..." \
bash scripts/smoke_backend.sh

Hinweis

Passwort-Hashing und CSRF/Rate-Limit sind als naechste Ausbaustufe vorgesehen.