From 3120bbfdbf4849de507f24e7fe6da7994a269774 Mon Sep 17 00:00:00 2001 From: Daniel Michelberger Date: Mon, 7 Sep 2026 22:11:44 +0200 Subject: [PATCH] fix: Fahrer fuer Teammitglieder, die keinen mehr haben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bis zuletzt loeschte die Anwendung einen Fahrer, ohne sein Konto aus teams.users zu nehmen. Zurueck blieb ein Konto ohne Fahrer — im Kader eine Zeile, aus der kein Weg zurueckfuehrte: Ein bestehendes Konto nachtraeglich an einen Fahrer zu haengen gibt es bewusst nicht, weil dieselbe Person sonst zweimal in der Liste stehen koennte. riders.remove nimmt die Mitgliedschaft inzwischen mit; diese Migration raeumt auf, was vorher liegengeblieben ist, und stellt die Regel her, auf die sich die Oberflaeche verlassen darf: Wer im Team ist, steht im Kader. Kein Rueckweg: Die hier angelegten Fahrer sind hinterher nicht mehr von denen zu unterscheiden, die die Teamleitung selbst angelegt hat. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01P32KoesVtABd6xWsqMKzhr --- .../1754501900_riders_for_orphan_members.js | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 backend/pb_migrations/1754501900_riders_for_orphan_members.js diff --git a/backend/pb_migrations/1754501900_riders_for_orphan_members.js b/backend/pb_migrations/1754501900_riders_for_orphan_members.js new file mode 100644 index 0000000..10ae1b5 --- /dev/null +++ b/backend/pb_migrations/1754501900_riders_for_orphan_members.js @@ -0,0 +1,81 @@ +/// + +// Jedes Teammitglied bekommt einen Fahrer. +// +// Bis 1754501800 löschte die Anwendung einen Fahrer, ohne sein Konto aus +// `teams.users` zu nehmen. Zurück blieb ein Konto ohne Fahrer — im Kader eine +// Zeile ohne Namen, aus der kein Weg zurückführte: Ein bestehendes Konto +// nachträglich an einen Fahrer zu hängen gibt es bewusst nicht, weil dieselbe +// Person sonst zweimal in der Liste stehen könnte. Der Eintrag war damit +// unreparierbar. +// +// Das Leck ist zu (riders.remove nimmt die Mitgliedschaft mit). Diese +// Migration räumt auf, was es hinterlassen hat, und stellt damit die Regel +// her, auf die sich die Oberfläche künftig verlassen darf: +// +// Wer im Team ist, steht im Kader. +// +// Der Name kommt vom Konto: erst der Kontoname, sonst der Teil der +// E-Mail-Adresse vor dem @. Beides kann später von der Teamleitung geändert +// werden — der Fahrername ist ab dann die einzige Wahrheit, der Kontoname +// taucht in der Oberfläche nirgends mehr auf. + +migrate((app) => { + const teams = app.findRecordsByFilter('teams', 'id != ""', '', 0, 0) + let created = 0 + + for (const team of teams) { + // getStringSlice statt get: `get` gäbe bei einer Mehrfach-Relation ein + // Go-Slice zurück, auf dem sich weder includes noch map verlässlich + // verhalten. + const memberIds = team.getStringSlice('users') || [] + if (memberIds.length === 0) continue + + const taken = new Set() + for (const rider of app.findRecordsByFilter( + 'riders', + 'team = {:team} && user != ""', + '', + 0, + 0, + { team: team.id }, + )) { + taken.add(rider.getString('user')) + } + + for (const userId of memberIds) { + if (taken.has(userId)) continue + + let user + try { + user = app.findRecordById('users', userId) + } catch (err) { + // Konto gelöscht, die Relation zeigt ins Leere. Ein Fahrer für + // ein Konto, das es nicht gibt, wäre kein Gewinn. + continue + } + + const email = user.getString('email') + const name = + user.getString('name').trim() || + (email.indexOf('@') > 0 ? email.slice(0, email.indexOf('@')) : '') || + 'Ohne Namen' + + const rider = new Record(app.findCollectionByNameOrId('riders')) + rider.set('team', team.id) + rider.set('user', userId) + rider.set('name', name) + app.save(rider) + + taken.add(userId) + created++ + } + } + + console.log(`riders_for_orphan_members: ${created} Fahrer angelegt`) +}, (app) => { + // Kein Rückweg. Die hier angelegten Fahrer sind hinterher nicht mehr von + // denen zu unterscheiden, die die Teamleitung danach selbst angelegt hat — + // sie zu löschen träfe mit einiger Wahrscheinlichkeit die falschen, samt + // ihrer Teilnahmen und Zeiten. Ein Fahrer zu viel ist der kleinere Schaden. +})