- Migration 20260924120000_dashboard_image_drop_data: Schutzpruefung (bricht ab, solange eine Zeile ohne storagePath existiert; row_security aus, damit ein Eigentuemer ohne BYPASSRLS nicht still 0 Zeilen sieht), dann NOT NULL, DROP COLUMN data, DROP POLICY system_read_policy - Dienst: Bootstrap-Umzug samt forSystem() und Selbstheilung aus data entfernt; Upload vergibt die UUID selbst, Zeile gleich mit Pfad - FORSYSTEM_ALLOWED_CALL_SITES, Tests, Zugriffsklassifikation (per Gate-Schleife gemessen: 61/213/6) nachgezogen - Betriebshandbuch Kap. 4: Hinweis und Wiederherstellungsweg bei Abbruch - Todo 2026-09-22 nach completed/ Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
4.8 KiB
created, title, area, severity, trigger, relates_to
| created | title | area | severity | trigger | relates_to |
|---|---|---|---|---|---|
| 2026-09-22 | DashboardImage — Spalte "data" entfernen und "storagePath" auf NOT NULL setzen (Stufe 2 der Umstellung aus quick-260922-hk4) | apps/api/prisma | cleanup | erst wenn alpha UND live je einmal mit einer Version >= der Freigabe nach 1.3.0 gelaufen sind — dann hat der Bootstrap-Umzug auf beiden Servern gearbeitet und die Bytes liegen im Dateibereich. | quick-260922-hk4 (.planning/quick/260922-hk4-bilderrahmen-bilder-auf-die-festplatte/) |
Worum es geht
Die Bilder des Bilderrahmen-Widgets sind mit quick-260922-hk4 aus der
Datenbank in den Dateibereich gezogen (user-files/dashboard-images/ <userId>/<id>.<ext>, Pfad in der Spalte storagePath). Die Umstellung ist
BEWUSST ZWEISTUFIG:
- Stufe 1, ausgeliefert (Migration
20260922120000_dashboard_image_to_disk):storagePathdazu (NULLbar),datawird NULLbar — aber NICHT gelöscht. Der Umzug der vorhandenen Zeilen passiert beim ersten Start automatisch (DashboardImagesService.onApplicationBootstrap()). - Stufe 2, dieser Zettel:
datalöschen,storagePathauf NOT NULL.
Warum nicht sofort: prisma migrate deploy läuft VOR dem Anwendungsstart.
Ein sofortiges DROP COLUMN "data" hätte die Bytes vernichtet, bevor der
Umzug beim Start sie lesen konnte (T-HK4-03).
Was zu tun ist
-
Vorbedingung prüfen (auf BEIDEN Servern, alpha und live):
SELECT count(*) FROM "DashboardImage" WHERE "storagePath" IS NULL;Muss überall
0sein. Ist sie es nicht, ist der Umzug dort noch nicht gelaufen (Server noch auf einer älteren Version) — dann NICHT ausliefern. -
Neue Migration
20260922120100_dashboard_image_drop_data:ALTER TABLE "DashboardImage" ALTER COLUMN "storagePath" SET NOT NULL; ALTER TABLE "DashboardImage" DROP COLUMN "data"; -
Schema
apps/api/prisma/schema.prisma: Felddata Bytes?entfernen,storagePath String?→storagePath String. -
Dienst
apps/api/src/dashboard/dashboard-images.service.ts:onApplicationBootstrap()samtforSystem()-Aufruf entfernt sich damit — der Umzug hat seine Arbeit getan. Danach:- Eintrag
apps/api/src/dashboard/dashboard-images.service.tsausFORSYSTEM_ALLOWED_CALL_SITESinapps/api/src/prisma/rls-access-inventory.spec.tswieder ENTFERNEN (die Liste ist ein „genau", ein veralteter Eintrag macht die Spec rot). - In
docs/mandantentrennung-zugriffsklassifikation.mdden Stand der Zeiledashboard-images.service.ts/dashboardImagevonsystem-gebundenzurück aufgebundensetzen und die Zahlen der Bereichszeiledashboardsowie die Summe neu messen (Gate-Schleife, nicht abschreiben). - Die Tests 18, 21, 22 und 23 der Dienst-Spec (Zeile ohne
storagePath, Bootstrap-Umzug) entfallen mit dem Umzug. - Die Regel
system_read_policyauf"DashboardImage"(angelegt in 20260922120000) kann bleiben oder mitDROP POLICYfallen — bleibt sie, gehört sie in der Klassifikation erwähnt; fällt sie, ist die Aufzählung „fünf/sechs Tabellen" dort nachzuziehen.
- Eintrag
-
Prüfen, dass die Datenbank kleiner wird:
SELECT pg_size_pretty(pg_total_relation_size('"DashboardImage"'));(Nach dem DROP zusätzlich
VACUUM FULL "DashboardImage";, sonst gibt PostgreSQL den Platz nicht ans Dateisystem zurück.)
Was passiert, wenn es liegen bleibt
Nichts Schlimmes: die Spalte steht leer herum und kostet je neuer Zeile
nichts. Der Gewinn der Umstellung (kleiner pg_dump) ist bereits da, weil
neue Uploads keine Bytes mehr in die Zeile schreiben. Nur die Bytes der
ALTEN Bilder bleiben bis dahin doppelt vorhanden — einmal in der Datei,
einmal in der Spalte.
Erledigt in quick-260924-m4n (24.09.2026)
- Migration heißt
20260924120000_dashboard_image_drop_data(nicht20260922120100: sie muss hinter allen vorhandenen Migrationen liegen). Sie prüft zuerst, dass keine Zeile ohnestoragePathexistiert, und bricht sonst mit Meldung ab, bevor sie etwas ändert;row_securityist für die Prüfung aus, damit ein Eigentümer ohne BYPASSRLS nicht still 0 Zeilen sieht (lokal nachgewiesen). DanachstoragePathNOT NULL,DROP COLUMN "data",DROP POLICY IF EXISTS system_read_policy ON "DashboardImage". - Dienst: Bootstrap-Umzug,
forSystem()und die Selbstheilung ausdataentfernt; der Upload vergibt die UUID selbst und legt die Zeile gleich mit Pfad an. Erlaubnisliste, Tests (10b, 10c, 18, 21–23 entfallen) und Zugriffsklassifikation nachgezogen (Zahlen mit der Gate-Schleife gemessen). - Wiederherstellungsweg nach einem Abbruch (fehlgeschlagene Migration als
zurückgenommen vermerken, 1.3.1 laufen lassen, erneut einspielen) in
docs/anleitung-betrieb.mdKapitel 4, in einer Wegwerf-Datenbank durchgespielt.