Files
Kontrollverlust/notes/migrations.md
T
irrlicht 15ef7db5f7 Profilbilder: Avatar-Upload, Anzeige auf Profil & Feed
- user.avatar-Spalte (Schema, migrate.sh, Migrationsdoku)
- POST /user/avatar (geschützt): Upload via storeImage, ersetzt/löscht altes Bild
- avatar in /u/{name}/info, /user/info und im entrySelect-Join (Feed-Karten)
- Account-Löschung entfernt auch das Avatar-File
- Frontend: Avatar im Profilkopf + Byline der Karten (50px), Upload-Form,
  Platzhalterbild no_profile_pic.jpg als Fallback
- .card img per :not(.avatar) von Beitragsbildern getrennt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:20:14 +02:00

3.4 KiB

Datenbank-Migrationen

Manuelle Schritte, die beim Deploy gegen eine bestehende Datenbank nötig sind. Eine frische DB (Schema aus db.go) braucht keine davon.


avatar-Spalte in user

Wann: beim Deploy der Profilbild-Version gegen eine bestehende kver.db.

Hintergrund: Profilbilder werden als Pfad (static/media/...) in der neuen Spalte user.avatar gespeichert (leerer String = kein Bild, Frontend zeigt dann das Platzhalterbild). CREATE TABLE IF NOT EXISTS ergänzt die Spalte bei einer vorhandenen Tabelle nicht.

Migration:

ALTER TABLE user ADD COLUMN avatar TEXT NOT NULL DEFAULT '';

Bestehende Nutzer haben damit kein Bild (''). Nur einmalig ausführen.


filepath NULL → leerer String

Wann: beim Umstieg auf die Go-Version, falls entry.filepath NULL-Werte enthält.

Hintergrund: scanEntries scannt filepath in ein Go-string-Feld (kein Pointer). SQLite NULL in ein string scannen schlägt fehl; scanEntries überspringt diese Zeilen still mit continue. Ergebnis: Einträge ohne Bild fehlen im Feed komplett. Das aktuelle Go-Schema definiert filepath TEXT NOT NULL DEFAULT ''. migrate.sh normalisiert NULL → '' beim Kopieren aus der Quelldatenbank.

UPDATE entry SET filepath = '' WHERE filepath IS NULL;

filepath-Sentinel "none" → leerer String

Wann: beim Umstieg auf die Go-Version, falls eine alte kver.db aus der Python-Zeit weiterverwendet wird.

Hintergrund: Die Python-Version schrieb für Beiträge ohne Bild den String "none" in entry.filepath. Die Go-Version nutzt stattdessen den leeren String (Go-Zero-Value) und prüft nur noch auf filepath == "". Alte "none"-Zeilen würden sonst im Feed als Bildpfad interpretiert (<img src="/none"> → kaputtes Bild).

Migration:

UPDATE entry SET filepath = '' WHERE filepath = 'none';

Idempotent — kann gefahrlos mehrfach laufen.


Threading-Spalten in entry

Wann: beim Deploy der Threading-Version gegen eine bestehende kver.db, die die Tabelle entry noch ohne die Threading-Spalten hat.

Hintergrund: Das Threading führt reply_to (pid des Eltern-Posts, 0 = Root), reply_count (Anzahl Antworten im gesamten Teilbaum) und last_activity (Sortierschlüssel des Hauptfeeds) ein. CREATE TABLE IF NOT EXISTS ergänzt diese Spalten bei einer vorhandenen Tabelle nicht.

Migration:

ALTER TABLE entry ADD COLUMN reply_to INTEGER NOT NULL DEFAULT 0;
ALTER TABLE entry ADD COLUMN reply_count INTEGER NOT NULL DEFAULT 0;
ALTER TABLE entry ADD COLUMN last_activity INTEGER;
UPDATE entry SET last_activity = created_at WHERE last_activity IS NULL;

Bestehende Zeilen werden so zu Root-Beiträgen (reply_to = 0, reply_count = 0) mit last_activity = created_at. Nicht idempotent — die ALTER TABLE-Zeilen nur einmalig ausführen.


Soft-Delete-Spalte in entry

Wann: beim Deploy der Soft-Delete-Version gegen eine bestehende kver.db.

Hintergrund: Statt Beiträge hart zu löschen werden sie als [deleted]-Platzhalter markiert (deleted = 1, Inhalt/Bild/Autor geleert), damit Antworten nicht verwaisen. Das Frontend und die Feeds erkennen gelöschte Beiträge an dieser Spalte.

Migration:

ALTER TABLE entry ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0;

Bestehende Beiträge bleiben damit sichtbar (deleted = 0). Nur einmalig ausführen.