stammtisch-hersbruck/TODO.md
Daniel Michelberger 561d7cbbc7 docs: Symptom der noch nicht gelaufenen Migrationen in TODO.md benennen
"Only superusers can perform this action" beim Anlegen eines Mitglieds ist
kein Fehler im Frontend, sondern die unveraenderte users.createRule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014dh9W1i7aLSdPYJzQPid5o
2026-09-02 13:13:39 +02:00

5 KiB

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

Rollenmodell: Superadmin appweit

Geplant sind drei Rollen: Superadmin (appweit, über alle Teams), Team-Admin (Owner/Admins eines Teams, gibt es schon) und Mitglied.

Umsetzung, sobald die zwei Fragen unten geklärt sind:

  • users.superadmin als Bool-Feld.
  • Die updateRule der users-Collection muss dabei @request.body.superadmin:isset = false ergänzen — sonst kann sich jeder Nutzer selbst befördern, denn er darf seinen eigenen Datensatz ändern.

Offen:

  1. Vorhandene Team-Flags. Flag-Typen sollen appweit gelten (siehe unten). Heute hat jedes Team seinen eigenen Satz. Zusammenführen und Duplikate von Hand aufräumen, oder alle behalten und ab sofort global sichtbar machen?
  2. Erster Superadmin. Den kann nur jemand direkt im PocketBase-Admin setzen. Reicht ein Hinweis im Migrationskommentar, oder soll es eine Superadmin-Verwaltung in den Einstellungen geben?

Flag-Typen appweit statt pro Team

Hängt am Rollenmodell. Heute ist trail_flags team-gebunden: Das Feld team existiert, der Store filtert danach, lesen darf das Team, schreiben Owner und Admins.

Ziel: team entfällt, lesen für alle Eingeloggten, schreiben nur Superadmin. Die Typen werden damit App-weite Vorschläge, aus denen jedes Team auswählt.

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.<feld>: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.

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

Vier 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

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.

cd frontend && npm run generate-pocketbase-types

Die Datei sollte danach unverändert bleiben. Tut sie es nicht, gilt das Ergebnis des Generators.

Kleinigkeiten

  • Der Melder eines Trail-Markers („wer") zeigt bis zum Deploy „Unbekannt". Die gelockerte users.viewRule kommt mit 1754500500.
  • NAMING.md und frontend/static/pedaler.svg liegen bewusst nur lokal.