Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
21 KiB
SAVEPOINT — Rippy
Aktueller Stand: v3.7 — Drei Praxis-Bugs (Mounts, HandBrake, Encoder-Wahl) (24.07.2026)
Alle drei live auf der VM verifiziert:
- Speicher-Mounts robust: Ein toter CIFS-Mount (NAS weg/Rebuild) war
mounted:false, verschwand aus „Verfügbare Ziele" und ließ sich nicht neu
anlegen („Name existiert"). Jetzt:
reachable-Status (boundedtimeout 3 ls— Endpoint lädt in 0,014 s statt 10 s),umount -l-Fallback,reparieren()(lazy abhängen + frisch mounten), Re-Add repariert statt 409, POST /storage-mounts/{name}/repair, eigene „Netzwerk-Mounts"-Liste im UI mit Status + Reparieren/Entfernen. Bewiesen: Reparatur desrippy- Mounts → mounted:true, writable:true. - HandBrake-Versionen konsistent: Windows-Installer zieht dynamisch die neueste (GitHub latest) — bewiesen: HandBrake 1.11.2 installiert (statt fest 1.9.2). Update-UI erklärt: Docker = Debian-stabil (bewusst älter), Windows = neueste. Nebenbei ein latenter Installer-Bug gefixt: PowerShell 5.1 liest .ps1 als ANSI — ein Gedankenstrich zerschoss das Skript → install.ps1 ist jetzt ASCII-only.
- Encoder-/Worker-Wahl beim Rip: Celery
worker_direct=True, gezieltes Routing (transcode_queue) mit sicherem Fallback auf die geteilte Queue. Bewiesen mit ping_worker: Task landet exakt beim gewählten Node. Dropdown im Rip-Dialog ab 2 Online-Workern. Node-Zuordnung disambiguiert bei mehreren Workern pro Host. Nebenfund gefixt: DeviceDiscovery leitete die Titel-Auswahl (titles) gar nicht weiter. ⚠️ Gezieltes Routing braucht AKTUELLEN Worker-Code (worker_direct) — ein vor dieser Version installierter Remote-Worker pingt zwar, konsumiert aber seine Direkt-Queue nicht → neu installieren. - Voller Transcode-E2E weiterhin durch die UHD-Key-Lage blockiert (keine entschlüsselbare Disc) — die Routing-Mechanik ist per ping_worker bewiesen.
Vorheriger Stand: v3.6 — Design 2.0 gelandet + Ein-Branch-Umstellung (24.07.2026)
- Design 2.0 ist in
main(von Gemini umgesetzt): UI von 428theme === 'dark'-Ternaries auf Tailwind-dark:+ UI-Primitives (components/ui/,lib/design.ts) umgebaut, „Cinematic Cinema OS"-Look. Ampel grün (49 Tests, Ruff, Vite-Build), Live auf der VM. - Nur noch EIN Branch:
main(Commander-Entscheid). Derstable-Zwischenbranch samt Grün-Gate ist abgeschafft — er war vestigial, weil die VM ohnehin ausmaindeployt. Konsequenzen:- ci.yml: Beförderungs-Schritt raus, die Ampel PRÜFT nur noch.
- deploy.sh: nutzt
mainstattstable. - AGENTS §C / README / DESIGN-Briefing entsprechend umgeschrieben.
- Gelöschte Branches:
stable,design-2.0(gemergt),kernumbau-2026-07-23(alt).
- Deploy-Weg ab jetzt: push → Ampel grün prüfen → auf der VM
git pull(in ~/projects/rippy) bzw../deploy.sh.
Vorheriger Stand: v3.5 — Track-Tabelle, nativer Windows-Worker, Anleitungs-Tab (24.07.2026, Claude)
- Volle Titel-Auswahl vor dem Rip: „Disc scannen" im Rip-Dialog → Worker-Task scan_tracks (makemkvcon info; Ergebnis via settings-Tabelle 'tracks:', UI pollt) → Tabelle mit Checkbox/Dauer/Größe/Kapiteln, Vorauswahl ab 5 min. Gewählte Titel gehen als meta.titles in den Job; der Worker rippt sie einzeln (makemkvcon kann pro Aufruf nur einen Titel oder all), Fortschritt anteilig. Parser mit Tests (apdefs-Attr 8/9/11).
- Nativer Windows-Worker (ohne Docker!): Einstellungen → Worker bietet
jetzt ZWEI Varianten — Linux (Docker, wie gehabt) und Windows (nativ,
braucht nur Python). Die Rippy-Instanz versorgt sich selbst:
GET /worker-setup/windows liefert install.ps1, /worker-setup/paket den
Worker-Code als Zip (beides liegt via api-Dockerfile im Image).
install.ps1: venv + Abhängigkeiten, HandBrakeCLI 1.9.2 vom offiziellen
GitHub-Release (URL verifiziert), start-worker.bat (celery -Q transcode
--pool=solo), optional -Autostart (schtasks onlogon). tasks.py lädt auf
Windows ohne fcntl (Import-Guard); rip_disc ist dort hart verriegelt.
Für echte Transcodes übersetzt RIPPY_PATH_MAP die Container-Pfade aufs
Netzlaufwerk (pfad_lokal, mit Tests) — Voraussetzung bleibt eine
Freigabe der Rippy-Ablage (derselbe offene Infra-Punkt wie beim
Linux-Remote-Worker/AI-Box).
E2E-BEWEIS (24.07., Commander-PC): Installer in einem Rutsch
durchgelaufen (venv, Abhängigkeiten, HandBrakeCLI 1.9.2), Worker
gestartet und in Rippy erschienen:
test-windows-nativ | online: True | HandBrake: 1.9.2 | IP: 192.168.178.98— echte LAN-IP, Celery-Ping grün. Testeintrag danach wieder entfernt. - Tray-Symbol + rückstandsfreie Deinstallation (v3.5.1, bewiesen):
tray.py (pystray/Pillow, nur Windows-Worker) — Disc-Symbol neben der
Uhr mit Status, Start/Stopp, „Rippy öffnen", Log, Beenden; Celery läuft
als Kind ohne Konsolenfenster. install.ps1 erzeugt start-tray.bat
(empfohlen), start-worker.bat (Debug) und uninstall.ps1. E2E bewiesen
auf dem Commander-PC: Frisch installiert → Tray + celery-Kind liefen →
tray-testonline in Rippy → uninstall.ps1 -Force stoppte alle Prozesse, meldete den Worker per DELETE /workers/{name} ab und löschte den Ordner restlos (danach: 0 Prozesse, Ordner weg, in Rippy nur noch rippy-hauptworker). - Anleitungs-Tab im UI: kompletter Selbsterklärer (Disc-Weg, Serien, NAS, Media-Server, Benachrichtigungen, Key, Worker, Downloads, FAQ).
- Design 2.0 kommt bewusst in eine FRISCHE Session (Commander-Entscheid) — Infrastruktur steht (darkMode 'class'), reine Konvertierungsarbeit.
Vorheriger Stand: v3.4 — Restefeger: der Ideen-Katalog ist abgearbeitet (24.07.2026, Claude)
Commander-Entscheid: AUTH IST KOMPLETT RAUS (Heimnetz-only; das UI hatte nie einen Login, die Endpoints waren Placebo, passlib/bcrypt brach die Ampel). /token + /api-keys + auth.py + Abhängigkeiten entfernt, JWT_SECRET_KEY ist keine Pflicht mehr — der Schnellstart läuft ohne .env-Zwang. KONZEPT §10.
Neu in v3.4 (Details in ROADMAP Etappe 15):
- Serien-Flow: Rip-Dialog fragt Serienname + Staffel → Ablage
<Serie>/Season NN, tvshow.nfo/poster im Serien-Ordner, und die Episoden werden per Laufzeitabgleich (TMDB) erkannt und benannt („Serie S01E02.mkv") — nur bei eindeutiger Zuordnung, sonst ehrliches Log. Komplette Staffel auf einer Disc klappt auch bei uniformen Anime-Laufzeiten. - Jellyfin/Emby-Refresh nach jedem fertigen Rip (URL/API-Key + Test-Knopf in Einstellungen → Ripping) — Disc rein, Film erscheint im Server, null Klicks dazwischen.
- Duplikat-Warnung per Disc-Fingerabdruck (Karte zeigt „bereits gerippt", Vollautomatik überspringt).
- „Nur Hauptfilm" funktioniert jetzt wirklich (Info-Lauf → längster Titel; pro Rip im Dialog wählbar). Vorher wirkungsloses Setting.
- OMDb-Treffer werden eingedeutscht (TMDB /find über die IMDb-ID).
- Dashboard: Speicherplatz-Anzeige (amber < 60 GB) + CSV-Export.
- Metadaten-Seite entfernt (Korrektur-Popup ist der einzige Weg) samt Placebo-Endpoints; Doppel-Jahr „(2009) (2009)" gefixt.
- Remote-Worker-Blocker behoben: redis/postgres waren NIE veröffentlicht — Ports 6379/5432 jetzt offen, API_URL für Worker gesetzt. Damit sind AI-Box/Windows-Worker überhaupt erst anschließbar.
Bewusst offen (ROADMAP „Ideen-Katalog (Rest)"): volle Track-Tabelle, nativer Windows-Worker (braucht Testlauf auf Ziel-Hardware), Design-2.0- Konvertierung (Infrastruktur steht), AI-Box-NFS-Export, Kodi-Refresh.
Vorheriger Stand: v3.3 — Praxis-Feedback-Runde (24.07.2026, Claude)
Zwei echte Bugs mit Beweis gefixt:
- SMB-Mount „Unable to apply new capability set": mount.cifs hebt
CAP_DAC_READ_SEARCH an — die fehlt in Dockers Default-Caps. Auf der VM
reproduziert (Bounding-Set a82425fb, Bit 2 fehlt) und mit
cap_add: DAC_READ_SEARCHbewiesen behoben (docker-compose.yml). - TMDB fiel still aus: Der Client konnte nur v4-Bearer-Tokens — der eingetragene übliche v3-Key (32 Hex) bekam still 401, Suche lieferte nur OMDb. Jetzt beide Key-Arten (ist_v4_token, mit Tests); Einstellungen → APIs hat „Verbindung prüfen" mit Live-Status je Quelle (am Cache vorbei).
Neu in v3.3:
- 4K UHD als eigener Disc-Typ (classify ≥ 55 GiB, beide detection.py, Tests): eigene Badge-Farbe überall, Prescan-Label „4K UHD".
- UHD-Kette diagnostiziert (Nachtrag, gleicher Tag): Der BU40N-Flash IST erledigt — makemkvcon meldet „Using LibreDrive mode (v06.3)". Der Summer-Wars-Fehlschlag lag NICHT am Laufwerk, sondern an „The volume key is unknown": die Disc (MKB v82) ist neuer als MakeMKVs Schlüssel-DB — auf der VM mit 1.17.7 UND der aktuellsten 1.18.4 bewiesen. Konsequenzen: MakeMKV auf 1.18.4 gehoben (Scan-Hänger durch überall genutztes --noscan umgangen, auf der BU40N sauber gelaufen; URL-Base → /download), run_makemkv reicht kritische Meldungen (volume key/Key abgelaufen) in den Fehlertext durch, UHD-Klartext unterscheidet jetzt „Laufwerk kann kein UHD" von „Disc neuer als Key-DB" inkl. Forum-Dump-Hinweis (MakeMKV speichert den AACS-Dump automatisch unter /root/.MakeMKV/). Summer Wars bleibt bis zu einem MakeMKV-Key-Update nicht entschlüsselbar — das ist Stand der Technik, kein Rippy-Bug.
- Vollautomatik (Einstellungen → Ripping): Disc erkannt → Rip startet ohne Popup in den passenden Schnellwahl-Ordner (Serie/Film/Musik).
- Job-Verwaltung: „Neu komprimieren" nur noch, wenn Rohdaten wirklich daliegen (can_retry); Jobs einzeln löschbar (Papierkorb) + „Erledigte aufräumen" mit Bestätigungs-Dialog — Dateien bleiben immer liegen.
- „Alle herunterladen" im Job-Detail (gestaffelte Einzel-Downloads — bewusst kein Server-seitiges 40-GB-Zip).
- Worker zuordenbar: WORKER_NAME-Env als stabiler Anzeigename (compose: rippy-hauptworker; Remote-Worker: frei wählbar) — fixt zugleich die Offline-Leichen nach Rebuilds; IP + Container-ID werden mit angezeigt, verwaiste Einträge sind löschbar (DELETE /workers/{name}). Online-Abgleich läuft jetzt über info.hostname.
- Disc-Karte: „Quelle: TMDB/OMDb/MyAnimeList · xx % sicher" statt des nackten „Übereinstimmung xx %"; TMDB-Metadaten sind Deutsch (language= de-DE war schon überall dran — sie kamen nur nie an, siehe Key-Bug).
- Ripping-Tab nach Medium gegliedert (Video / Audio-CD / Allgemein) + Klartext: alle Tonspuren & Untertitel bleiben erhalten (--all-audio/ --all-subtitles) — wichtig für Anime.
- Ordner-Verwaltung (Ex-„Dateibrowser") ist jetzt beschriftet, erklärt und standardmäßig eingeklappt.
- Docker-Pflicht beim Worker: ehrlich im UI beantwortet; nativer Windows-Dienst steht als Ausbaustufe in der ROADMAP (Ideen-Katalog).
Vorheriger Stand: v3.2 — Universal-Komfort-Runde + Ampel entrostet (24.07.2026, Claude)
Wichtigster Befund zuerst: die Ampel war seit dem 23.07. ROT und stable
hing 10 Commits hinter main — deshalb kam nichts Neues mehr auf die VM.
Zwei Ursachen, beide behoben:
- bcrypt ≥ 4.1 bricht passlib 1.7.4 (
__about__entfernt → Selbsttest wirft „password cannot be longer than 72 bytes") → bcrypt==4.0.1 gepinnt. - Der cache_keys-Test kannte den Disc-Fingerprint im Prescan-Key (23.07.) nicht → Test an das echte Format angepasst + Fingerprint-Testfall dazu.
Neu in v3.2 (Commander-Sammelauftrag, alles mit Tests / Vite-Build grün):
- Media-Server-Integration: Setting
mediaServer(Wizard + Einstellungen → Ripping): Zielordner „Titel (Jahr)" statt Job-UUID; für Jellyfin/Emby/Kodi zusätzlich movie.nfo/tvshow.nfo + poster.jpg (Worker: medien.py). Plex = nur Benennung. Job speichert Disc-Metadaten jetzt mit (jobs.meta, Migration). - Benachrichtigungen ECHT: notify.py in API+Worker (Discord/Slack/ntfy/ generisch, Erkennung an der URL) — das Feld war vorher ein Placebo. Meldung bei fertig/fehlgeschlagen/abgebrochen; Anleitung + „Test senden" im UI.
- SMB-Scan-Fix: „NT_STATUS_ACCESS_DENIED" heißt jetzt im Klartext „Gast- Abfrage verweigert → Benutzer/Passwort eintragen"; Credential-Felder stehen im UI VOR dem Auflisten-Knopf. NAS-Ziel-Anlage quittiert per Toast.
- 4K-UHD-Vorsorge: Arbeitsverzeichnis
workDirkonfigurierbar (auf NAS-Freigabe legbar), Platz-Check per Disc-Größe (ioctl) VOR dem Rip mit Klartext-Abbruch statt voller Platte bei 40 GB. - Einstellungen → System: Werkzeug-Versionen je Worker (MakeMKV/HandBrake, ENV MAKEMKV_VERSION im Image), Key-Quelle (ui/env/keiner), freier Platz; MakeMKV-Beta-Key im UI pflegbar — gilt ab dem nächsten Rip, ohne Rebuild.
- Job-Detail-Popup (Klick auf Titel in „Neueste Jobs"): Poster, Jahr, Beschreibung, Genres, Ablagepfad, Fehler (GET /jobs/{id}/detail).
- Download fertiger Rips im Browser: „Download"-Knopf bei fertigen Jobs (Aktion-Spalte) → Dateiliste mit Größen im Detail-Popup, Stream via GET /jobs/{id}/files/{name} (Pfad-Validierung strikt unter /app/media, realpath-Check gegen Symlink-Ausbrüche) — vorher nur per scp erreichbar.
- UI-Feedback: Toast-System (ToastContext, ploppt oben rechts), drehende Refresh-Knöpfe, Logs-Pills um Warnung/Fehler ergänzt, Datei-Browser zeigt jetzt auch DATEIEN (grau, mit Größe) — der „leere" Bluray-Ordner war voll.
- Favicon (Disc, Indigo-Verlauf) + Footer „Created with ❤️ by LucyAI, Claude and KrBrZ".
- Doku: README (Media-Server, Benachrichtigungen, UHD-Arbeitsverzeichnis, „Rippy woanders bereitstellen"), ROADMAP Etappe 13 + Ideen-Katalog, KONZEPT-Fortschreibungen (Abschnitt 10), AGENTS-Stand.
Nächste Schritte: unverändert die Fäden aus v3.1 (unten) + Ideen-Katalog in der ROADMAP (Serien-Flow, Duplikat-Warnung, Jellyfin-Refresh, Auth).
Vorheriger Stand: v3.1 — E2E BEWIESEN + Universal-Runde (24.07.2026, Claude)
Der Beweis steht: Evangelion 2.22 (BD-50) komplett durch die Kette — erkannt → verlustfrei gerippt (43 GB, LibreDrive) → H.264-komprimiert → 4,8 GB Endergebnis (Hauptfilm 3,3 GB + 4 Extras), Rohdaten automatisch gelöscht. Retry-transcode dabei live bewiesen (x265 war auf 4 vCPUs zu lahm → Abbruch + Neustart mit H.264 OHNE Neu-Rip).
Seit v3.0 dazugekommen (alles deployt, Ampel grün):
- Korrektur-Flow: „Nicht korrekt?!"-Popup an der Disc-Karte; Suche über alle Quellen (GET /metadata/search), Wahl wird 30 Tage per Disc-Fingerabdruck gemerkt (POST /metadata/override)
- Metadaten-Kette: BD-Klartext-Titel via ro-Mount (bdmt_*.xml), Jikan/MAL (keyless, Ähnlichkeits-Score), OMDb-Qualitäts-Gate, Wort-Strip-Degradation, ehrliches Cache-TTL (unknown nie cachen)
- Worker-Verwaltung (Einstellungen → Worker): Live-Erreichbarkeit (Celery-Ping + Minuten-Herzschlag), Copy-Paste-Anbindung neuer Maschinen
- Speicherziele: SMB-Freigaben-Auflistung, Schreibtest beim Mount, lokaler Ordner-Browser + mkdir; Mounts via UI (CAP_SYS_ADMIN + rshared)
- First-Run-Wizard, Job-Abbruch (kooperativ), Transcode als eigener
Task auf Queue
transcode(Basis Remote-GPU-Worker), ruff.toml gepinnt
Nächste Schritte: AI-Box als VAAPI-Transcode-Worker (VCN4; NFS-Export
nötig, deploy/remote-transcode-worker.yml) · TMDB-Key eintragen ·
Arcane-GitSync-Binding auf stable (aktuell Notfall-Deploy-Weg) ·
Metadaten-Seite entfernen, wenn Popup abgenommen · Jellyfin-Postprocessing
an Worker · Auth vor schreibende Endpoints · MAKEMKV_APP_KEY erneuern
(~Ende Juli, Forum t=1053).
Vorheriger Stand: v3.0 — Kernumbau (23.07.2026, Claude)
Der Zweck existiert jetzt wirklich. Komplett-Audit ergab: „Disc rein → gerippt raus" hatte nie einen Code-Pfad (Details in ROADMAP Etappe 11).
Kernpunkte des Umbaus:
- Rip-Kette komplett neu: POST /jobs → Celery → Worker (MakeMKV 1.18.4 verlustfrei, Etappe 10) → Postgres-Job-Status → UI. CD weiter via abcde.
- Disc-Erkennung über Kernel-ioctls (CDROM_DISC_STATUS + Größe), Watcher pollt statt udev (im Container gibt es kein udev).
- UI: echter Vite-Build hinter nginx mit /api-Proxy — vorher Dev-Server und hartkodiertes localhost:8000 (deshalb waren nie Laufwerke zu sehen).
- Compose: Laufwerk als devices: (Bind-Mounts gaben EPERM), Ausgabe auf media-Volume (vorher /output → nicht gemountet + read-only-Falle).
- Placebos entfernt: Mock-Logs, toter SSE-Stream, udevadm-Discovery, 14 Troubleshooting-Altdateien (ARCAN-*.md, Setup-Skripte, udev-Rules).
Hardware-Kette (23.07.): Laufwerk (Verbatim 4K BD RW, BU40N 1.05) hängt am
Proxmox-Host; LPM-Quirk usbcore.quirks=18a5:0428:k gefixt die Serien-Disconnects
(reboot-fest in GRUB). VM 106 bekommt es per USB-Passthrough host=18a5:0428.
⚠️ Firmware 1.05 kann KEIN UHD-Ripping (verschlüsselt) — Crossflash auf 1.03-MK
ist der dokumentierte Weg, separater Faden. DVD/BD normal geht.
Offen: E2E mit echter Disc · Jellyfin-Post-Processing an Worker anbinden · Auth vor schreibende Endpoints · MAKEMKV_APP_KEY in Arcane-Env pflegen (monatlich).
Vorheriger Stand
v1.10 — Complete Dark Mode Implementation (22.07.2026)
Rippy läuft auf Arcane VM (192.168.178.162):
- ✅ Arcane WebUI: http://192.168.178.162:3552
- ✅ Rippy UI: http://192.168.178.162:80
- ✅ Rippy API: http://192.168.178.162:8000
- ✅ Theme Context ausgelagert (App.tsx → ThemeContext.tsx + useDarkMode.ts)
- ✅ Config Validation mit TMDB-API-Key Pflicht
- ✅ Cache Key Centralization (cache/keys.py)
- ✅ Dark Mode mit Theme-Toggle und localStorage persistence (UI-Only)
- ✅ Alle UI-Komponenten komplett auf Dark Mode aktualisiert:
App.tsx,Dashboard.tsx,Settings.tsx,MetadataPreview.tsx
- ✅ Sidebar Navigation mit Dark Mode Support
- ✅ Einstellungen-Page mit Tab-Struktur
- ✅ Doppelte Arcane-Einträge behoben (
rippystattRippy) - ✅ Import-Fixes (relative → absolute Imports)
- ✅ Git Sync in Arcane konfiguriert
- ✅ Commit:
d2fb281— Complete Dark Mode Implementation
Docker-Container
| Container | Port | Status |
|---|---|---|
| rippy-api | 8000 | Healthy |
| rippy-worker | - | Running |
| rippy-ui | 80 | Running |
| rippy-postgres | 5432 | Healthy |
| rippy-redis | 6379 | Healthy |
Features
- ✅ Etappe 3: SQLite-Cache, TMDB/MusicBrainz/TheTVDB Clients, Pre-Scan, Metadaten-Preview
- ✅ Etappe 4: Jellyfin-Formatierung (NFO-Generator, Image-Downloader)
- ✅ Etappe 5: JWT-Auth (15min/7T), Rate-Limiting (100/min), API-Key-Management
- ✅ Etappe 6: Docker read_only, tmpfs, healthchecks, minimale Images
- ✅ Etappe 7: API UI Modernisiert, Import-Fixes, Doppelte Einträge behoben
- ✅ Etappe 8: Dark Mode mit Theme-Toggle, Separation of Concerns
- ✅ Etappe 9: Complete Dark Mode Implementation (alle UI-Komponenten)
- ✅ Dokumentation: README, KONZEPT.md, ROADMAP.md, SAVEPOINT.md
Nächste Schritte
- Job-Verlauf UI (aktuell nur leere Listen)
- TMDB API Schlüssel in Arcane Environment konfigurieren
- Proxmox LXC Template
- Ansible Playbooks
SoC Refactoring — Abgeschlossen (Etappe 9)
- ✅ Theme-Context: Theme-Logik aus App.tsx ausgelagert
- ✅ Dark Mode Utility: useDarkMode Hook implementiert
- ✅ Component-Struktur: Dark Mode props von inneren Komponenten versteckt
- ✅ Config Validation: TMDB-API-Key ist Pflicht
- ✅ Cache Key Centralization: cache/keys.py erstellt
- ✅ CD-Ripping: abcde-Integration implementiert
Git-Log
d2fb281 - fix: complete dark mode implementation with all UI components
43dfce5 - feat(ui): implement dark mode with theme toggle
rippy-ui-modern - UI Modernisiert & Import-Fixes
3d87c8c - Dokumentation aktualisiert
bdb9f8d - SAVEPOINT v1.5: Sicherheit abgeschlossen
efa642e - Etappe 6: Sicherheit
v2.0 — Fix-Runde nach externem Code-Review (22.07.2026, Claude)
Alle Befunde des Reviews behoben, echte Tests eingeführt, Ampel-CI aktiv.
Gefixt:
- Metadaten-Preview WIEDERHERGESTELLT: Beim SoC-Refactoring hatte ein Stub-Paket die echte prescan-Implementierung überschattet — die Preview lieferte immer „Unknown Disc". Echte Logik liegt jetzt im Paket, tote Altmodule (cache.py, prescan.py flach) gelöscht.
- Fortschrittsmeldung: Celery
update_statestatt Aufrufe eines nie existierenden Tasks;self.send_task(erfundene API) entfernt. - abcde-Kommando korrigiert (
-owar doppelt → CD-Ripping war nie funktionsfähig); Zielverzeichnis jetzt via OUTPUTDIR-Config; Kommando-Bau als testbare Funktion. - JWT: fester Schlüssel PFLICHT (kein Zufalls-Fallback pro Prozess mehr); Logout blacklistet wirklich; Cleanup löscht nur Abgelaufene (vorher: alles).
- main.py: crashende Endpoints repariert (fehlende Imports Path/secrets,
nicht existentes api_keys-Dict → ratelimit-Store), Audio-
year-Bug, Admin-Zugang aus .env statt hartkodiert. - Ruff komplett grün (29 Funde), package-lock.json committet.
- Tests: test_auth, test_cache_keys, test_ripping_helpers (der giftige test_health-Placebo ist raus).
✅ ENTSCHIEDEN (22.07. abends): Das KONZEPT gilt — MakeMKV kommt
MakeMKV lossless (Muss-Feature) wird umgesetzt — als eigene Etappe 10 in der ROADMAP (Worker-Container + makemkvcon + Beta-Key, in Zed zu bauen, E2E mit echter Disc). Bis dahin bleibt HandBrake als SICHTBARER Übergang aktiv — jede*r weiß: aktuell wird transkodiert, nicht verlustfrei gesichert.
Deploy-Weg seit 22.07. abends: GRÜN-GATE (vollautomatisch)
Push auf main → Ampel prüft → grün → CI befördert auf Branch stable →
Arcane-GitSync zieht stable und deployt. Rot deployt NIE. ./deploy.sh
ist nur noch der Notfall-Hebel; SSH zur VM bleibt als Fallback erlaubt.