# 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`](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`](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 ```sh 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. ```sh 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" ```sh 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 /oamc-turnier:0.1.0 -f docker/Dockerfile . docker push /oamc-turnier:0.1.0 ``` Multi-Arch für den Raspberry Pi 4: ```sh docker buildx build --platform linux/arm64,linux/amd64 \ -t /oamc-turnier:0.1.0 -f docker/Dockerfile --push . ``` Migrationen laufen automatisch beim Containerstart (`docker/entrypoint.sh`). ## Auslieferung 2 — Debian-Paket / eigenes APT-Repo ```sh 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: ```sh 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`](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 ` | `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 1`–`S 9` / `A 1`–`A 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, Geburts*jahr* statt -datum, Opt-out-Anonymisierung (`fahrer.anzeige_anonymisiert`) ist umgesetzt; die Vorstandsentscheidung zur öffentlichen Darstellung von Jugenddaten steht noch aus.