Drei Migrationen, dazu der Snapshot in 1754400000_init_schema.js, aus dem
die TypeScript-Typen erzeugt werden - beide muessen zusammenpassen, sonst
laufen Schema und Typen auseinander.
riders.user verknuepft einen Fahrer mit einem Login, ohne cascadeDelete:
Ein geloeschtes Konto darf keine Zeiten mitreissen. Anlegen, Aendern und
Loeschen von Fahrern wird zur Sache der Teamleitung; bisher durfte das
jedes Teammitglied.
users.viewRule von "nur ich selbst" auf "eingeloggt" - ohne das laesst sich
zu einer bekannten ID kein Name anzeigen, was Mitgliederliste,
Fahrerkonten und den Melder eines Trail-Markers betrifft. Die listRule
bleibt eng, E-Mails bleiben ueber emailVisibility verborgen. users.createRule
erlaubt eingeloggten Nutzern das Anlegen von Konten, nicht der ganzen Welt.
events verliert status und bekommt starts/ends. Der Status war Handarbeit:
Wer vergass, ein Event abzuschliessen, hatte eine falsche Uebersicht. Ein
Datum weiss von selbst, was ansteht, laeuft und vorbei ist. ACHTUNG: Die
Migration entfernt das Feld samt seiner Werte.
trails bekommt status_changed und status_by. Einer Sperrung soll man
ansehen, ob sie von heute Morgen oder vom letzten Herbst ist.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014dh9W1i7aLSdPYJzQPid5o
Der Pin stand auf 0.39.6, aktuelles Release ist 0.39.11. Reine Patch-Updates
innerhalb 0.39, keine Schema- oder API-Aenderungen, aber sicherheitsrelevant:
0.39.7 ersetzt ozzo-validation durch einen eigenen Fork, nachdem die
Originalbibliothek den Besitzer gewechselt hat; 0.39.8 und 0.39.11 ziehen
Sicherheitsfixes der golang.org/x-Abhaengigkeiten nach.
Version an beiden aktiven Stellen gesetzt (Dockerfile-ARG und der Default in
docker-compose.yaml). Die Planungsdokumente unter docs/ bleiben unangetastet,
sie halten den Stand ihrer Entstehung fest.
.env.example um den Deployment-Fall ergaenzt: Beim Deployment gibt es keine
.env-Datei, dieselben Variablen werden in Coolify als Environment Variables
gesetzt. Ausserdem der Hinweis, dass SUPERUSER_* nur greift, solange noch kein
Superuser existiert — nachtraegliche Aenderungen wirken nicht mehr.
Verifiziert: Image gebaut, Binary meldet 0.39.11, alle Migrationen laufen
gegen eine frische Datenbank durch, alle elf Collections vorhanden,
Team-Anlage als normaler User erfolgreich.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Auf einer leeren Datenbank brach der Start des Backends ab, damit war die
Anwendung insgesamt nicht benutzbar. Zwei Ursachen, beide nur ohne
bestehende pb_data sichtbar, weil angewendete Migrationen nicht erneut
laufen.
Erstens verwies trail_flags.deleteRule auf @collection.trail_markers,
obwohl trail_markers erst danach angelegt wird. Die verschaerfte Regel war
nachtraeglich in die bereits angewendete Migration eingebaut worden,
zusaetzlich zu den korrekten Folgemigrationen 200/300. Hier steht nun
wieder die referenzfreie Ursprungsregel; den Zielzustand setzen die
Nachtraege.
Zweitens enthaelt 1754400000_init_schema.js als Snapshot des Live-Schemas
die trail-Collections bereits, wodurch diese Migration sie ein zweites Mal
anlegte und am eindeutigen Collection-Namen scheiterte. Ein Guard
ueberspringt sie, wenn trails schon existiert.
Verifiziert gegen ein leeres Datenverzeichnis: alle Migrationen laufen
durch, alle elf Anwendungs-Collections vorhanden, die Nachtraege korrekt
im Endzustand (geklammerte deleteRule, coord_distances, avatar.maxSize),
Team-Anlage als normaler User erfolgreich.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
elevation enthält einen Eintrag pro Originalpunkt, geojson.coordinates
nur die per Douglas-Peucker vereinfachten Punkte. Ein gemeinsamer Index
zeigte deshalb ab rund 3 % des Profils auf das Streckenende. Die neue
Distanz-Kopplung nutzt coord_distances (kumulative Distanz je
vereinfachter Koordinate), um beim Überfahren des Höhenprofils die
nächstgelegene Stelle auf der Karte zu finden.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBMBfip6BAG8VV9raSf6vu
&& bindet stärker als || — ohne Klammern galt die
Marker-Referenzprüfung nur für den admins-Zweig. Ein Team-Owner konnte
dadurch einen noch von Markern referenzierten Flag-Typ löschen und
verwaiste Marker hinterlassen.
Klammerung in 1754500000_created_trails.js korrigiert, damit ein
Neuaufbau der Datenbank die richtige Regel von Anfang an bekommt.
1754500200_trail_flags_delete_rule.js (bereits mit der fehlerhaften
Regel angewendet) inhaltlich ebenfalls korrigiert, und eine neue
Migration 1754500300_trail_flags_delete_rule_precedence.js trägt die
Korrektur für bestehende Instanzen nach. Snapshot aktualisiert.
trail_markers.flag ist required, hatte aber cascadeDelete: false — beim
Löschen eines Flag-Typs blieben Marker mit toter Referenz zurück. Die
deleteRule von trail_flags verbietet das Löschen jetzt, solange noch
Marker den Typ referenzieren.
1754500000_created_trails.js wurde direkt angepasst, damit ein Neuaufbau
der DB die Regel von Anfang an enthält. Da die Migration lokal bereits
angewendet war, trägt 1754500200_trail_flags_delete_rule.js dieselbe
Änderung für bestehende Instanzen nach. Snapshot in
1754400000_init_schema.js entsprechend aktualisiert.
Der in 22cd427 ergänzte Bind-Mount ./pb_migrations:/pb/pb_migrations
überdeckt das Verzeichnis aus dem Image. Auf einem Deployment-Host, neben
dessen compose-Datei kein ausgechecktes Repo liegt, legt Docker dort ein
leeres Verzeichnis an: PocketBase findet keine Migration und startet mit
einer Datenbank ohne Collections. Genau das ist auf der neu deployten
Instanz passiert — users war da (legt PocketBase selbst an), events, teams,
riders, runs und times fehlten.
Reproduziert und beide Richtungen verifiziert: mit leerem Mount 404 auf
allen fünf Collections, ohne Mount kommen alle sechs aus dem Image.
Die Migrationen kommen damit wieder ausschließlich über COPY ins Image. Der
Preis ist der Weg zurück: Im Admin-UI erzeugte Migrationen liegen nur im
Container und müssen mit "docker compose cp" ins Repo geholt werden. Das
steht jetzt in backend/README.md und CLAUDE.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die SvelteKit-App liegt unter frontend/, das Backend unter backend/ als
eigenständige PocketBase-Instanz mit Dockerfile, docker-compose und
versioniertem Schema.
- PocketBase-URL über PUBLIC_PB_URL konfigurierbar, Default bleibt die
produktive Instanz https://api.stammtisch-hersbruck.de
- Schema als Snapshot-Migration der sechs fachlichen Collections
(users, teams, events, runs, riders, times), abgezogen von der
produktiven Instanz. Verifiziert: ein Erststart gegen leere pb_data
legt alle sechs an, Felder und API-Rules stimmen überein.
- pb_data und pb_migrations als Bind-Mounts, damit Daten persistieren und
im Admin-UI erzeugte Migrationen im Repo landen
- Veraltete Dokumentation entfernt: pocketbase_schema.json nannte
Collections (stages, results, organizers), die es nicht gibt
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>