Files
linusandClaude Sonnet 5 03f6fdb0d9 Erstumsetzung: OAMC Turnierauswertung (AP 0–7, 9)
* Datenmodell + Alembic-Initialmigration (Plan §4), Seed Saison 2026
* Wertungs-Engine (Plan §3.3), regelbasiert je Kategorie/Saison
  - Abnahmetest gegen die Ergebnisliste 2026-05-31
* Meisterschaftsberechnung mit Streichresultaten + Tie-Break
  (PLATZHALTER-Punktetabelle, O-1 offen)
* Ingest-API (idempotent, dry_run) inkl. Excel-Leser und Fahrer-Matching/Merge
* Zeitmessungs-Endpoint (Batch, idempotent, unzugeordnet/unplausibel) + SSE-Anzeige
  - Mess-Pi-Client bewusst NICHT enthalten (docs/zeitmessung-endpoint.md)
* Frontend: öffentliche Seiten + internes Backend (Jinja2/HTMX, kein Build)
* Auslieferung: Docker (multi-arch) + docker-compose sowie Debian-Paket/APT-Repo
* 57 Tests grün gegen echte PostgreSQL-Testdatenbank

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 18:49:00 +02:00

5.6 KiB
Raw Permalink Blame History

OAMC Turnierauswertung

Webanwendung zur Auswertung von ADAC Motorrad-Turnieren des OAMC Reinheim e.V.: Ergebnisse (Fehlerpunkte + Zeit → Platzierung), Fahrerdatenbank mit Historie, Meisterschaftswertung und ein Endpoint für die Lichtschranken-Zeitmessung.

Fachliche Grundlagen, offene Fragen und Architekturbegründung: plan.md.

Der Mess-Pi-Client (GPIO/Lichtschranke) ist nicht Teil dieses Repos — die Anwendung stellt nur den Endpoint bereit. Contract: docs/zeitmessung-endpoint.md.


Stack

Schicht Wahl
DB PostgreSQL 17 (JSONB, ARRAY, pg_trgm)
Backend Python 3.11+ · FastAPI · SQLAlchemy 2 · Alembic · Pydantic v2
Frontend serverseitig gerendertes Jinja2 + HTMX (kein Node, kein Build)
Live Server-Sent Events (sse-starlette)
Auslieferung Docker-Image und Debian-Paket (.deb / eigenes APT-Repo)

Projektstruktur

src/oamc/
  models/        ORM (§4 im Plan)
  wertung/       Wertungs-Engine — der Kern (§3.3). engine.py + service.py
  meisterschaft/ Punkte, Streichresultate, Tie-Break, Endlaufquali (§3.4)
  matching/      Fahrer-Dublettenerkennung + Merge (§6.4)
  importer/      Bulk-Ingest + Excel-Leser
  geraete/       Zeitmessungs-Endpoint-Logik (§3.6)
  api/v1/        read.py · ingest.py · geraete.py · admin.py
  frontend/      public.py · intern.py + templates/  static/
migrations/      Alembic
tests/           pytest gegen echte PostgreSQL-Testdatenbank
docker/          Dockerfile · nginx.conf · entrypoint.sh
debian/          .deb-Paketierung (venv unter /opt/oamc-turnier)
deploy/          systemd-Unit · nginx-vHost · Backup-Skript (bare metal)
packaging/apt-repo/  reprepro-Konfiguration + Build-Skript

Entwicklung

python3 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env                       # DATABASE_URL anpassen

createdb oamc_dev                          # PostgreSQL-Rolle mit CREATEDB nötig
alembic upgrade head
oamc-turnier seed                          # Stammdaten Saison 2026
oamc-turnier benutzer-anlegen admin --rolle admin
oamc-turnier serve --reload                # http://127.0.0.1:8000  ·  /docs

Tests

Brauchen eine erreichbare PostgreSQL-Testdatenbank (OAMC_DATABASE_URL, Default …/oamc_test). Das Schema wird pro Lauf frisch migriert, jeder Test läuft in einer zurückgerollten Transaktion.

createdb oamc_test
pytest

Der Abnahmetest der Wertungs-Engine (tests/test_wertung_regression_2026_05_31.py) rechnet die im Plan §3.3 zitierten Zeilen der realen Ergebnisliste vom 31.05.2026 nach.

Auslieferung 1 — Docker / „docker repo"

cp .env.example .env      # OAMC_SECRET_KEY setzen!
docker compose up -d      # db + app + nginx  →  http://localhost:8080
docker compose exec app oamc-turnier seed

# Image für eine Registry bauen/pushen:
docker build -t <registry>/oamc-turnier:0.1.0 -f docker/Dockerfile .
docker push  <registry>/oamc-turnier:0.1.0

Multi-Arch für den Raspberry Pi 4:

docker buildx build --platform linux/arm64,linux/amd64 \
  -t <registry>/oamc-turnier:0.1.0 -f docker/Dockerfile --push .

Migrationen laufen automatisch beim Containerstart (docker/entrypoint.sh).

Auslieferung 2 — Debian-Paket / eigenes APT-Repo

sudo apt install build-essential debhelper devscripts python3-venv
./packaging/apt-repo/build-deb.sh          # → ../oamc-turnier_0.1.0_*.deb
sudo apt install ../oamc-turnier_0.1.0_*.deb

Das Paket bringt ein eigenes virtualenv unter /opt/oamc-turnier/venv, eine systemd-Unit und Beispielkonfiguration mit. Danach:

sudoedit /etc/oamc-turnier/oamc-turnier.env    # DATABASE_URL, SECRET_KEY
sudo systemctl enable --now oamc-turnier
sudo -u oamc /opt/oamc-turnier/venv/bin/oamc-turnier seed

Eigenes signiertes APT-Repo aufsetzen: packaging/apt-repo/README.md.

API-Überblick (/docs für die vollständige OpenAPI-Doku)

Bereich Auth Beispiele
Read GET /api/v1/turniere/{id}/ergebnisse, /api/v1/fahrer?q=, /api/v1/meisterschaften/{id}/stand
Ingest X-API-Key POST /api/v1/turniere/{id}/ergebnisse (idempotent, ?dry_run=true), POST …/import/xlsx
Geräte Authorization: Bearer <geräte-token> POST /api/v1/zeitmessungen (Batch, idempotent), SSE GET /api/v1/turniere/aktiv/anzeige
Admin interne Session POST /api/v1/admin/geraete, …/zeitmessungen/{id}/zuordnen, …/meisterschaften/{id}/berechnen, …/fahrer/merge

Bekannte offene Punkte (aus plan.md §10)

Diese sind im Code klar markiert und blockieren einen offiziellen Produktivgang:

  • O-1 — echte Meisterschafts-Punktetabelle fehlt. Es läuft eine PLATZHALTER_PUNKTETABELLE; jeder berechnete Stand trägt einen Warnhinweis.
  • O-2 — Zuordnung S 1S 9 / A 1A 4 → Fahrzeugtyp: Klassen sind angelegt, fahrzeugtyp bleibt NULL.
  • Wertungsregeln §3.3 sind aus PDFs abgeleitet — vor Produktivgang gegen die ADAC-Turnierordnung 2026 zu verifizieren. Die Engine ist regelbasiert konfigurierbar (oamc.wertung.engine.REGELN), nicht fest verdrahtet.
  • O-13/O-14/O-16 — Details der Zeitmessung (was wird gemessen, Zuordnung zum Fahrer, Genauigkeit): siehe docs/zeitmessung-endpoint.md.
  • §11 Datenschutz — Fahrerprofile sind noindex + robots.txt-gesperrt, Geburtsjahr statt -datum, Opt-out-Anonymisierung (fahrer.anzeige_anonymisiert) ist umgesetzt; die Vorstandsentscheidung zur öffentlichen Darstellung von Jugenddaten steht noch aus.