Files
BSN-Chatsystem/bsn-system-standards-todo.md

7.3 KiB

BSN System- & Prozess-Standards — TODO

Quelle: Externes Review-Feedback (21. Juni 2026) Kontext: Code-Standards (v1.0) decken die Datei-Ebene ab. Diese Liste adressiert die System- und Prozess-Ebene — wo der größere Hebel liegt.


P0 — Sofort (höchste Hebelwirkung)

sys-1: Gitea Actions CI-Gate

Problem: pre-commit ist mit --no-verify in 2 Sekunden umgangen — und KI-generierter Code (Cody, Kevin) hat keinen lokalen pre-commit-Pfad. Die eigentliche Durchsetzung muss serverseitig im Repo sitzen.

Lösung: Gitea Actions Workflow, der bei jedem Push ausgeführt wird:

  • ruff check . (Linting + Sicherheit)
  • ruff format --check . (Formatierung)
  • mypy . (Typ-Prüfung, im echten venv)
  • pytest --cov --cov-fail-under=80 (Tests + Coverage)

Warum P0: Ohne serverseitigen Gate sind alle Coding-Standards freiwillig. Mit Gitea Actions ist kein Merge ohne bestandene Checks möglich — unabhängig davon, wer oder was den Code geschrieben hat.

Umsetzung: .gitea/workflows/quality.yml im Repo anlegen.


sys-2: Edge-Queue + Idempotenz (Chatbot)

Problem: Wenn der WireGuard-Tunnel zur Heim-GPU wackelt oder die Box neu startet, gehen Einreichungen verloren. Telegram/WhatsApp-Webhooks stellen bei Timeout erneut zu → ohne Idempotenz wird dieselbe Einreichung mehrfach verarbeitet.

Lösung (3 Komponenten):

  1. Queue am Hetzner-Edge — Redis Streams oder NATS, puffert Submissions statt sie synchron an die Heim-GPU durchzureichen
  2. Idempotenz — Webhook-Signatur/Deduplication-Key vor Verarbeitung prüfen, doppelte Zustellungen erkennen und verwerfen
  3. Webhook-Signaturprüfung — X-Hub-Signature-256 (WhatsApp) / SHA256-HMAC (Telegram) am Edge validieren, bevor irgendwas in die Queue geht

Warum P0: Einzige Stelle, wo Nutzer direkt zuschauen. „Tunnel down = Datenverlust" → „Tunnel down = Verarbeitung verzögert". Das ist der Unterschied zwischen „funktioniert" und „Produktion".

Umsetzung: Architektur-Skizze + Redis-Integration in den bestehenden Flask-Intake.


P1 — Bald (hohe Hebelwirkung, etwas Aufwand)

sys-3: uv + Lockfile

Problem: pip install ruff mypy ... ohne Lockfile → kein reproduzierbarer Stand. Drei Maschinen (GB10/ARM64, Strix Halo/x86_64, Hetzner/AMD64) mit unterschiedlicher Architektur → „läuft bei mir" ist vorprogrammiert.

Lösung: Wechsel auf uv (Astral-Ökosystem, gleicher Hersteller wie Ruff):

  • uv pip compile pyproject.toml -o requirements.txt → lockfile
  • uv sync → installiert exakt die gelockten Versionen
  • uv lock --check in CI → bricht Build, wenn Lockfile nicht aktuell

Vorteile: Drastisch schneller als pip, reproduzierbar, selbes Ökosystem wie Ruff.

Umsetzung: uv installieren, uv.lock generieren, Doku-Abschnitt in Coding-Standards ergänzen.


sys-4: Pydantic an API-Grenzen

Problem: Externe Daten (Gamefound-API, Amazon PAAPI, FantasyWelt-CSV, BGG, Scraper) werden als dict[str, Any] modelliert — mypy strict hilft null, und zur Laufzeit knallt's, wenn ein Feld fehlt.

Lösung: Pydantic-Modelle an jeder API-/Scraper-Grenze:

  • Laufzeit-Validierung → sofortiger Fehler mit Kontext, nicht erst 3 Schichten später
  • Echte Typen → mypy kann innen durchvalidieren
  • Any bleibt auf die Grenzschicht beschränkt, innen nur validierte Objekte

Beispiel:

from pydantic import BaseModel

class GamefoundProject(BaseModel):
    id: str
    title: str
    funding_eur: float
    backers: int | None = None
    end_date: datetime

# API-Response → validiertes Modell
project = GamefoundProject.model_validate(api_response)
# Ab hier: mypy-safe, keine Überraschungen

Umsetzung: Pydantic-Modelle für Gamefound, BGG, Amazon PAAPI, SPIEL-Essen-API definieren.


sys-5: Observability (structlog + GlitchTip)

Problem: „Mit Kontext loggen" steht in den Standards, aber ohne konkrete Werkzeuge. Bei einem öffentlichen Chatbot mit mehreren Servern erfährst du von Fehlern erst, wenn ein Nutzer sich beschwert.

Lösung:

  1. structlog — strukturiertes Logging, JSON-Output, kontextbehaftet
  2. GlitchTip — selbstgehostet, Sentry-kompatibel, ein Bruchteil der Ressourcen
import structlog
logger = structlog.get_logger()

logger.info("submission_processed",
    submission_id=sub.id,
    channel="whatsapp",
    duration_ms=142,
)

Umsetzung: structlog konfigurieren, GlitchTip-Instanz aufsetzen, Error-Tracking in Flask integrieren.


P2 — Später (wichtig, nicht dringend)

sys-6: Secret-Scanning (gitleaks)

Problem: Viele Keys im Umlauf (PAAPI, Telegram-Token, Tavily, IPRoyal, Gamefound). Bandits B105/B106 sind schwächer als dediziertes Secret-Scanning.

Lösung: gitleaks in pre-commit + Gitea Actions:

  • Pre-commit: gitleaks protect --staged
  • CI: gitleaks detect --source .

Umsetzung: .gitleaks.toml konfigurieren, Hook in .pre-commit-config.yaml ergänzen.


sys-7: Regressions-Evals für Agenten-Pipeline

Problem: Du benchmarkst LLMs systematisch — aber wenn du ein Modell oder einen Prompt änderst, gibt es keine automatische Prüfung, ob die Agenten-Pipeline noch die gleiche Qualität liefert.

Lösung: Golden-Set (10-20 typische Fälle) mit Constraints:

  • Enthält alle Pflichtfelder
  • Keine Halluzination der BGG-ID
  • Deutsche Sprache
  • Länge im erwarteten Bereich

Nach jeder Prompt-/Modelländerung gegen das Golden-Set laufen lassen und auf Constraint-Verletzungen prüfen.

Umsetzung: Golden-Set definieren, Evaluations-Skript schreiben, in Cronjob integrieren.


sys-8: ADRs in Obsidian

Problem: Architekturentscheidungen (Edge-Scaling, Modell-Routing, Proxy-Strategie) gehen im Alltag unter — in 6 Monaten weiß niemand mehr, warum etwas so gebaut wurde.

Lösung: Architecture Decision Records (ADR) — ein Markdown pro Entscheidung:

  • Titel: Kurz und prägnant
  • Kontext: Was war die Situation?
  • Entscheidung: Was haben wir entschieden?
  • Konsequenzen: Was folgt daraus? (Positiv + negativ)

In der Obsidian-KB ablegen, für Agenten lesbar.


sys-9: Backup/DR (3-2-1)

Problem: Gitea, DBs, Joomla-Installationen — wenn die Heim-Box stirbt, was ist weg? Ungetestete Backups sind keine Backups.

Lösung: 3-2-1-Schema:

  • 3 Kopien der Daten
  • Auf 2 verschiedenen Medientypen
  • 1 Kopie off-site

Mit automatisierten, getesteten Restores (regelmäßiger Restore-Test).


Priorisierung

Prio Item Hebel Aufwand
P0 Gitea Actions CI-Gate 🔴 Macht Standards erst real durchsetzbar 2-4h
P0 Edge-Queue + Idempotenz 🔴 Verhindert Datenverlust an sichtbarster Stelle 4-8h
P1 uv + Lockfile 🟡 Reproduzierbarkeit auf 3 Architekturen 1-2h
P1 Pydantic an API-Grenzen 🟡 Fängt Laufzeitfehler an der Wurzel 3-6h
P1 Observability 🟡 Du fliegst nicht mehr blind 2-4h
P2 Secret-Scanning 🟢 Safety-Netz für Commits 1h
P2 Regressions-Evals 🟢 Schützt vor stillen Qualitätseinbrüchen 3-5h
P2 ADRs 🟢 Langfristiges Wissensmanagement Laufend, je 15min
P2 Backup/DR 🟢 Existenzsicherung 4-8h initial

Empfohlener Start: sys-1 (Gitea Actions) + sys-2 (Edge-Queue). Danach sys-3 (uv) + sys-4 (Pydantic) im Projekt-Setup.


Erstellt: 21. Juni 2026 · Quelle: Externes Review-Feedback