Architektur-Entscheidung aus Issue #62: Diátaxis-Framework für Doku- Pflege ohne Drift. Pflege im Repo, ADRs immutable, Stale-Snapshots explizit als Archiv markiert. Phase 1 — Architecture Decision Records: - docs/README.md — Diátaxis-Index, Erklärung was wo dokumentiert wird - docs/adr/README.md — ADR-Workflow + Index - docs/adr/template.md — Vorlage für neue ADRs - docs/adr/0001-llm-citation-binding.md — Issue #60 Doppel-Fix-Story (A=ENUM-Anker, B=server-seitige Rekonstruktion, warum Option C verworfen) - docs/adr/0002-adapter-architecture.md — ParlamentAdapter-Basisklasse + Registry, Klassen vs. Strategy vs. Modul-pro-Adapter - docs/adr/0003-citation-property-tests.md — Sub-D Strategie, warum Property-Test gegen echte PDFs statt Schema-Tests oder Online-Verify - docs/adr/0004-deployment-workflow.md — Docker-Compose + Volumes Standard-Workflow + SN-XML-Sonderpfad + Container-UTC-Gotcha Phase 3 — Stale Doku archiviert: - DOKUMENTATION.md (24.März, Skript-Architektur vor Webapp-Migrate) → docs/archive/DOKUMENTATION-2026-03-24.md - STATUS-2026-03-28.md (Tagesstand-Snapshot) → docs/archive/STATUS-2026-03-28.md - README.md (28.März, listet nur NRW-Adapter, vor 16 weiteren BLs) → docs/archive/README-2026-03-28.md - docs/archive/README.md erklärt warum die Files da sind und warum niemand sie überschreiben oder ersetzen sollte Plus neue Top-Level-README.md im Project-Root (außerhalb git, da project-root kein Repo ist) als Folder-Index für den User. CLAUDE.md ergänzt um Doku-Sektion mit Verweis auf docs/adr/. Phase 2 (mkdocs Setup) folgt separat — braucht eine Docker-Image- Erweiterung, die ich nicht autark einrollen will ohne Decision. Tests: 194/194 grün (keine Code-Änderung). Refs: #62
10 KiB
10 KiB
GWÖ-Antragsprüfer — Projektdokumentation
Stand: 28.03.2026, 23:58 Uhr Telegram-Topic: 🌱 GWÖ-Antragsprüfer (thread_id 4247)
🎯 Projektziel
Automatische Bewertung von Parlamentsanträgen nach der Gemeinwohl-Ökonomie (GWÖ) Matrix 2.0 für Gemeinden. Das Tool analysiert Anträge aus Landesparlamenten und bewertet sie nach GWÖ-Kriterien, vergleicht mit Wahl- und Parteiprogrammen und schlägt konkrete Textverbesserungen vor.
🌐 Live-System
| Was | URL |
|---|---|
| Webapp | https://gwoe.toppyr.de |
| Git-Repository | https://repo.toppyr.de/tobias/gwoe-antragspruefer |
| Server | VServer 152.53.119.77 |
| Container | /opt/gwoe-antragspruefer/ |
🏗️ Architektur
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Durchsuchen │ │ 🏷️ Tags │ │ Prüfen │ │
│ │ (Liste) │ │ (Wolke) │ │ (Upload/Analyse) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ /api/ │ │ /api/ │ │ /api/ │ │ /api/ │ │
│ │assessments│ │search- │ │analyze- │ │assessment/ │ │
│ │ │ │landtag │ │drucksache│ │pdf │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐
│ SQLite │ │ OPAL API │ │ DashScope (Qwen) │
│ gwoe-antraege│ │ (Landtag │ │ qwen-plus-latest │
│ .db │ │ NRW) │ │ (LLM Analyse) │
└─────────────┘ └─────────────┘ └─────────────────────────┘
📁 Projektstruktur
webapp/
├── app/
│ ├── main.py # FastAPI-Endpoints + Security Middleware
│ ├── analyzer.py # LLM-Analyse mit v5-Prompt + Retry-Logik
│ ├── database.py # SQLite (aiosqlite) Persistenz
│ ├── models.py # Pydantic Assessment-Model
│ ├── parlamente.py # OPAL-Adapter für NRW Landtag
│ ├── report.py # PDF-Generierung (WeasyPrint)
│ ├── config.py # Settings + Environment
│ ├── embeddings.py # Wahlprogramm-Embeddings (optional)
│ ├── kontext/
│ │ ├── gwoe-matrix-2.0.md # GWÖ-Matrix Referenz
│ │ ├── wahlprogramme-nrw-2022.md # Zusammenfassungen
│ │ ├── parteiprogramme.md # Grundsatzprogramme
│ │ └── *-nrw-2022-paged.txt # Volltext (paginiert)
│ ├── templates/
│ │ ├── index.html # Haupt-UI (Jinja2)
│ │ └── quellen.html # Quellenübersicht
│ └── static/
│ └── referenzen/ # Original-PDFs der Programme
├── data/ # SQLite-DBs (Docker Volume)
│ └── gwoe-antraege.db # Haupt-Datenbank
├── reports/ # Generierte PDFs (Docker Volume)
├── docker-compose.yml # Traefik + Let's Encrypt
├── Dockerfile # Python 3.12 + WeasyPrint
├── requirements.txt
├── .env.example
├── .gitignore
├── .dockerignore
├── LICENSE (MIT)
└── README.md
✨ Features (Stand 28.03.2026)
Analyse
- GWÖ-Score (0-10) mit Matrix-Zuordnung
- Bewertungssymbole (++/+/○/−/−−) pro Matrix-Feld
- Wahlprogrammtreue (0-10) pro Fraktion
- Parteiprogrammtreue (0-10) pro Fraktion
- Verbesserungsvorschläge im Redline-Format
- Original-Zitat aus dem Antrag
- Konkreter Verbesserungsvorschlag
- GWÖ-Begründung
- Themen-Tags für Kategorisierung
- Retry-Logik (3 Versuche) bei JSON-Parse-Fehlern
UI
- Score-Filter (Alle / 8-10 / 5-7 / 0-4)
- Partei-Filter (Dropdown)
- Durchschnittswerte pro Partei (kompakte Stats-Bar)
- Tag-Wolke mit Multi-Select (Schnittmenge)
- Landtag-Suche via OPAL-API
- "Jetzt prüfen"-Button für neue Anträge
- Detail-Ansicht mit allen Bewertungen
- PDF-Download pro Antrag
Security
- Content-Security-Policy
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- X-XSS-Protection
- Referrer-Policy
- Permissions-Policy
- /docs, /redoc, /openapi.json deaktiviert
Infrastruktur
- Docker Compose mit Traefik Reverse Proxy
- Let's Encrypt SSL
- Persistente SQLite-DB (Volume, überlebt Container-Neustarts)
- Git-Repository auf repo.toppyr.de
🔧 Konfiguration
Environment-Variablen (.env)
DASHSCOPE_API_KEY=sk-... # Alibaba DashScope API
KEYCLOAK_URL=https://sso.toppyr.de # Optional: SSO
KEYCLOAK_REALM=collaboration
KEYCLOAK_CLIENT_ID=gwoe-antragspruefer
LLM-Modelle
| Modell | Verwendung | Kosten |
|---|---|---|
qwen-plus-latest |
Standard (Free Tier) | Kostenlos |
qwen-plus |
Fallback (Paid) | ~$0.80/MTok |
qwen-max |
Premium | ~$2.40/MTok |
📊 API-Endpoints
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | / |
Web-UI |
| GET | /health |
Health Check |
| GET | /quellen |
Quellenübersicht |
| GET | /api/assessments |
Alle Bewertungen (JSON) |
| GET | /api/assessment?drucksache=18/12345 |
Einzelne Bewertung |
| GET | /api/search?q=Klima |
Interne DB-Suche |
| GET | /api/search-landtag?q=Klima |
Landtag OPAL-Suche |
| POST | /api/analyze-drucksache |
Neue Analyse starten |
| GET | /api/assessment/pdf?drucksache=18/12345 |
PDF-Download |
| GET | /api/bundeslaender |
Verfügbare Bundesländer |
| GET | /status/{job_id} |
Job-Status abfragen |
🧠 Prompt v5 — Kern-Features
Der Analyse-Prompt fordert:
-
GWÖ-Treue (0-10) mit Matrix-Zuordnung:
- Matrix-Feld (z.B. "D1 Menschenwürde")
- Symbol (++/+/○/−/−−)
- Kurzbegründung
-
Programmtreue für Antragsteller UND Regierungsfraktionen:
- Wahlprogramm-Score (0-10)
- Parteiprogramm-Score (0-10)
- Begründungen
-
Verbesserungsvorschläge (max. 3):
{ "original": "Zitat aus dem Antrag", "vorschlag": "Konkret **verbesserter** Text", "begruendung": "Stärkt GWÖ-Wert X durch Y" } -
Themen-Tags für Kategorisierung
🚀 Deployment
Erstinstallation
ssh vserver
cd /opt
git clone https://repo.toppyr.de/tobias/gwoe-antragspruefer.git
cd gwoe-antragspruefer
# .env erstellen
cp .env.example .env
nano .env # DASHSCOPE_API_KEY eintragen
# Starten
docker compose up -d
Update
# Lokal
cd ~/Nextcloud/dotty/projekte/2026-03-23\ GWÖ-Antragsprüfer\ _WIP_/webapp
git add . && git commit -m "Update" && git push
# Auf Server
ssh vserver 'cd /opt/gwoe-antragspruefer && git pull && docker compose up -d --build'
Manuelles Deploy (ohne Git auf Server)
cd ~/Nextcloud/dotty/projekte/2026-03-23\ GWÖ-Antragsprüfer\ _WIP_/webapp
tar czf /tmp/gwoe-webapp.tar.gz --exclude='venv' --exclude='__pycache__' --exclude='data' --exclude='reports' --exclude='.env' .
scp /tmp/gwoe-webapp.tar.gz vserver:/tmp/
ssh vserver 'cd /opt/gwoe-antragspruefer && tar xzf /tmp/gwoe-webapp.tar.gz && docker compose up -d --build'
📈 Statistiken (28.03.2026)
| Metrik | Wert |
|---|---|
| Analysierte Anträge | 20 |
| Ø GWÖ-Score gesamt | 4.6 |
| Ø SPD | 7.7 |
| Ø GRÜNE | 6.0 |
| Ø CDU | 6.0 |
| Ø FDP | 4.8 |
| Ø AfD | 1.5 |
🐛 Bekannte Issues / TODOs
Offen
- Keycloak SSO-Integration aktivieren
- Weitere Bundesländer (BY, BW) anbinden
- Batch-Analyse für viele Anträge
- Wahlprogramm-Zitate mit Seitenzahlen
- Export als CSV/Excel
Gelöst (28.03.2026)
- JSON-Parse-Fehler bei LLM-Output → Retry-Logik
- DB nicht persistent → Dockerfile gefixt, data/ als Volume
- Alte Assessments überschreiben neue → JSON-Import deaktiviert
- Partei-Filter zeigt "Suchfehler" → JS-Bug gefixt
📝 Changelog
v1.0.0 (28.03.2026)
- Initial Release
- GWÖ-Matrix 2.0 Analyse für NRW
- Verbesserungsvorschläge im Redline-Format
- Tag-Wolke mit Multi-Select
- Partei-Filter + Durchschnittswerte
- Security Headers
- Docker Deployment
📚 Quellen
- GWÖ-Matrix 2.0 für Gemeinden (Arbeitsbuch)
- ECOnGOOD Corporate Design Manual 2024
- NRW OPAL Parlamentsdokumentation
- Wahlprogramme NRW 2022 (CDU, GRÜNE, SPD, FDP, AfD)
- Grundsatzprogramme der Parteien
Entwickelt von Tobias Rödel mit Unterstützung von Dotty 👻