Files
grok-bot 872f836a47 feat: add Quellenatlas knowledge base
Private, source-based system with FastAPI, Next.js, Postgres schema,
ethics constraints, RSS/API ingest into a review queue, and 24 seeded cases.
2026-08-21 22:37:45 +02:00

3.7 KiB

Quellenatlas — Architektur

Privates, selbst gehostetes Recherche-System für quellenbasierte Dokumentation politischer und gesellschaftlicher Auffälligkeiten. Kein öffentliches Portal, kein Meinungsprodukt.

Ziele

  • Hierarchische Navigation über Jurisdiktionen, Entitäten, Kategorien und Einzelfälle
  • Jede faktische Aussage ist einer Quelle zugeordnet
  • Klare Status-Trennung: bestätigt / Vorwurf / widerlegt / laufend; zusätzlich disputed
  • Erhöhte Sorgfalt für priorisierte Cluster: Ursula von der Leyen, Ukraine, EU-Spitzen
  • Halbautomatische Aktualisierung nur über RSS/API in eine Review-Queue (kein Medien-HTML-Scraping)
  • Export zitierfähiger Einträge (JSON, CSV, Markdown)

Nicht-Ziele (v1)

  • Öffentlicher Zugriff ohne Login
  • LLM-generierte Zusammenfassungen
  • HTML-Crawler gegen Nachrichtenportale
  • Neo4j (Graph ist eine SQL-abgeleitete JSON-Sicht)
  • Multi-Tenancy, Kommentare, Social Sharing

Systemübersicht

[Browser / Next.js]
        |  HTTP + Cookie (JWT)
        v
[FastAPI  /api/v1]
        |                 [APScheduler]
        |                        |
        +-- CRUD/Search/Export   +-- IngestAdapter (RSS/API)
        |                        |
        v                        v
   PostgreSQL 16          SourceEntry + ReviewItem
        ^
        |
   data/sources.yaml  (Katalog, kanonisch)
   data/seed/**       (YAML-Fälle)

Drei Prozesse in Docker Compose: postgres, backend, frontend. Der Ingest-Scheduler läuft im Backend-Prozess (kein Redis in v1).

Schichten (Backend)

Schicht Pfad Verantwortung
HTTP backend/app/api/v1/ Auth, Serialisierung, Statuscodes
Services backend/app/services/ Orchestrierung, Audit-Log
Ethik backend/app/core/ethics.py Harte Regeln; von Services aufgerufen
ORM backend/app/models/ Schema
Ingest backend/app/ingest/ Adapter, Dedup, Keyword-Priority

Admin-UI ist kein separates SQLAdmin. Alle Schreibzugriffe laufen durch dieselben Services, damit Ethik-Regeln nicht umgangen werden.

Auth

  • Rollen: admin, editor, viewer
  • JWT in httpOnly-Cookie (quellenatlas, SameSite=Lax)
  • Bootstrap-User aus ADMIN_USERNAME / ADMIN_PASSWORD
  • Alle API-Routen außer POST /api/v1/auth/login und /health erfordern Session
  • Frontend-Middleware blockt unauthentifizierte Seiten außer /login

Datenfluss: Fall anlegen

  1. Editor erstellt Case (Status Default allegation)
  2. Mindestens ein SourceEntry mit accessed_at
  3. Claims mit je ≥ 1 Quelle
  4. ethics.validate_* — sonst HTTP 422
  5. CaseRevision-Snapshot + UpdateLog

Datenfluss: Ingest

  1. Scheduler oder POST /api/v1/ingest/run/{slug}
  2. Adapter holt Feed/API, kanonisiert URL, hasht Inhalt
  3. Upsert SourceEntry (nie ein Case)
  4. Keyword-Match (VdL / Ukraine / Kategorien) → ReviewItem, bei Treffer priority=high
  5. Mensch reviewed: accept / reject / merge in bestehenden Fall

Cluster-Navigation

Keine Sonder-Tabellen. Cluster sind Tags auf Entity/Case (vdl, ukraine, eu-top, dach) plus care_level=high. Endpoints /api/v1/clusters/vdl und /clusters/ukraine filtern darauf.

Graph (v1)

GET /api/v1/graph?entity=slug|case=slug baut Knoten und Kanten aus SQL (Case↔Entity, Case↔Category, Entity↔Jurisdiction, Claim↔Source). Kein Graph-Store.

Erweiterbarkeit

  • Neue Quelle: Eintrag in data/sources.yaml, bei neuem Protokoll ein Adapter in ingest/adapters/
  • Neue Kategorie/Jurisdiktion: Seed-YAML oder Admin-API
  • Später Neo4j: denselben Graph-Endpoint als Quelle für ein Read-Model nutzen

Deployment

Siehe Root-README.md. Lokal: docker compose up --build. Persistenz nur in der Postgres-Volume. Backups = pg_dump.