Приём: дедуп по target_missing/orphaned + стоп-кран «Закрыть»
Два дубля-близнеца на один инфохэш рождались, когда повторный приём
попадал на запись в target_missing: дедуп искал только активную задачу,
а target_missing терминален → заводилась новая загрузка, воркер усыновлял
уже присутствующий торрент и раскладывал его.
- Приём: критерий дедупа расширен до «блокирующей повторный приём» =
активные ∪ {target_missing, orphaned}. Повторный приём такого инфохэша
привязывается к существующей записи (спящей, без обращения к qBittorrent),
а не плодит близнеца. Прочие терминальные (done/cancelled/failed/reverted/
deleted) повторный приём не блокируют — осознанная свежая попытка. Новый
read-метод FindReingestBlockingByInfohash (приоритет активной над desync);
общий active-гард не тронут.
- Команда «Закрыть» (Dismiss) — универсальный стоп-кран из любого состояния,
кроме deleted → cancelled (error_code=user_dismiss). Только меняет статус:
файлы (в т.ч. хардлинки done/orphaned) и раздачу qBittorrent не трогает,
в отличие от «Удалить». Веб — danger-зона внизу страницы; Telegram —
кнопка с подтверждением; из cancelled — идемпотентный no-op.
- Транспорты при дедупе на desync-запись сообщают адресно (target_missing —
привязать заново/закрыть; orphaned — закрыть и добавить заново); веб при
дедупе ведёт на страницу существующей записи.
Спеки: ingest (дедуп), state-reconciliation (стоп-кран); граф переходов
допополнен рёбрами <терминал>→cancelled. OpenSpec change
dedup-target-missing-and-dismiss заархивирован.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,13 +92,27 @@
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<!-- Опасная зона: полное удаление загрузки (снять хардлинки + снести раздачу с
|
||||
файлами из qBittorrent). Секция скрыта в details (раскрыть сознательно). С JS
|
||||
hx-confirm показывает диалог подтверждения; без JS гейт — только раскрытие
|
||||
details и явный submit (диалога нет). -->
|
||||
{{if .Deletable}}
|
||||
<!-- Опасная зона: закрытие (только смена статуса) и полное удаление (снять
|
||||
хардлинки + снести раздачу). Секция скрыта в details (раскрыть сознательно).
|
||||
С JS hx-confirm показывает диалог подтверждения; без JS гейт — только
|
||||
раскрытие details и явный submit (диалога нет). -->
|
||||
{{if or .Dismissable .Deletable}}
|
||||
<details class="section danger-zone" style="margin-bottom:0;border-color:color-mix(in srgb,var(--st-err) 35%,transparent)">
|
||||
<summary style="color:var(--st-err);cursor:pointer;font-weight:600">Опасная зона</summary>
|
||||
{{if .Dismissable}}
|
||||
<p class="muted" style="margin:var(--sp-3) 0">
|
||||
Закрытие снимет запись из активного списка (перевод в «отменено») —
|
||||
<strong>файлы и раздачу не трогает</strong>. Стоп-кран для зависшей, спорной
|
||||
или лишней загрузки; при необходимости позже можно привязать заново.
|
||||
</p>
|
||||
<form method="post" action="/ui/downloads/{{.ID}}/dismiss"
|
||||
hx-post="/ui/downloads/{{.ID}}/dismiss" hx-target="#download-main" hx-swap="outerHTML"
|
||||
hx-confirm="Закрыть загрузку? Запись уйдёт в «отменено». Файлы и раздача останутся нетронутыми.">
|
||||
<input type="hidden" name="surface" value="download">
|
||||
<button class="btn btn-danger" type="submit">Закрыть загрузку</button>
|
||||
</form>
|
||||
{{end}}
|
||||
{{if .Deletable}}
|
||||
<p class="muted" style="margin:var(--sp-3) 0">
|
||||
Полное удаление снимет библиотечные хардлинки <strong>и</strong> снесёт раздачу
|
||||
с файлами из qBittorrent — освободит место. Действие необратимо.
|
||||
@@ -109,6 +123,7 @@
|
||||
<input type="hidden" name="surface" value="download">
|
||||
<button class="btn btn-danger" type="submit">Удалить загрузку</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</details>
|
||||
{{end}}
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user