/// // Events werden zu Ausfahrten, Rennen, Stammtischen — je nach Schaltern. // // `timing` blendet Runs und Zeitnahme ein. Der wöchentliche Stammtisch // braucht das nicht, das Rennen schon; ein zweites Konzept neben Events wäre // dafür zu viel gewesen. // // `participation` legt fest, wie man teilnimmt: // 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 ein // // Bestehende Events bekommen `timing = true` und `geschlossen`: Genau so // wurden sie bisher benutzt. const MANAGER = 'event.created_by.id ?= @request.auth.id' + ' || event.team.owner.id ?= @request.auth.id' + ' || event.team.admins.id ?= @request.auth.id' // Sich selbst eintragen: nur den eigenen Datensatz, nur mit dem Status, den // der Modus vorsieht. Ohne die Statusprüfung könnte man sich im // Bestätigungsmodus gleich selbst bestätigen. // // Geprüft wird auf den Feldern des entstehenden Datensatzes statt über // @request.body: Eine Relation aus dem Request-Body heraus weiterzuverfolgen // (@request.body.rider.user) ist nicht verlässlich. const SELF_SIGNUP = 'event.team.users.id ?= @request.auth.id' + ' && rider.user.id ?= @request.auth.id' + ' && (' + '(event.participation = "offen" && status = "zugesagt")' + ' || (event.participation = "bestaetigung" && status = "angefragt")' + ')' // Die eigene Teilnahme darf man ändern — aber nicht in eine Bestätigung. const SELF_UPDATE = 'rider.user.id ?= @request.auth.id' + ' && @request.body.rider:isset = false' + ' && @request.body.event:isset = false' + ' && @request.body.number:isset = false' + ' && @request.body.status != "zugesagt"' migrate((app) => { const events = app.findCollectionByNameOrId('events') if (!events.fields.getByName('timing')) { events.fields.add(new Field({ id: 'bool_event_timing', name: 'timing', type: 'bool', })) } if (!events.fields.getByName('participation')) { events.fields.add(new Field({ id: 'select_event_participation', name: 'participation', type: 'select', maxSelect: 1, values: ['offen', 'bestaetigung', 'geschlossen'], })) } app.save(events) for (const event of app.findRecordsByFilter('events', 'id != ""', '', 0, 0)) { event.set('timing', true) event.set('participation', 'geschlossen') app.save(event) } const participants = app.findCollectionByNameOrId('event_participants') participants.createRule = `${MANAGER} || (${SELF_SIGNUP})` participants.updateRule = `${MANAGER} || (${SELF_UPDATE})` // Absagen heißt Status ändern, nicht löschen — sonst verschwindet die // Historie einer Anmeldung. participants.deleteRule = MANAGER app.save(participants) }, (app) => { const events = app.findCollectionByNameOrId('events') events.fields.removeByName('timing') events.fields.removeByName('participation') app.save(events) const participants = app.findCollectionByNameOrId('event_participants') participants.createRule = MANAGER participants.updateRule = MANAGER participants.deleteRule = MANAGER app.save(participants) })