From 7df0e9a5ba279ed60a9921bf0ec1ac0ad96c9496 Mon Sep 17 00:00:00 2001 From: Daniel Michelberger Date: Fri, 14 Aug 2026 15:43:14 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Trail-Migration=20auf=20frischer=20Daten?= =?UTF-8?q?bank=20lauff=C3=A4hig=20machen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auf einer leeren Datenbank brach der Start des Backends ab, damit war die Anwendung insgesamt nicht benutzbar. Zwei Ursachen, beide nur ohne bestehende pb_data sichtbar, weil angewendete Migrationen nicht erneut laufen. Erstens verwies trail_flags.deleteRule auf @collection.trail_markers, obwohl trail_markers erst danach angelegt wird. Die verschaerfte Regel war nachtraeglich in die bereits angewendete Migration eingebaut worden, zusaetzlich zu den korrekten Folgemigrationen 200/300. Hier steht nun wieder die referenzfreie Ursprungsregel; den Zielzustand setzen die Nachtraege. Zweitens enthaelt 1754400000_init_schema.js als Snapshot des Live-Schemas die trail-Collections bereits, wodurch diese Migration sie ein zweites Mal anlegte und am eindeutigen Collection-Namen scheiterte. Ein Guard ueberspringt sie, wenn trails schon existiert. Verifiziert gegen ein leeres Datenverzeichnis: alle Migrationen laufen durch, alle elf Anwendungs-Collections vorhanden, die Nachtraege korrekt im Endzustand (geklammerte deleteRule, coord_distances, avatar.maxSize), Team-Anlage als normaler User erfolgreich. Co-Authored-By: Claude Opus 5 (1M context) --- .../1754500000_created_trails.js | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/backend/pb_migrations/1754500000_created_trails.js b/backend/pb_migrations/1754500000_created_trails.js index 7fe3dc7..4b650f9 100644 --- a/backend/pb_migrations/1754500000_created_trails.js +++ b/backend/pb_migrations/1754500000_created_trails.js @@ -5,8 +5,23 @@ // Reihenfolge ist wichtig: trails.current zeigt auf trail_versions, // trail_versions.trail zeigt zurück auf trails. Deshalb wird trails zuerst // OHNE current angelegt, dann trail_versions, und current danach ergänzt. +// +// 1754400000_init_schema.js wurde nachträglich als vollständiger Snapshot des +// Live-Schemas neu exportiert und enthält die trail-Collections seither +// bereits. Auf einer bestehenden Instanz fällt das nicht auf, weil beide +// Migrationen längst als angewendet vermerkt sind — auf einer frischen +// Datenbank laufen sie nacheinander und kollidieren am eindeutigen +// Collection-Namen. Deshalb der Guard: ist trails schon da, gibt es hier +// nichts zu tun. migrate((app) => { + try { + app.findCollectionByNameOrId('trails') + return + } catch { + // Noch nicht vorhanden — regulär anlegen. + } + const teams = app.findCollectionByNameOrId('teams') const users = app.findCollectionByNameOrId('users') @@ -128,14 +143,19 @@ migrate((app) => { app.save(versions) // --- trails.current nachtragen --------------------------------------- - trails.fields.add(new Field({ + // Frisch laden statt das Objekt von oben weiterzuverwenden: das aus + // `new Collection()` erzeugte Objekt gilt weiterhin als neu, ein zweites + // app.save() darauf liefe erneut als Insert und scheiterte am + // eindeutigen Collection-Namen. + const trailsSaved = app.findCollectionByNameOrId('trails') + trailsSaved.fields.add(new Field({ name: 'current', type: 'relation', maxSelect: 1, collectionId: versions.id, cascadeDelete: false, })) - app.save(trails) + app.save(trailsSaved) // --- trail_flags ------------------------------------------------------ const adminOnly = @@ -149,11 +169,12 @@ migrate((app) => { viewRule: 'team.users.id ?= @request.auth.id', createRule: adminOnly, updateRule: adminOnly, - // Löschen nur, solange kein Marker diesen Typ verwendet — sonst - // bliebe ein Pflichtfeld zurück, das ins Leere zeigt. - // Klammern nötig: && bindet stärker als || — ohne sie gälte die - // Marker-Prüfung nur für den admins-Zweig, nicht für owner. - deleteRule: '(' + adminOnly + ') && @collection.trail_markers.flag ?!= id', + // Hier bewusst ohne die Marker-Prüfung: trail_markers existiert an + // dieser Stelle noch nicht, eine @collection.trail_markers-Referenz + // ließe die Migration auf einer frischen Datenbank scheitern. + // Die verschärfte Regel setzt 1754500200_trail_flags_delete_rule.js + // nach, sobald trail_markers angelegt ist. + deleteRule: adminOnly, fields: [ teamScoped('team'), { name: 'label', type: 'text', required: true, max: 60 },