152 lines
12 KiB
Markdown
152 lines
12 KiB
Markdown
# Real-Debrid-Downloader — Tasks (Stand 2026-06-08)
|
||
|
||
**Status:** Alle zugesagten Features erledigt+released (Archiv unten). Aktuell läuft ein
|
||
**intensiver Bug-Audit** (User-Goal 2026-06-08, "schaue intensiv nach weiteren Bugs") —
|
||
Fortschritt direkt unten.
|
||
|
||
---
|
||
|
||
## 🔴 LAUFEND — Bug-Audit 2026-06-08 (Multi-Agent find→verify, 18 bestätigt)
|
||
|
||
Advisor-Triage: **A = einzige echte Daten-Verlust-Notlage** (zerstört echte Datei auf Platte)
|
||
→ zuerst, ALLEINE Release. **B verifiziert demoted:** applyRetroactiveCleanupPolicy/
|
||
removePackageFromSession löschen KEINE Platten-Dateien (nur Session/Queue-Einträge + ggf.
|
||
History-Eintrag) → Queue-Integrität, nicht Daten-Verlust → in v1.7.190-Batch.
|
||
Sequenz: Release 1 (v1.7.189) = **A allein**; Release 2 (v1.7.190) = B/I,C,D/E,F,G,H,J,L,M,N,O,P,Q.
|
||
Ein Commit pro Fix, jeder einzeln verifiziert. **K übersprungen** (auto-rename-Reorder,
|
||
schlechtestes Risiko/Nutzen, kann für diesen User gar nicht feuern).
|
||
|
||
### Release 1 — Daten-Verlust-Stopper (v1.7.189, A ALLEIN)
|
||
- [x] **A** `video-processor.ts` atomic-replace zerstörte bei Windows-Lock BEIDE Kopien
|
||
(rm(original) VOR bestätigtem Replace + outer-catch rm(temp) → 0 Kopien). **GEFIXT:**
|
||
atomic replace-over + `renameWithRetry` (EBUSY/EACCES/EPERM/EEXIST, Backoff 200/500/1000ms),
|
||
rm-first-Fallback entfernt, **unique** Temp-Name (`~rd<pid><rand>`, löst auch C-Kollision).
|
||
Advisor bestätigt Ansatz besser als bak-dance (kein Missing-File-Window). 3 neue Tests
|
||
(Recovery + Retry-Pfad), 41 video-processor-Tests grün, tsc=6 (Baseline). Commit 189af22.
|
||
|
||
### Release 2 — Medium/Low (v1.7.190), ein Commit pro Fix
|
||
- [ ] **B/I** `app-controller.ts` importBackup settings-only: setSettings → applyRetroactive
|
||
CleanupPolicy purged die LIVE-Queue (Vertragsbruch "running queue stays untouched"; Dateien
|
||
bleiben aber auf Platte). **Fix (Advisor):** (b) retroaktiven Sweep NUR für diesen Import
|
||
unterdrücken (importierte Policy gilt weiter für künftige Completions über normalen Pfad) —
|
||
NICHT über updateSettings routen (zweite Landmine resetHistoryForRetention). **I:** die 5
|
||
Live-Usage/Status-Felder overlayen wie updateSettings 322-331 INKL. Key-Filterung der
|
||
debridLinkApiKey*UsageBytes auf keyIds in restored debridLinkApiKeys (3 All-Time-Totals deckt
|
||
setSettings-Math.max schon ab). Vorher 1 grep: forward-Anwendungsstelle der Policy bestätigen.
|
||
- [ ] **C** ~~fixe Temp-Name-Kollision~~ → bereits in A subsumiert (unique Name).
|
||
- [ ] **D/E** debrid.ts Rotation: abort-Klassifizierung über `signal.reason` (TimeoutError vs
|
||
cancel) statt Text/elapsedMs; API-Pfad 'cancel' umgeht. **VORHER empirisch bestätigen:**
|
||
`AbortSignal.any([ac.signal, AbortSignal.timeout(x)]).reason?.name==='TimeoutError'` in DIESEM
|
||
Electron-Build; konservativen Fallback behalten, alte Guard nicht blind löschen.
|
||
- [ ] **F** Mega-Web empty-streak Concurrency (streak permanent-park unreachable-to-clear vorher
|
||
re-verifizieren bevor Maschinerie).
|
||
- [ ] **G** download-manager `dropItemContribution` subtrahiert Session-Totals nicht.
|
||
- [ ] **H** logger.ts `flushAsync` snapshot-by-slice korrumpiert bei 1MB-Cap-Trim während await
|
||
→ move-snapshot (`linesSnapshot = pendingLines; pendingLines = []`).
|
||
- [ ] **I** → mit B zusammen (app-controller live-usage-Counter).
|
||
- [ ] **J** download-manager `abortPackagePostProcessing` löscht Task-Handle ohne Identity-Guard.
|
||
- [ ] **L** `isGermanStream` Title-Regex False-Positive.
|
||
- [ ] **M** `looksLikeGermanRelease` 'dubbed' zu breit.
|
||
- [ ] **N** `stripDualLangFromFileName` Kollision.
|
||
- [ ] **O** classifyAccountFailure abort-Branch jetzt tot (nach v1.7.187-Fix).
|
||
- [ ] **P** extractor.ts nested-Resume-Keys (`nested:<name>`) bei jedem extractPackageArchives
|
||
gepurged (prune-Whitelist nur top-level) → `startsWith("nested:")` in prune skippen.
|
||
- [ ] **Q** (NEU, aus A-Review) `collectFilesByExtensions` filtert `~rd`-Temp-Präfix NICHT →
|
||
crash-verwaiste Teil-Remuxe könnten in Library gesammelt werden. Vorbestehend (alter fixer
|
||
`~rdtmp` wurde überschrieben, neuer unique akkumuliert) → `~`-Präfix in collect skippen.
|
||
|
||
---
|
||
|
||
## 🟢 OFFEN — Backlog (optional, nie begonnen)
|
||
|
||
### ✅ Mega-Web Account-Rotation überspringt Account 3 — GEFIXT 2026-06-08 (v1.7.187)
|
||
**Fix:** Ein Mega-Web-Account-Abbruch (geteiltes Timeout feuert während der Account lief)
|
||
setzt jetzt einen 2-min-Cooldown auf den Account (nur wenn er ≥8s lief, sonst = User-Cancel,
|
||
RD_MEGA_ABORT_MIN_RUN_MS env). Dadurch überspringt der download-manager-Retry diesen Account
|
||
und rotiert zum nächsten (debrid.ts, abort-Handling im Rotations-catch, vor classifyAccountFailure).
|
||
Log-Event `TIMEOUT_COOLDOWN` (gelb, "Timeout/Abbruch → nächster Account beim Retry") statt
|
||
rotem "fataler Fehler" (App.tsx:1141 Label). 2 Regressionstests (Cooldown gesetzt → Call 2
|
||
rotiert; Quick-Abbruch → kein Cooldown). EHRLICH: fixt Korrektheit, NICHT Latenz — Account 1
|
||
brennt weiter ~60s ins Timeout bevor der Retry auf Account 2 wechselt (instant-Failover bräuchte
|
||
per-Account-Timeout = größerer Eingriff, bewusst verschoben). Advisor-gegengeprüft.
|
||
|
||
**(Ursprüngliche Analyse — Symptom & Mechanismus, zur Doku belassen)**
|
||
**Symptom (User):** 3 Mega-Debrid-Web-Accounts aktiv, Rotation pendelt aber nur zwischen
|
||
Account 1 ↔ 2 (bzw. nur Account 1), Account 3 (Su****xe) wird NIE probiert.
|
||
|
||
**Verifizierter Mechanismus (Code):**
|
||
- Rotationsschleife `debrid.ts:1898`. Account 1 → "Mega-Web Antwort leer" → Cooldown 20s →
|
||
weiter zu Account 2. Account 2 → `aborted:debrid`.
|
||
- `classifyAccountFailure` (`debrid.ts:2036`) stuft JEDEN Abbruch als **fatal** ein →
|
||
`throw` (`debrid.ts:1991`) → Schleife bricht ab → **Account 3 nie erreicht.**
|
||
- Account 2 bekommt beim Fatal-Abbruch **keinen Cooldown** (cooldownMs:0). Beim
|
||
download-manager-Retry wird Account 1 (Cooldown) übersprungen, aber Account 2 (kein
|
||
Cooldown) ERNEUT vor Account 3 probiert → bricht wieder ab → ewiges 1↔2.
|
||
- Geteiltes 60s-Unrestrict-Timeout `download-manager.ts:8590` (`AbortSignal.any([taskAbort,
|
||
timeout(60s)])`) gilt für die GANZE Rotation, nicht pro Account. Mega-Web pollt intern bis
|
||
180s (`mega-web-fallback.ts:235` + Poll-Loop `:371`). Sobald das geteilte 60s feuert, bleibt
|
||
das kombinierte Signal aborted → KEIN späterer Account kriegt im selben Pass eine echte Chance.
|
||
|
||
**BESTÄTIGT 2026-06-08 (zweite Screenshots):** Account 1 läuft 10x rasch "erfolgreich"
|
||
(11:51:45–11:52:26), dann zwei "abgebrochen (aborted:debrid)" um 11:53:30 UND 11:54:30 —
|
||
**exakt 60s auseinander** = das geteilte 60s-Unrestrict-Timeout feuert (kein User-Stop, der
|
||
wiederholt sich nicht periodisch). Hier rotiert GAR NICHTS: Account 1 bricht ab → fatal →
|
||
Rotation stoppt sofort bei idx=0 → Account 2 und 3 werden NIE probiert. Bug eindeutig
|
||
bestätigt, elapsedMs nicht mehr nötig. Account 1 selbst ist gesund (10x ok) — Mega-Web hängt
|
||
nur sporadisch (no-server-Poll) bis ins 60s-Timeout.
|
||
|
||
**Fix-Design (wenn bestätigt):** Pro-Account-Timeout-Budget, abgekoppelt vom geteilten Cap.
|
||
debrid.ts braucht das **cancel-only** Signal getrennt vom Timeout (kombiniertes Signal kann
|
||
beides nicht unterscheiden). Minimal-invasiv: optionaler `opts`-Param an `unrestrictLink`
|
||
({cancelSignal, perAttemptTimeoutMs}) — nur die Mega-Rotation liest ihn, andere Provider
|
||
unberührt (kombiniertes Signal bleibt). Pro Account: `AbortSignal.any([cancelSignal,
|
||
AbortSignal.timeout(perAttemptMs)])`. Abbruch-Logik: cancelSignal aborted → echter Stop;
|
||
eigenes Account-Timer gefeuert → non-fatal, Cooldown, weiter zum nächsten Account (inkl. 3).
|
||
**Regressionstest ZUERST** (3 Accounts, 1+2 failen/aborten → assert Account 3 kriegt TEST).
|
||
**Advisor-Gate** vor Eingriff (kritischer Unrestrict-Pfad, betrifft jeden Download).
|
||
Hinweis: Grundursache der leeren Antworten = Mega-Debrid Server/IP-Thema — Fix macht Rotation
|
||
nur FAIRER (alle Accounts drankommen), bringt aber keinen busy Server zum Antworten.
|
||
|
||
### Features / UX (nach ROI)
|
||
App läuft headless auf Windows-Server → Nutzer sitzt nicht davor.
|
||
|
||
1. [ ] **Push-Benachrichtigungen** (Discord/Telegram/ntfy) — S–M. Paket fertig/Fehler/Quota/Provider-down aufs Handy. Neuer `notifier.ts`, Hooks an Completion-Punkten. **Höchster ROI.**
|
||
2. [ ] **Fernsteuerung über Debug-Server** (POST-Endpunkte) — S–M. Server hat HTTP + Token-Auth, aber nur GET. POST `/control/add-links`, `/start`, `/stop`.
|
||
3. [ ] **URL-Duplikat-Erkennung beim Hinzufügen** — S. History-`urls` existiert, wird nie geprüft → versehentliche Re-Downloads. Warnen: "3 Links bereits geladen".
|
||
4. [ ] **Pre-Flight-Check + Bulk-Skip toter Links** — M. Vor Start Größe/Name/Online für ganze Queue, "alle offline überspringen".
|
||
5. [ ] **Speicherplatz-Vorabprüfung vor Start** — S. Aktuell keine Free-Space-Prüfung für Downloads → Abbruch mitten drin bei voller Platte.
|
||
6. [ ] **Konsolidierte Fehler-Ansicht** — M. Alle fehlgeschlagenen Items flach + Fehlertext + "alle erneut versuchen". (Daten dafür liegen jetzt teils in der Error-Ring aus v1.7.185.)
|
||
7. [ ] **Per-Provider-Statistik** — M. Rohdaten (`providerTotalUsageBytes`) existieren, werden nicht dargestellt. Welches Abo lohnt sich?
|
||
8. [ ] **Auto-Retry fehlgeschlagener Pakete nach Wartezeit** — S–M. Quota/Cooldown-Fails am nächsten Tag automatisch neu.
|
||
9. [ ] **Plex/Jellyfin Library-Refresh nach MKV-Move** — S. Gleicher Hook wie #1.
|
||
10. [ ] **Watch-Folder für DLC/Link-Auto-Import** — M.
|
||
|
||
### Design-Richtung (Entscheidung steht aus)
|
||
4 Mockups in `design-mockups/` (index.html = Vergleich): **Aurora** (verfeinert dark, geringstes Risiko) · **Command** (Terminal/Ops, dicht) · **Vellum** (light editorial) · **Nebula** (neon).
|
||
→ Richtung wählen. Siehe Memory: design-taste (Anti-KI-Look) + design-direction (Ember-Wärme, flach/ehrlich).
|
||
|
||
### Alte Audit-Items (2026-04-04, Status ggf. veraltet — VOR Fix gegen aktuellen Code verifizieren)
|
||
- [ ] Debrid-Link `maxDataHost` kühlt ganzen Key ab statt nur den Host
|
||
- [ ] Debrid-Link `fileNotAvailable` setzt Key auf "error" statt temporär
|
||
- [ ] AllDebrid: kein per-host-Cooldown für erschöpfte Quotas
|
||
- [ ] LinkSnappy: keine Auth-Dedup (parallele Requests rufen beide authenticate())
|
||
- [ ] Extractor password-cache race (parallele Worker mutieren `packageLearnedPasswords`)
|
||
- [ ] Hybrid race: 1 Datei/Staffel evtl. beim MKV-Move nicht umbenannt (NUR per-package fixen — Post-MKV-Move-Scan ist tabu, v1.7.107 revertiert)
|
||
|
||
---
|
||
|
||
## ✅ ERLEDIGT — Archiv (Details in git-History + Memory)
|
||
|
||
- **Erweitertes Logging** → released **v1.7.185** (Crash-Handler, Renderer-Fehler-IPC, RD_DEBUG-Level, Error-Ring + `/errors`, ENOSPC-Klassifizierung, Memory-Heartbeat). → Memory: extended-logging
|
||
- **Link-Prefetch** → untersucht (6-Agent) + **bewusst verworfen** (marginal bei maxParallel 8, Mega-Web single-flight). → Memory: link-prefetch-declined
|
||
- **Backup nur Settings** → v1.7.184 (`backupIncludeDownloads`-Toggle + 4 Selektions/Flicker-Fixes). → Memory: backup-settings-only
|
||
- **Account-Rotation-Overhaul** → v1.7.164–168 (Validity/Premium-Badges, Live-Panel, "Alle prüfen"). → Memory: account-rotation
|
||
- **Mega-Debrid-Account deaktivieren (UI)** → erledigt (Toggle im Edit-Dialog, im Code verifiziert 2026-06-07)
|
||
- **Bugs/Robustheit (Deferred-Pipeline H1/H2/H3/M1/M2/N1)** → v1.7.158/159; M3 bewusst übersprungen (Generation-Guard schützt Integrität bereits)
|
||
- **Deferred-Pfad Rename-Gap** → gefixt v1.7.162+ (finaler Deferred-Pass benennt frische Dateien vor Collect um; Repro-Test grün)
|
||
- **Repo-Privacy-Audit** → GitHub gelöscht+neu (saubere History), Gitea unberührt. → Memory: repo-privacy-audit
|
||
|
||
### Bewusst NICHT angefasst (Crash-Debris / alte Experimente)
|
||
- Gestashtes Crash-Debris `stash@{0}` (Revert von 08372f9/18eada9/98dc366 + log.old) — bei Bedarf recoverbar, sonst verwerfbar
|
||
- Untracked `*-postprocess/` + `fix-library-renames.mjs` — alte Experimente (Apr/Mai)
|