WahlCheck

WahlCheck ist eine selbst gehostete, datengetriebene Wahlhilfe in Go. Nutzer beantworten politische Thesen, gewichten besonders wichtige Positionen und vergleichen ihre Antworten transparent mit Parteien. Die Anwendung formuliert bewusst keine Wahlempfehlung. Der mitgelieferte Datensatz ist vollständig fiktiv.

Funktionen

  • Vollständiger SSR-Ablauf ohne Frontend-Framework oder Buildsystem
  • Korrigierbare Antworten, Überspringen und doppelte Gewichtung
  • Auswahl beliebiger Parteien, Prozentwerte und sortierte Ergebnisse
  • Detailmatrix mit Parteibegründungen und Kategorieauswertung
  • HMAC-signierte, zweistündige HttpOnly-Cookie-Session; keine Nutzerantworten in SQLite
  • CSRF-Schutz, CSP und weitere Security-Header, Request-Limit und Server-Timeouts
  • JSON-Validierung und CLI-Verwaltung mehrerer Wahlen
  • Geschützter Web-Import per Datei-Upload oder Copy-and-paste
  • Eingebettete Templates, CSS und JavaScript; reiner Go-SQLite-Treiber ohne CGO

Voraussetzungen und Build

Go 1.24 oder neuer:

git clone <repository-url>
cd wahlcheck
go mod download
go build -o wahlcheck ./cmd/server

Schnellstart

export WAHLCHECK_SESSION_SECRET="$(openssl rand -base64 48)"
export WAHLCHECK_ADMIN_PASSWORD="eine-lange-einmalige-passphrase"
./wahlcheck import data/example-election.json
./wahlcheck serve

Danach http://localhost:8080 öffnen. Das Secret muss mindestens 32 Zeichen lang und in Produktion dauerhaft gesetzt sein. Ohne gültiges Secret erzeugt der Server nur für lokale Entwicklung ein zufälliges temporäres Secret; bestehende Sessions verfallen dann beim Neustart.

CLI

./wahlcheck validate data/example-election.json
./wahlcheck import data/example-election.json
./wahlcheck elections
./wahlcheck delete-election demo-2026
./wahlcheck serve

Ein erneuter Import derselben Wahl-ID aktualisiert den kompletten Datensatz atomar. Fehlerhafte Datensätze werden vor einer Datenbankänderung abgelehnt.

Konfiguration

Variable Standard Bedeutung
WAHLCHECK_LISTEN :8080 HTTP-Listenadresse
WAHLCHECK_DATABASE ./wahlcheck.db Pfad zur SQLite-Datei
WAHLCHECK_SESSION_SECRET keiner HMAC-Secret, mindestens 32 Zeichen
WAHLCHECK_SECURE_COOKIE false true bei HTTPS; setzt das Secure-Attribut
WAHLCHECK_ADMIN_PASSWORD keiner Aktiviert den geschützten Web-Import unter /admin/login

Import im Browser

Setze WAHLCHECK_ADMIN_PASSWORD, starte den Server und öffne http://localhost:8080/admin/login. Nach der Anmeldung kann eine JSON-Datei bis 10 MB hochgeladen oder JSON direkt eingefügt werden. „Nur validieren“ zeigt eine Vorschau, ohne Daten zu speichern. „Validieren und importieren“ veröffentlicht den Datensatz atomar. Eine vorhandene Wahl mit derselben ID wird nur nach ausdrücklicher Bestätigung vollständig ersetzt. Ist keine Admin-Passphrase konfiguriert, antwortet der Adminbereich mit 503 und bleibt deaktiviert.

Nachrichtenanalyse und Thesenentwürfe

Unter /admin/news kann eine einzelne Artikel-URL analysiert werden. Aus Sicherheits- und Neutralitätsgründen akzeptiert WahlCheck ausschließlich HTTPS-URLs von rbb24.de, tagesspiegel.de, berliner-zeitung.de, taz.de, deutschlandfunk.de und deutschlandfunkkultur.de. Der Artikel muss einen erkennbaren Berlin-Bezug besitzen.

Die lokale Analyse ordnet Schlagwörter transparent politischen Kategorien zu und erzeugt neutrale, vorformulierte Thesenentwürfe. Erwähnungen von sozialen Medien, Plattformen, Influencern oder Desinformation setzen zusätzlich das Flag Social Media. Gespeichert werden Entwurf, Artikelüberschrift und Link, nicht der vollständige urheberrechtlich geschützte Artikeltext. Entwürfe erhalten den Status draft und werden weder automatisch einer Wahl hinzugefügt noch für das Scoring verwendet. Parteipositionen müssen weiterhin aus einer expliziten, belegbaren Parteiquelle stammen.

Für einen öffentlichen Betrieb TLS an einem Reverse Proxy terminieren, WAHLCHECK_SECURE_COOKIE=true setzen, ein langlebiges zufälliges Secret aus dem Secret-Management verwenden und die SQLite-Datei sichern.

Tests und Qualität

go fmt ./...
go vet ./...
go test ./...

Die Tests decken alle neun Antwortkombinationen, normale/wichtige/übersprungene Thesen, Gesamtsortierung und fehlerhafte Importe ab.

Docker Compose

export WAHLCHECK_SESSION_SECRET="$(openssl rand -base64 48)"
docker compose build
docker compose run --rm wahlcheck import /opt/wahlcheck/example-election.json
docker compose up -d

SQLite liegt im Volume wahlcheck-data. Setze hinter HTTPS zusätzlich WAHLCHECK_SECURE_COOKIE=true.

Datenformat

Eine Datei enthält election, theses und parties. Jede Partei muss genau für jede Thesis eine Position mit answer (-1, 0, 1) und nichtleerer reason besitzen. IDs müssen eindeutig sein, das Datum verwendet YYYY-MM-DD. Ein vollständiges Beispiel steht in data/example-election.json.

Architektur

internal/election enthält Modell, Validierung, Service und die unabhängige Scoring Engine. internal/storage implementiert das Repository in normalisiertem SQLite. internal/web enthält die HTTP-Schicht, signierte Sessions, Middleware sowie eingebettete UI-Dateien. cmd/server stellt CLI und den explizit konfigurierten HTTP-Server mit Graceful Shutdown bereit.

Datenschutz

Es gibt keine Konten, Analytics, Tracking-IDs oder IP-Profile. Wahlantworten und politische Präferenzen werden weder geloggt noch in SQLite gespeichert. Sie befinden sich signiert im Browser-Cookie und verfallen nach zwei Stunden oder über „Antworten löschen / Neu starten“.

S
Description
wahlcheck Sonntagsprojekt
Readme 64 KiB
Languages
Go 79.6%
HTML 18.2%
Dockerfile 0.9%
JavaScript 0.7%
CSS 0.6%