Раскладка: сходимость папки сериала (второй сезон в ту же папку)

При подтверждённом матче база папки (имя+год) наследуется от живой
папки-якоря того же (provider, provider_id) вместо печати заново из выхода
LLM — так второй/последующий сезон ложится в ТУ ЖЕ папку, а не заводит
рядом почти одинаковую. Отдельная сущность «тайтл» не вводится.

- layout: Plan.FolderBase перекрывает базу в папке и именах файлов;
  TitleFolder разбирает dst_path в папку тайтла и базу (снятие тега).
- store: LiveTitleFolders — dst_path живых ссылок того же матча.
- worker: resolveFolderBase (живость якоря — по наличию папки на диске,
  os.Lstat, а не по статусу ссылки в БД) в linkPlan и в превью ревью
  (превью=применение); рассинхрон нескольких живых папок → review из
  linking (deferred→review в графе нет).

Схема БД не менялась. Change series-folder-convergence заархивирован,
требования влиты в openspec/specs/file-layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-10 13:50:49 +03:00
co-authored by Claude Opus 4.8
parent 3f1a928000
commit 5c3ef79496
20 changed files with 1031 additions and 56 deletions
+6
View File
@@ -74,6 +74,9 @@ type Store interface {
ListOverrides(ctx context.Context, downloadID string) (map[string]string, error)
CreateFileLinks(ctx context.Context, links []store.FileLink) error
SupersedeForeignLinks(ctx context.Context, downloadID string, dstPaths []string) error
// LiveTitleFolders — dst_path живых ссылок загрузок того же (provider,
// provider_id), кроме excludeDownloadID (правило сходимости папки).
LiveTitleFolders(ctx context.Context, provider, providerID, excludeDownloadID string) ([]string, error)
LatestBatchID(ctx context.Context, downloadID string) (string, error)
ListFileLinksByBatch(ctx context.Context, batchID string) ([]store.FileLink, error)
DeleteFileLinksByBatch(ctx context.Context, batchID string) error
@@ -110,6 +113,9 @@ type Layouter interface {
Apply(ctx context.Context, links []layout.Link) ([]layout.Result, error)
Undo(ctx context.Context, links []layout.Link) (int, error)
Remove(ctx context.Context, links []layout.Link) (int, error)
// TitleFolder разбирает dst_path в папку тайтла и базу имени (правило
// сходимости папки). ok=false, если путь не под корнем нужной библиотеки.
TitleFolder(t layout.MediaType, dst string) (dir, base string, ok bool)
}
// NotifyEvent — повод позвать пользователя.