# Offene Punkte Stand: 2026-09-02. Was hier steht, ist bewusst nicht erledigt — entweder weil es eine Entscheidung braucht oder weil es außerhalb des Repos passiert. ## Entscheidungen ### Trail-Status: dürfen Mitglieder melden? Anzeige und Herkunft (`status_changed`, `status_by`) sind fertig. Ändern darf den Status weiterhin nur, wer Pate oder Team-Admin ist — `trails.updateRule` lässt nichts anderes zu. Sollen alle Teammitglieder melden dürfen, braucht es eine Regel, die genau ein Feld freigibt: `team.users.id ?= @request.auth.id` kombiniert mit `@request.body.:isset = false` für **jedes** andere Feld. Das funktioniert, wird aber lang und bricht still, sobald ein Feld dazukommt. Deshalb erst nach ausdrücklicher Entscheidung. ### Fahrer: Kader oder Event-Teilnehmer? `riders.event` bindet einen Fahrer an genau ein Event. Ein in den Einstellungen angelegter Fahrer ohne Event steht deshalb nur im Verzeichnis und taucht in keiner Zeitnahme auf; der Dialog hat dafür ein optionales Event-Feld. Ein echter Team-Kader, aus dem man Fahrer in Events übernimmt, wäre eine n:m-Beziehung — also eine Schema-Änderung, keine Oberflächenfrage. ### Mitglied per E-Mail einladen Die alte Einladung über eine E-Mail-Suche ist entfallen und durch „Mitglied anlegen" ersetzt. Sie konnte nie funktionieren: `users.listRule` gibt nur den eigenen Datensatz frei, die Suche lief immer ins Leere. Ein **bestehendes** fremdes Konto in ein Team zu holen braucht eine offenere `listRule` (z. B. `@request.auth.id != ""`). Das erlaubt allerdings, alle Konten der Instanz aufzulisten — deshalb bewusst nicht ohne Rücksprache. ### Ausfahrten: geplant, noch nicht gebaut Ausfahrten werden **nicht** zu einem zweiten Konzept neben Events, sondern Events bekommen Schalter. Ein Bikepark-Ausflug mit gestoppten Läufen ist beides zugleich; eine Trennung wäre willkürlich und würde Datum, Rechte und Oberfläche doppelt führen. Geplant, in dieser Reihenfolge: 1. **`events.timing`** (bool). Runs und Zeitnahme erscheinen nur, wenn gesetzt. Der wöchentliche Stammtisch braucht sie nicht. 2. **Teilnahme** als eigene Collection `event_participants` (Event, Person, Status, Zeitpunkt) — nicht als Liste am Event, sonst hängen Status und Zeitpunkt nirgends, und Gäste ohne Konto passen nicht hinein. `events.participation` steuert, wie man hineinkommt: | Wert | Bedeutung | |---|---| | `offen` | Jedes Teammitglied trägt sich selbst ein | | `bestaetigung` | Anmeldung möglich, Ersteller oder Team-Admin bestätigt | | `geschlossen` | Nur Ersteller oder Team-Admin trägt Teilnehmer ein | 3. **Serien** (`event_series`): Regel, Zeitraum und Vorlage; daraus entstehen echte Einzeltermine. Bewusst nicht ein Datensatz mit Wiederholungsregel, aus dem Termine nur gerechnet werden — sobald „wer kommt am 12.?" oder „diese Woche fällt aus" beantwortet werden soll, braucht jeder Termin einen eigenen Datensatz. Offen: Sind Teilnehmer **Nutzerkonten** oder **Fahrer**? Für den Stammtisch wären es Konten, für eine gemeinsame Ausfahrt eher Fahrer (die es auch ohne Konto gibt). Beides zugleich geht, macht die Collection aber breiter. ## Vor dem nächsten Deploy ### `PUBLIC_CARTO_API_KEY` in Coolify setzen Die Kartenkacheln kommen von CARTO. Der Schlüssel muss den Browser erreichen, deshalb das `PUBLIC_`-Präfix — ohne das reicht SvelteKit ihn nicht weiter. Gelesen wird er über `$env/dynamic/public`, das heißt: Die Variable muss in der **Laufzeitumgebung** des `node build`-Prozesses stehen, nicht nur zur Buildzeit. In Coolify als normale Umgebungsvariable eintragen genügt. Fehlt sie, laufen die Kacheln ohne Schlüssel weiter — die Karte bleibt also sichtbar. ### Migrationen greifen beim nächsten Start Sechs neue Migrationen liegen in `backend/pb_migrations/`: - `1754500500_riders_user_and_admin_rules.js` - `1754500600_events_dates_instead_of_status.js` - `1754500700_trail_status_meta.js` - `1754500800_trail_markers_custom.js` - `1754500900_users_superadmin.js` - `1754501000_teams_logo.js` Solange sie nicht gelaufen sind, scheitert alles, was auf den neuen Regeln aufbaut. Am deutlichsten beim Anlegen eines Mitglieds oder eines Fahrer-Logins: **„Only superusers can perform this action"** — genau das sagt die noch unveraenderte `users.createRule` (null = nur Superuser). **Achtung:** Die mittlere entfernt `events.status` **samt seiner Werte**. Das ist so gewollt (Events werden datiert statt bewertet), aber es ist ein Datenverlust und nicht zurückzunehmen. Ebenfalls neu: Fahrer anlegen, ändern und löschen darf ab dann nur noch die Teamleitung. Mitglieder ohne Admin-Rolle verlieren diese Möglichkeit auch auf der Event-Seite. ### Typen einmal neu erzeugen `frontend/src/lib/types.d.ts` wurde bei den letzten Schema-Änderungen von Hand ergänzt (`riders.user`, `trails.status_by`/`status_changed`, `events.starts`/`ends` statt `status`). Grund: `pocketbase-typegen` braucht native sqlite3-Bindings, die in der Arbeitsumgebung nicht gebaut werden durften. ```bash cd frontend && npm run generate-pocketbase-types ``` Die Datei sollte danach unverändert bleiben. Tut sie es nicht, gilt das Ergebnis des Generators. ### Logo des Stammtischs zuordnen `teams.logo` gibt es ab `1754501000`. Solange nichts hinterlegt ist, zeigt die App weiterhin das Wappen aus `static/` — für den Stammtisch Hersbruck sieht es also unverändert aus. Wer es als Datei am Team haben will, lädt es nach dem Deploy unter Einstellungen → Team → Logo hoch. ## Kleinigkeiten - Der Melder eines Trail-Markers („wer") zeigt bis zum Deploy „Unbekannt". Die gelockerte `users.viewRule` kommt mit `1754500500`. - Die Rolle **Superadmin** existiert seit `1754500900` und ist für stammtisch@dne.name gesetzt, gibt in der App aber noch keine besonderen Rechte. Sie ist bewusst nur in PocketBase vergebbar: Die `updateRule` der users-Collection schließt `superadmin` vom Selbstsetzen aus. Sobald klar ist, was sie dürfen soll, kommen die Regeln dazu. - Flag-Typen bleiben **teamspezifisch**. Ein neues Team bekommt beim Anlegen den hartkodierten Standardsatz aus `trailFlags.svelte.ts`, den es danach frei ändern kann. Eine appweite Verwaltung gibt es damit bewusst nicht. - `NAMING.md` und `frontend/static/pedaler.svg` liegen bewusst nur lokal.