Migration-Safety: Datenverlust bei App- und Server-Updates verhindern #99
Labels
No labels
block-planning
bug
documentation
duplicate
enhancement
feature
good first issue
help wanted
infrastructure
invalid
planning
priority:high
priority:low
question
refactoring
status:backlog
status:done
status:in-progress
status:todo
tech-decision
test
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: bollwerkadmin/bollwerk#99
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ziel
Sicherstellen, dass App-Updates und Server-Updates niemals Benutzerdaten löschen. Aktuell gibt es auf beiden Seiten kritische Schwachstellen.
Ist-Zustand & Risiken
Android (Room)
🔴 Kritisch:
fallbackToDestructiveMigration()aktivIn
DatabaseModule.ktist der Room-Fallback aktiv:Das bedeutet: Sobald Room eine Schemaversion erkennt, für die kein Migrationspfad definiert ist, löscht es die gesamte Datenbank und erstellt sie neu. Alle Inventar-Daten, Nachrichten und Einstellungen gehen verloren.
🔴 Keine
@AutoMigration-AnnotationenObwohl Room 2.6.1
@AutoMigrationunterstützt, sind keine definierten Migrationspfade vorhanden. Alle bisherigen Schemaübergänge (v2→v3→v4→v5→v6) liefen über den Destruktiv-Fallback.🔴
kcal_per_kg→kcal_per_unit(v5→v6) bereits verlustbehaftetDas Umbenennen dieser Spalte im letzten Release hat bei Usern mit v5-Datenbank alle Items-Daten gelöscht. Dies ist ein bereits eingetretener Schaden.
🟡 CASCADE DELETE ohne Soft-Delete
ItemEntityhatonDelete = CASCADEzu Categories und Locations. Löscht ein User eine Kategorie, verschwinden alle Items darin sofort und unwiederbringlich.Server (PostgreSQL + Exposed)
✅ Grundsätzlich sicher:
SchemaUtils.createMissingTablesAndColumns()Diese Methode ist rein additiv – sie erstellt fehlende Tabellen und Spalten, löscht aber keine bestehenden Daten.
🟡 Kein versioniertes Migrations-Tracking (kein Flyway/Liquibase)
Spalten-Umbenennen oder Typ-Änderungen können nicht mit
SchemaUtilsdurchgeführt werden. Diese müssen als manuelle SQL-Migration inDatabaseFactory.ktgeschrieben werden – ohne Versionierung besteht das Risiko, dass eine Migration doppelt oder gar nicht ausgeführt wird.🟡 Veraltete
user_id-Spalte (stille Migration)Nach der Multi-Tenant-Migration bleibt die alte
user_id-Spalte in mehreren Tabellen mit einemtry/catchversteckt. Das ist technische Schuld und kann bei zukünftigen Migrationen zu Konflikten führen.Lösung
Android
1.
fallbackToDestructiveMigration()entfernen (sofort)Ohne Fallback crasht die App, wenn kein Migrationspfad vorhanden ist – das ist gewollt, damit Datenverlust auffällt statt still passiert.
2.
@AutoMigrationfür alle neuen Schemaänderungen nutzen@AutoMigrationfunktioniert für: neue Spalten (mit Default), neue Tabellen, Spalten löschen (@DeleteColumn), Tabellen löschen (@DeleteTable).Für Spalten-Umbenennungen muss zusätzlich eine
@RenameColumn-Spezifikation angegeben werden:3. Manuelle Migration als letzter Ausweg
Für komplexe Fälle (Daten transformieren, Tabellen zusammenführen):
4. Migrations-Tests
Room bietet
MigrationTestHelperfür automatisierte Tests:Server
1. Flyway für versioniertes Migrations-Tracking einführen
Flyway ergänzt Exposed nahtlos. Migrationsskripte liegen als SQL-Dateien vor und werden nur einmal ausgeführt:
2. Übergangsweise: Manuelle Migration formalisieren
Bis Flyway eingeführt ist, jede manuelle Migration in
DatabaseFactory.ktmit einer Guard-Condition versehen:Abhängigkeiten
Akzeptanzkriterien
fallbackToDestructiveMigration()ist ausDatabaseModule.ktentfernt@AutoMigrationoder manuelleMigration-Klassenuser_id-Spalte auf dem Server ist bereinigtAlle Akzeptanzkriterien erfüllt – Issue wird geschlossen.
✅ fallbackToDestructiveMigration() entfernt
✅ @AutoMigration (v5→v6, v6→v7) aktiv
✅ Migrations-Tests mit MigrationTestHelper vorhanden
✅ Flyway im Server integriert
✅ user_id-Spalte per Flyway V2 bereinigt
✅ Kein Destruktiv-Fallback mehr