Punkt 5 beschreibt die anonyme Reichweitenmessung inkl. ASN-Einordnung; durchgaengig "anonymisierte IP-Adresse" und expliziter Hinweis, dass auch fuer die ASN-Bestimmung nie die volle IP verwendet wird. IPv6- Anonymisierung auf /32 (letzte 96 Bit) korrigiert. Notes: Migration der asn-Spalte (ALTER TABLE) und neue Env-Var KVER_GEOIP_ASN samt GeoLite2-Bereitstellung. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.1 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.
asn-Spalte in impression
Wann: beim Deploy der ASN-Auswertung gegen eine bestehende impression-Tabelle.
Hintergrund: Pro Impression wird das autonome System (Netzbetreiber) gespeichert,
aufgelöst aus der vollen Client-IP vor dem Maskieren (siehe lookupASN). Die Spalte
liegt bewusst nicht im Primärschlüssel — pro anon_ip ist das ASN deterministisch,
also entstehen keine Zeilen-Duplikate, und ein simples ADD COLUMN genügt (kein
Tabellen-Rebuild). CREATE TABLE IF NOT EXISTS ergänzt die Spalte bei einer
vorhandenen Tabelle nicht.
Migration:
ALTER TABLE impression ADD COLUMN asn TEXT NOT NULL DEFAULT '';
Bestehende Zeilen haben damit kein ASN ('', in der Auswertung „(unbekannt)"). Nur
einmalig ausführen.