stammtisch-hersbruck/backend/pb_migrations/1754500500_riders_user_and_admin_rules.js
Daniel Michelberger 1cd708e0ff feat(schema): Fahrerkonten, Event-Daten und Herkunft des Trail-Status
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
2026-09-02 12:55:47 +02:00

73 lines
2.8 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
// Fahrer bekommen ein optionales Benutzerkonto, und die Fahrerverwaltung wird
// zur Sache der Teamleitung.
//
// 1) riders.user — Verknüpfung eines Fahrers mit einem Login. Optional, weil
// die meisten Fahrer nur in Ergebnislisten auftauchen und sich nie
// anmelden. cascadeDelete ist bewusst aus: Wird ein Konto gelöscht, soll
// der Fahrer samt seiner Zeiten erhalten bleiben.
//
// 2) riders create/update/delete nur noch für Owner und Admins. Bisher durfte
// jedes Teammitglied Fahrer anlegen, ändern und löschen — mit den Zeiten
// daran ist das zu viel Vertrauen in jeden Mitfahrer. Lesen bleibt für das
// ganze Team offen.
//
// 3) users.viewRule von "nur ich selbst" auf "eingeloggt" gelockert. Ohne das
// lässt sich zu einer bekannten User-ID kein Name anzeigen — betrifft die
// Mitgliederliste eines Teams, den Melder eines Trail-Markers und die
// Kontoverknüpfung eines Fahrers. Die listRule bleibt eng: Wer keine ID
// kennt, kann auch keine Konten durchblättern. E-Mail-Adressen bleiben
// über emailVisibility verborgen.
//
// 4) users.createRule von "niemand" auf "eingeloggt". Damit kann ein Admin
// einem Fahrer direkt ein Login anlegen. Bewusst nicht offen (""), sonst
// wäre es eine öffentliche Registrierung.
const RIDERS_ADMIN_RULE =
'team.owner.id ?= @request.auth.id || team.admins.id ?= @request.auth.id'
const RIDERS_MEMBER_RULE = 'team.users.id ?= @request.auth.id'
const LOGGED_IN = '@request.auth.id != ""'
migrate((app) => {
const users = app.findCollectionByNameOrId('users')
const riders = app.findCollectionByNameOrId('riders')
// Der Snapshot in 1754400000_init_schema.js führt das Feld inzwischen
// mit. Auf einer frischen Datenbank ist es also schon da, auf einer
// bestehenden noch nicht — dieselbe Lage wie bei den trail-Collections.
if (!riders.fields.getByName('user')) {
riders.fields.add(new Field({
id: 'relation_rider_user',
name: 'user',
type: 'relation',
collectionId: users.id,
cascadeDelete: false,
maxSelect: 1,
minSelect: 0,
required: false,
}))
}
riders.createRule = RIDERS_ADMIN_RULE
riders.updateRule = RIDERS_ADMIN_RULE
riders.deleteRule = RIDERS_ADMIN_RULE
app.save(riders)
users.viewRule = LOGGED_IN
users.createRule = LOGGED_IN
app.save(users)
}, (app) => {
const users = app.findCollectionByNameOrId('users')
const riders = app.findCollectionByNameOrId('riders')
riders.fields.removeByName('user')
riders.createRule = RIDERS_MEMBER_RULE
riders.updateRule = RIDERS_MEMBER_RULE
riders.deleteRule = RIDERS_MEMBER_RULE
app.save(riders)
users.viewRule = 'id = @request.auth.id'
users.createRule = null
app.save(users)
})