iOS-Voll-App M0: Media-Registry (iCloud-Hybrid) — Originale in Nutzer-CloudKit, Server nur Previews: POST/PATCH/GET /api/media (register/confirm/mine/original-Fallback), Phantom-URL+iCloud-404 in serve_media, Registry-Cleanup in Delete-Pfaden, media_items mit storage+ck_record_name; Datenschutz v5 (CloudKit); Fixes: daily_photo_cache in zentrale Migration (Löschen warf auf frischer DB 500), Preview/Thumb-Leichen beim Medium-Löschen; 9 neue Tests, Suite 73 grün

This commit is contained in:
rene 2026-06-10 19:58:30 +02:00
parent 40d117874b
commit bf5df11f78
7 changed files with 565 additions and 3 deletions

View file

@ -2673,6 +2673,44 @@ def _migrate(conn_factory):
""")
logger.info("Migration: failed_emails Tabelle bereit.")
# iOS-Voll-App M0: Media-Registry — Originale liegen in der privaten
# CloudKit-DB des Nutzers, der Server hält nur Previews. Die Registry ist
# die Quelle der Wahrheit über Existenz + Speicherort (storage: server|icloud).
# ON DELETE CASCADE → Self-Delete (FK-Introspektion in profile.py) und
# Admin-Delete (finaler users-DELETE) räumen automatisch mit ab.
conn.executescript("""
CREATE TABLE IF NOT EXISTS media_registry (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
url TEXT NOT NULL UNIQUE,
storage TEXT NOT NULL DEFAULT 'icloud',
ck_record_name TEXT,
ck_state TEXT NOT NULL DEFAULT 'pending',
kind TEXT NOT NULL DEFAULT 'image',
context TEXT,
context_id INTEGER,
bytes_original INTEGER,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_media_registry_user ON media_registry(user_id);
CREATE INDEX IF NOT EXISTS idx_media_registry_ctx ON media_registry(context, context_id);
""")
logger.info("Migration: media_registry Tabelle bereit (iCloud-Hybrid).")
# daily_photo_cache wurde bisher NUR lazy in routes/dogs.py (Tagesfoto)
# angelegt — delete_diary/delete_media_item referenzieren sie aber auch.
# Auf einer frischen DB ohne Tagesfoto-Abruf warf Löschen daher 500.
# Struktur identisch zum Lazy-CREATE in dogs.py:241.
conn.executescript("""
CREATE TABLE IF NOT EXISTS daily_photo_cache (
dog_id INTEGER NOT NULL,
datum TEXT NOT NULL,
photo_url TEXT NOT NULL,
PRIMARY KEY (dog_id, datum)
);
""")
logger.info("Migration: daily_photo_cache Tabelle bereit.")
# Second-Pass der ALTER-TABLE-Migrations:
# Manche Migrations (z.B. diary_media.img_width) referenzieren Tabellen,
# die erst weiter unten in dieser Funktion per CREATE IF NOT EXISTS angelegt