teams.logo nimmt eine Datei auf; hochgeladen wird sie in den Team-Einstellungen. Ohne eigenes Logo bleibt das Wappen aus static/ als Rueckfalloption - fuer den Stammtisch Hersbruck aendert sich damit nichts, fuer jedes weitere Team waere es fremdes Vereinswappen gewesen. Dasselbe Logo liegt gedreht und sehr blass in der rechten unteren Ecke der Seite. Es haengt fest im Bildschirm, faengt keine Klicks ab und ist fuer Screenreader nicht vorhanden; im Dunkelmodus etwas kraeftiger, sonst verschwaende es im dunklen Grund. In TODO.md ausserdem der Plan fuer Ausfahrten: Sie werden kein zweites Konzept neben Events, sondern Schalter daran - timing, participation (offen/bestaetigung/geschlossen) und Serien, die echte Einzeltermine erzeugen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014dh9W1i7aLSdPYJzQPid5o
141 lines
6.2 KiB
Markdown
141 lines
6.2 KiB
Markdown
# 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.<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.
|
|
|
|
### 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.
|