#96 Methodik-/Transparenz-Seite unter /methodik
Neue Seite für Endnutzer-Transparenz über die Bewertungsmethodik: - GWÖ-Matrix 2.0 Erklärung mit interaktivem 5×5-Grid - Analyse-Pipeline als 5-Schritt-Visualisierung (Download → Embedding → LLM → Verifikation → Darstellung) - Wahlprogramm-Vergleich: Erklärung des Retrieval + Top-K + Verifikation - Qualitätssicherung: Sub-D Property-Tests, server-seitige Quellen- Rekonstruktion, automatische Neu-Analyse - Einschränkungen: KI-Bias, keine juristische Bewertung, nur indexierte Programme, kein Abstimmungsverhalten - Datenquellen: dynamische Tabelle aller angebundenen Parlamente aus ADAPTERS + bundeslaender.py - Technische Details aufklappbar (details/summary) für Interessierte, Haupttext verständlich für Nicht-Techniker - Links zu Quellen-Seite, Adapter-Matrix, ADRs In Hauptnavigation verlinkt (neben Quellen + Auswertungen). Template-Variablen: adapter_count, model_name, programme_count, chunk_count, bundeslaender — alles dynamisch aus dem Backend. Tests: 194/194 grün. Refs: #96
This commit is contained in:
parent
5ea507b771
commit
07507de24a
27
app/main.py
27
app/main.py
@ -633,6 +633,33 @@ async def list_bundeslaender():
|
|||||||
|
|
||||||
# === Quellen / Programme ===
|
# === Quellen / Programme ===
|
||||||
|
|
||||||
|
@app.get("/methodik", response_class=HTMLResponse)
|
||||||
|
async def methodik_page(request: Request):
|
||||||
|
"""Transparenz-/Methodik-Seite (#96)."""
|
||||||
|
from .bundeslaender import aktive_bundeslaender, BUNDESLAENDER
|
||||||
|
from .embeddings import get_indexing_status
|
||||||
|
|
||||||
|
bl_list = []
|
||||||
|
for bl in aktive_bundeslaender():
|
||||||
|
bl_list.append({
|
||||||
|
"code": bl.code,
|
||||||
|
"name": bl.name,
|
||||||
|
"doku_system": bl.doku_system,
|
||||||
|
})
|
||||||
|
|
||||||
|
status = get_indexing_status()
|
||||||
|
|
||||||
|
return templates.TemplateResponse("methodik.html", {
|
||||||
|
"request": request,
|
||||||
|
"app_name": settings.app_name,
|
||||||
|
"adapter_count": len(ADAPTERS),
|
||||||
|
"model_name": settings.llm_model_default,
|
||||||
|
"programme_count": status.get("total", 0),
|
||||||
|
"chunk_count": sum(p.get("chunks", 0) for p in status.get("programmes", [])),
|
||||||
|
"bundeslaender": sorted(bl_list, key=lambda x: x["name"]),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.get("/quellen", response_class=HTMLResponse)
|
@app.get("/quellen", response_class=HTMLResponse)
|
||||||
async def quellen_page(request: Request):
|
async def quellen_page(request: Request):
|
||||||
"""Quellen-Seite mit allen Wahl- und Parteiprogrammen."""
|
"""Quellen-Seite mit allen Wahl- und Parteiprogrammen."""
|
||||||
|
|||||||
@ -700,6 +700,7 @@
|
|||||||
<button class="mode-btn" onclick="showMode('tags')">🏷️ Tags</button>
|
<button class="mode-btn" onclick="showMode('tags')">🏷️ Tags</button>
|
||||||
<button class="mode-btn" onclick="showMode('upload')">📤 Prüfen</button>
|
<button class="mode-btn" onclick="showMode('upload')">📤 Prüfen</button>
|
||||||
<a href="/quellen" class="mode-btn" style="text-decoration: none;">📚 Quellen</a>
|
<a href="/quellen" class="mode-btn" style="text-decoration: none;">📚 Quellen</a>
|
||||||
|
<a href="/methodik" class="mode-btn" style="text-decoration: none;">🔍 Methodik</a>
|
||||||
<button id="auth-btn" class="mode-btn" style="border:none;cursor:pointer;font-size:0.85rem;">🔑 Anmelden</button>
|
<button id="auth-btn" class="mode-btn" style="border:none;cursor:pointer;font-size:0.85rem;">🔑 Anmelden</button>
|
||||||
<a href="/auswertungen" class="mode-btn" style="text-decoration: none;">📈 Auswertungen</a>
|
<a href="/auswertungen" class="mode-btn" style="text-decoration: none;">📈 Auswertungen</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
363
app/templates/methodik.html
Normal file
363
app/templates/methodik.html
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Methodik — {{ app_name }}</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color-darkgray: #5a5a5a;
|
||||||
|
--color-green: #889e33;
|
||||||
|
--color-blue: #009da5;
|
||||||
|
--color-lightgray: #bfbfbf;
|
||||||
|
--color-bg: #f5f5f5;
|
||||||
|
--color-amber: #ffc107;
|
||||||
|
}
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
font-family: 'Avenir', 'Segoe UI', sans-serif;
|
||||||
|
color: var(--color-darkgray);
|
||||||
|
line-height: 1.6;
|
||||||
|
background: var(--color-bg);
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background: white;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
border-bottom: 1px solid var(--color-lightgray);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.header h1 { color: var(--color-blue); font-size: 1.5rem; }
|
||||||
|
.header a { color: var(--color-blue); text-decoration: none; }
|
||||||
|
.container { max-width: 900px; margin: 2rem auto; padding: 0 2rem; }
|
||||||
|
h2 {
|
||||||
|
color: var(--color-blue);
|
||||||
|
margin: 2rem 0 1rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 2px solid var(--color-blue);
|
||||||
|
}
|
||||||
|
h3 { color: var(--color-green); margin: 1.5rem 0 0.5rem; }
|
||||||
|
.card {
|
||||||
|
background: white;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,.08);
|
||||||
|
}
|
||||||
|
.matrix-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto repeat(5, 1fr);
|
||||||
|
gap: 2px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
.matrix-grid .cell {
|
||||||
|
padding: 0.4rem;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
.matrix-grid .header-cell {
|
||||||
|
background: var(--color-blue);
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.matrix-grid .row-header {
|
||||||
|
background: var(--color-green);
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
details { margin: 0.5rem 0; }
|
||||||
|
details summary {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color-blue);
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.3rem 0;
|
||||||
|
}
|
||||||
|
details summary:hover { text-decoration: underline; }
|
||||||
|
.pipeline-step {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 1rem;
|
||||||
|
margin: 0.75rem 0;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid var(--color-blue);
|
||||||
|
}
|
||||||
|
.step-num {
|
||||||
|
background: var(--color-blue);
|
||||||
|
color: white;
|
||||||
|
width: 28px; height: 28px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.note {
|
||||||
|
background: #fff3cd;
|
||||||
|
border-left: 3px solid var(--color-amber);
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
table { border-collapse: collapse; width: 100%; margin: 0.5rem 0; }
|
||||||
|
th, td { padding: 0.5rem; border: 1px solid #e0e0e0; text-align: left; font-size: 0.9rem; }
|
||||||
|
th { background: #f0f0f0; }
|
||||||
|
a { color: var(--color-blue); }
|
||||||
|
.footer { text-align: center; padding: 2rem; color: #999; font-size: 0.85rem; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>{{ app_name }}</h1>
|
||||||
|
<a href="/">Bewertungen</a>
|
||||||
|
<a href="/auswertungen">Auswertungen</a>
|
||||||
|
<a href="/quellen">Quellen</a>
|
||||||
|
<strong>Methodik</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>Wie funktioniert der GWÖ-Antragsprüfer?</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>
|
||||||
|
Der GWÖ-Antragsprüfer bewertet Parlamentsanträge automatisch nach der
|
||||||
|
<strong>Gemeinwohl-Ökonomie Matrix 2.0 für Gemeinden</strong>. Jede Bewertung
|
||||||
|
analysiert drei Dimensionen: GWÖ-Treue, Übereinstimmung mit Wahlprogrammen
|
||||||
|
und Übereinstimmung mit Grundsatzprogrammen der Parteien.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top: 0.5rem;">
|
||||||
|
Alle Bewertungen werden durch ein KI-Sprachmodell erzeugt und anschließend
|
||||||
|
<strong>automatisch verifiziert</strong> — Zitate werden gegen die Originaltexte
|
||||||
|
der Wahlprogramme geprüft, nicht-verifizierbare Zitate werden verworfen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Die GWÖ-Matrix 2.0</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>Die Matrix besteht aus <strong>5 Berührungsgruppen</strong> (Zeilen) und
|
||||||
|
<strong>5 Werten</strong> (Spalten) = 25 Themenfelder:</p>
|
||||||
|
|
||||||
|
<div class="matrix-grid">
|
||||||
|
<div class="cell"></div>
|
||||||
|
<div class="header-cell">Menschen­würde</div>
|
||||||
|
<div class="header-cell">Solidarität</div>
|
||||||
|
<div class="header-cell">Ökologische Nachhaltig­keit</div>
|
||||||
|
<div class="header-cell">Soziale Gerechtig­keit</div>
|
||||||
|
<div class="header-cell">Transparenz & Demokratie</div>
|
||||||
|
|
||||||
|
<div class="row-header">A · Lieferanten</div>
|
||||||
|
<div class="cell">A1</div><div class="cell">A2</div><div class="cell">A3</div><div class="cell">A4</div><div class="cell">A5</div>
|
||||||
|
|
||||||
|
<div class="row-header">B · Finanzen</div>
|
||||||
|
<div class="cell">B1</div><div class="cell">B2</div><div class="cell">B3</div><div class="cell">B4</div><div class="cell">B5</div>
|
||||||
|
|
||||||
|
<div class="row-header">C · Verwaltung</div>
|
||||||
|
<div class="cell">C1</div><div class="cell">C2</div><div class="cell">C3</div><div class="cell">C4</div><div class="cell">C5</div>
|
||||||
|
|
||||||
|
<div class="row-header">D · Bürger</div>
|
||||||
|
<div class="cell">D1</div><div class="cell">D2</div><div class="cell">D3</div><div class="cell">D4</div><div class="cell">D5</div>
|
||||||
|
|
||||||
|
<div class="row-header">E · Gesellschaft</div>
|
||||||
|
<div class="cell">E1</div><div class="cell">E2</div><div class="cell">E3</div><div class="cell">E4</div><div class="cell">E5</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Jedes Feld wird auf einer Skala von <strong>-5</strong> (fundamental widersprechend)
|
||||||
|
bis <strong>+5</strong> (stark fördernd) bewertet. Der Gesamtscore (0-10) gewichtet
|
||||||
|
die Matrix-Bewertungen und berücksichtigt Ausschlusskriterien:</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Symbol</th><th>Rating</th><th>Bedeutung</th></tr>
|
||||||
|
<tr><td>++</td><td>+4 bis +5</td><td>Stark fördernd, vorbildlich</td></tr>
|
||||||
|
<tr><td>+</td><td>+1 bis +3</td><td>Fördernd</td></tr>
|
||||||
|
<tr><td>○</td><td>0</td><td>Neutral / nicht berührt</td></tr>
|
||||||
|
<tr><td>−</td><td>-1 bis -3</td><td>Widersprechend</td></tr>
|
||||||
|
<tr><td>−−</td><td>-4 bis -5</td><td>Stark widersprechend</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Mehr zur GWÖ-Matrix</summary>
|
||||||
|
<p style="margin-top: 0.5rem;">
|
||||||
|
Die Matrix basiert auf dem
|
||||||
|
<a href="https://econgood.org" target="_blank">Arbeitsbuch der Gemeinwohl-Ökonomie</a>.
|
||||||
|
Die Adaption für Gemeinden fokussiert auf kommunale Handlungsfelder:
|
||||||
|
Beschaffung, Haushalt, Verwaltung, Daseinsvorsorge und überregionale Wirkung.
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Analyse-Pipeline</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>Jede Bewertung durchläuft fünf Schritte:</p>
|
||||||
|
|
||||||
|
<div class="pipeline-step">
|
||||||
|
<div class="step-num">1</div>
|
||||||
|
<div>
|
||||||
|
<strong>Antrags-Text herunterladen</strong><br>
|
||||||
|
Der Volltext wird automatisch aus dem jeweiligen Landtags-Portal geholt
|
||||||
|
({{ adapter_count }} Parlamente angebunden). Der PDF-Text wird via PyMuPDF extrahiert.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pipeline-step">
|
||||||
|
<div class="step-num">2</div>
|
||||||
|
<div>
|
||||||
|
<strong>Relevante Wahlprogramm-Passagen suchen</strong><br>
|
||||||
|
Für <strong>alle Fraktionen der Wahlperiode</strong> werden per Embedding-Suche
|
||||||
|
(Qwen text-embedding-v3) die thematisch relevantesten Passagen aus Wahl- und
|
||||||
|
Grundsatzprogrammen gesucht (Top-5 pro Partei, Cosinus-Ähnlichkeit ≥ 0.45).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pipeline-step">
|
||||||
|
<div class="step-num">3</div>
|
||||||
|
<div>
|
||||||
|
<strong>KI-Bewertung</strong><br>
|
||||||
|
Ein Sprachmodell ({{ model_name }}) bewertet den Antrag anhand der GWÖ-Matrix
|
||||||
|
und vergleicht ihn mit den gefundenen Programm-Passagen. Der Prompt enthält
|
||||||
|
strikte Regeln für die Quellenangabe (nur wörtliche Zitate aus den vorgelegten Passagen).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pipeline-step">
|
||||||
|
<div class="step-num">4</div>
|
||||||
|
<div>
|
||||||
|
<strong>Zitat-Verifikation</strong><br>
|
||||||
|
Jedes vom Modell genannte Zitat wird <strong>server-seitig verifiziert</strong>:
|
||||||
|
Der zitierte Text muss als Substring (oder 5-Wort-Sequenz) in einem der
|
||||||
|
vorgelegten Chunks auffindbar sein. Nicht-verifizierbare Zitate werden
|
||||||
|
verworfen — Quellenangabe und Seitenzahl werden aus dem echten Treffer
|
||||||
|
rekonstruiert, nicht aus der Modell-Ausgabe übernommen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pipeline-step">
|
||||||
|
<div class="step-num">5</div>
|
||||||
|
<div>
|
||||||
|
<strong>Persistierung & Darstellung</strong><br>
|
||||||
|
Die verifizierte Bewertung wird gespeichert. Klick auf ein Zitat öffnet
|
||||||
|
das Original-Wahlprogramm-PDF mit <strong>gelb markierter Fundstelle</strong>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Technische Details zum Sprachmodell</summary>
|
||||||
|
<div style="margin-top: 0.5rem;">
|
||||||
|
<table>
|
||||||
|
<tr><th>Eigenschaft</th><th>Wert</th></tr>
|
||||||
|
<tr><td>Modell</td><td>{{ model_name }}</td></tr>
|
||||||
|
<tr><td>Anbieter</td><td>DashScope (Alibaba Cloud)</td></tr>
|
||||||
|
<tr><td>Retry bei Parse-Fehlern</td><td>3 Versuche mit steigender Temperatur</td></tr>
|
||||||
|
<tr><td>Embedding-Modell</td><td>text-embedding-v3 (1024 Dimensionen)</td></tr>
|
||||||
|
<tr><td>Chunk-Größe</td><td>400 Wörter, 50 Wörter Overlap</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Wahlprogramm-Vergleich</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>
|
||||||
|
Für jede Fraktion der aktuellen Wahlperiode wird die <strong>Passung</strong>
|
||||||
|
des Antrags zu zwei Programmen bewertet:
|
||||||
|
</p>
|
||||||
|
<ul style="margin: 0.5rem 0 0.5rem 1.5rem;">
|
||||||
|
<li><strong>Wahlprogramm</strong> — das Landtags-Wahlprogramm der jeweiligen Legislaturperiode</li>
|
||||||
|
<li><strong>Grundsatzprogramm</strong> — das aktuelle Bundespartei-Grundsatzprogramm</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Aktuell sind <strong>{{ programme_count }} Programme</strong> indexiert
|
||||||
|
({{ chunk_count }} Textabschnitte). Die vollständige Liste ist auf der
|
||||||
|
<a href="/quellen">Quellen-Seite</a> einsehbar.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="note">
|
||||||
|
<strong>Wichtig:</strong> Wenn für eine Fraktion kein Programm im Index vorhanden ist,
|
||||||
|
wird kein Score vergeben — stattdessen erscheint ein Hinweis. Bewertungen
|
||||||
|
basieren ausschließlich auf verifizierbaren Quellen, nicht auf dem Trainingswissen
|
||||||
|
des Sprachmodells.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Qualitätssicherung</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Zitat-Verifikation (Sub-D)</h3>
|
||||||
|
<p>
|
||||||
|
Ein automatisierter Property-Test prüft für jedes in der Datenbank gespeicherte
|
||||||
|
Zitat, ob der zitierte Text tatsächlich auf der angegebenen Seite des
|
||||||
|
Wahlprogramm-PDFs vorkommt (Substring- oder 5-Wort-Anker-Match). Dieses
|
||||||
|
Verfahren hat im April 2026 drei halluzinierte Zitate aufgedeckt und zur
|
||||||
|
Implementierung der server-seitigen Verifikation geführt.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Server-seitige Quellen-Rekonstruktion</h3>
|
||||||
|
<p>
|
||||||
|
Das Sprachmodell darf keine Quellenangaben (Programmname, Seitenzahl) frei
|
||||||
|
erfinden. Nach jeder Analyse wird jedes Zitat gegen die tatsächlich vorgelegten
|
||||||
|
Textabschnitte abgeglichen. Quellenangabe und URL werden aus dem gefundenen
|
||||||
|
Treffer <strong>server-seitig konstruiert</strong> — die Modell-Ausgabe für
|
||||||
|
diese Felder wird verworfen.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Automatische Neu-Analyse</h3>
|
||||||
|
<p>
|
||||||
|
Wenn ein Nutzer auf ein Zitat klickt und die Textstelle im PDF nicht auffindbar
|
||||||
|
ist (z.B. bei älteren Bewertungen vor der Verifikations-Einführung), wird der
|
||||||
|
Antrag automatisch mit der aktuellen Pipeline neu analysiert.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Einschränkungen</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<ul style="margin-left: 1.5rem;">
|
||||||
|
<li><strong>Keine juristische Bewertung</strong> — die GWÖ-Analyse ist eine
|
||||||
|
wertebasierte Einordnung, keine Rechtsprüfung.</li>
|
||||||
|
<li><strong>KI-Bias</strong> — Sprachmodelle können systematische Verzerrungen
|
||||||
|
aufweisen. Die Bewertungen sollten als Orientierung verstanden werden,
|
||||||
|
nicht als objektive Wahrheit.</li>
|
||||||
|
<li><strong>Nur indexierte Programme</strong> — Parteien ohne hinterlegtes
|
||||||
|
Programm können nicht zuverlässig bewertet werden.</li>
|
||||||
|
<li><strong>Keine Analyse des Abstimmungsverhaltens</strong> — bewertet wird
|
||||||
|
der Antragstext, nicht ob oder wie darüber abgestimmt wurde.</li>
|
||||||
|
<li><strong>Aktualität</strong> — Wahlprogramme werden einmalig zur Wahl
|
||||||
|
indexiert und nicht automatisch aktualisiert.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Datenquellen</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p><strong>{{ adapter_count }} Parlamente</strong> sind angebunden:</p>
|
||||||
|
<table>
|
||||||
|
<tr><th>Parlament</th><th>Doku-System</th></tr>
|
||||||
|
{% for bl in bundeslaender %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ bl.name }} ({{ bl.code }})</td>
|
||||||
|
<td>{{ bl.doku_system }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<p style="margin-top: 1rem;">
|
||||||
|
<a href="/quellen">Vollständige Programm-Liste</a> ·
|
||||||
|
<a href="https://docs.toppyr.de/gwoe-antragspruefer/reference/adapter-capabilities/" target="_blank">Technische Adapter-Vergleichsmatrix</a> ·
|
||||||
|
<a href="https://docs.toppyr.de/gwoe-antragspruefer/adr/" target="_blank">Architektur-Entscheidungen (ADRs)</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
{{ app_name }} · <a href="https://econgood.org" target="_blank">Gemeinwohl-Ökonomie</a> ·
|
||||||
|
<a href="https://repo.toppyr.de/tobias/gwoe-antragspruefer" target="_blank">Quellcode</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user