fix: Trail-Migration auf frischer Datenbank lauffähig machen
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) <noreply@anthropic.com>
This commit is contained in:
parent
1257456308
commit
7df0e9a5ba
1 changed files with 28 additions and 7 deletions
|
|
@ -5,8 +5,23 @@
|
||||||
// Reihenfolge ist wichtig: trails.current zeigt auf trail_versions,
|
// Reihenfolge ist wichtig: trails.current zeigt auf trail_versions,
|
||||||
// trail_versions.trail zeigt zurück auf trails. Deshalb wird trails zuerst
|
// trail_versions.trail zeigt zurück auf trails. Deshalb wird trails zuerst
|
||||||
// OHNE current angelegt, dann trail_versions, und current danach ergänzt.
|
// 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) => {
|
migrate((app) => {
|
||||||
|
try {
|
||||||
|
app.findCollectionByNameOrId('trails')
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
// Noch nicht vorhanden — regulär anlegen.
|
||||||
|
}
|
||||||
|
|
||||||
const teams = app.findCollectionByNameOrId('teams')
|
const teams = app.findCollectionByNameOrId('teams')
|
||||||
const users = app.findCollectionByNameOrId('users')
|
const users = app.findCollectionByNameOrId('users')
|
||||||
|
|
||||||
|
|
@ -128,14 +143,19 @@ migrate((app) => {
|
||||||
app.save(versions)
|
app.save(versions)
|
||||||
|
|
||||||
// --- trails.current nachtragen ---------------------------------------
|
// --- 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',
|
name: 'current',
|
||||||
type: 'relation',
|
type: 'relation',
|
||||||
maxSelect: 1,
|
maxSelect: 1,
|
||||||
collectionId: versions.id,
|
collectionId: versions.id,
|
||||||
cascadeDelete: false,
|
cascadeDelete: false,
|
||||||
}))
|
}))
|
||||||
app.save(trails)
|
app.save(trailsSaved)
|
||||||
|
|
||||||
// --- trail_flags ------------------------------------------------------
|
// --- trail_flags ------------------------------------------------------
|
||||||
const adminOnly =
|
const adminOnly =
|
||||||
|
|
@ -149,11 +169,12 @@ migrate((app) => {
|
||||||
viewRule: 'team.users.id ?= @request.auth.id',
|
viewRule: 'team.users.id ?= @request.auth.id',
|
||||||
createRule: adminOnly,
|
createRule: adminOnly,
|
||||||
updateRule: adminOnly,
|
updateRule: adminOnly,
|
||||||
// Löschen nur, solange kein Marker diesen Typ verwendet — sonst
|
// Hier bewusst ohne die Marker-Prüfung: trail_markers existiert an
|
||||||
// bliebe ein Pflichtfeld zurück, das ins Leere zeigt.
|
// dieser Stelle noch nicht, eine @collection.trail_markers-Referenz
|
||||||
// Klammern nötig: && bindet stärker als || — ohne sie gälte die
|
// ließe die Migration auf einer frischen Datenbank scheitern.
|
||||||
// Marker-Prüfung nur für den admins-Zweig, nicht für owner.
|
// Die verschärfte Regel setzt 1754500200_trail_flags_delete_rule.js
|
||||||
deleteRule: '(' + adminOnly + ') && @collection.trail_markers.flag ?!= id',
|
// nach, sobald trail_markers angelegt ist.
|
||||||
|
deleteRule: adminOnly,
|
||||||
fields: [
|
fields: [
|
||||||
teamScoped('team'),
|
teamScoped('team'),
|
||||||
{ name: 'label', type: 'text', required: true, max: 60 },
|
{ name: 'label', type: 'text', required: true, max: 60 },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue