From 55f25fae0ce4c571b42695dad2eab80f6a8df2be Mon Sep 17 00:00:00 2001 From: Daniel Michelberger Date: Thu, 6 Aug 2026 17:08:40 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20verwaiste=20trail=5Fmarkers=20beim=20L?= =?UTF-8?q?=C3=B6schen=20von=20trail=5Fflags=20verhindern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit trail_markers.flag ist required, hatte aber cascadeDelete: false — beim Löschen eines Flag-Typs blieben Marker mit toter Referenz zurück. Die deleteRule von trail_flags verbietet das Löschen jetzt, solange noch Marker den Typ referenzieren. 1754500000_created_trails.js wurde direkt angepasst, damit ein Neuaufbau der DB die Regel von Anfang an enthält. Da die Migration lokal bereits angewendet war, trägt 1754500200_trail_flags_delete_rule.js dieselbe Änderung für bestehende Instanzen nach. Snapshot in 1754400000_init_schema.js entsprechend aktualisiert. --- .../pb_migrations/1754400000_init_schema.js | 8 +++---- .../1754500000_created_trails.js | 4 +++- .../1754500200_trail_flags_delete_rule.js | 23 +++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 backend/pb_migrations/1754500200_trail_flags_delete_rule.js diff --git a/backend/pb_migrations/1754400000_init_schema.js b/backend/pb_migrations/1754400000_init_schema.js index b353646..9e2b5ab 100644 --- a/backend/pb_migrations/1754400000_init_schema.js +++ b/backend/pb_migrations/1754400000_init_schema.js @@ -130,7 +130,7 @@ migrate((app) => { "hidden": false, "id": "file376926767", "maxSelect": 1, - "maxSize": 0, + "maxSize": 5242880, "mimeTypes": [ "image/jpeg", "image/png", @@ -173,7 +173,7 @@ migrate((app) => { "CREATE UNIQUE INDEX `__pb_users_auth__tokenKey_idx` ON `users` (`tokenKey`)" ], "created": "2023-10-28 21:35:49.020Z", - "updated": "2026-08-06 12:06:09.028Z", + "updated": "2026-08-06 15:05:38.398Z", "system": false, "authRule": "", "manageRule": null, @@ -1273,7 +1273,7 @@ migrate((app) => { "viewRule": "team.users.id ?= @request.auth.id", "createRule": "team.owner.id ?= @request.auth.id || team.admins.id ?= @request.auth.id", "updateRule": "team.owner.id ?= @request.auth.id || team.admins.id ?= @request.auth.id", - "deleteRule": "team.owner.id ?= @request.auth.id || team.admins.id ?= @request.auth.id", + "deleteRule": "team.owner.id ?= @request.auth.id || team.admins.id ?= @request.auth.id && @collection.trail_markers.flag ?!= id", "name": "trail_flags", "type": "base", "fields": [ @@ -1390,7 +1390,7 @@ migrate((app) => { ], "indexes": [], "created": "2026-08-06 14:55:19.508Z", - "updated": "2026-08-06 14:55:19.508Z", + "updated": "2026-08-06 15:05:38.402Z", "system": false }, { diff --git a/backend/pb_migrations/1754500000_created_trails.js b/backend/pb_migrations/1754500000_created_trails.js index 9fca1c3..085f800 100644 --- a/backend/pb_migrations/1754500000_created_trails.js +++ b/backend/pb_migrations/1754500000_created_trails.js @@ -149,7 +149,9 @@ migrate((app) => { viewRule: 'team.users.id ?= @request.auth.id', createRule: adminOnly, updateRule: adminOnly, - deleteRule: adminOnly, + // Löschen nur, solange kein Marker diesen Typ verwendet — sonst + // bliebe ein Pflichtfeld zurück, das ins Leere zeigt. + deleteRule: adminOnly + ' && @collection.trail_markers.flag ?!= id', fields: [ teamScoped('team'), { name: 'label', type: 'text', required: true, max: 60 }, diff --git a/backend/pb_migrations/1754500200_trail_flags_delete_rule.js b/backend/pb_migrations/1754500200_trail_flags_delete_rule.js new file mode 100644 index 0000000..bee4927 --- /dev/null +++ b/backend/pb_migrations/1754500200_trail_flags_delete_rule.js @@ -0,0 +1,23 @@ +/// + +// trail_flags.deleteRule ergänzt: Löschen nur, solange kein Marker diesen +// Typ verwendet — sonst bliebe ein Pflichtfeld (trail_markers.flag) zurück, +// das ins Leere zeigt. Separate Migration, weil 1754500000_created_trails.js +// bereits angewendet wurde und PocketBase Migrationsdateien nur einmal +// anhand des Dateinamens ausführt, unabhängig vom Inhalt. + +migrate((app) => { + const flags = app.findCollectionByNameOrId('trail_flags') + const adminOnly = + 'team.owner.id ?= @request.auth.id' + + ' || team.admins.id ?= @request.auth.id' + flags.deleteRule = adminOnly + ' && @collection.trail_markers.flag ?!= id' + app.save(flags) +}, (app) => { + const flags = app.findCollectionByNameOrId('trail_flags') + const adminOnly = + 'team.owner.id ?= @request.auth.id' + + ' || team.admins.id ?= @request.auth.id' + flags.deleteRule = adminOnly + app.save(flags) +})