From 278079519f9604302db94b123b0b305f2b6baea4 Mon Sep 17 00:00:00 2001 From: 4gray Date: Mon, 21 Sep 2026 20:46:36 +0200 Subject: [PATCH] =?UTF-8?q?docs(tmdb):=20finish=20the=20sweep=20=E2=80=94?= =?UTF-8?q?=20a=20missed=20cache=20key=20and=20a=20last=20observed-fact=20?= =?UTF-8?q?claim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two spots the first pass left behind: - `tmdb-search-cache-cleanup.spec.ts` kept a catalog-derived lookup key verbatim. Only the TMDB id beside it had been swapped, because the sweep matched the title in its display casing and the key stores it lowercased — so one item of the inventory stayed in the repository, twice. - `SearchTitleVariant`'s doc comment still asserted that one specific folded string finds nothing on TMDB. State the mechanism instead: folding rewrites the letters the search matches on, so the folded form finds nothing there. `content-search.util.sqlite.spec.ts` gets a channel fixture that no longer reads as a film title. `search-text-fold.util.spec.ts` is deliberately left alone. Its "Ёлки" is a common noun sitting in a Unicode corpus beside "Amélie", "İnşaat" and "Ά", not an inventory entry — and its rows are precomposed/decomposed PAIRS (U+0401 against U+0415 U+0308). A textual substitution rewrites only the composed half and silently turns the pair into two different words; doing it failed that spec, which is what a fixture encoding an invisible property is for. Co-Authored-By: Claude Opus 5 --- .../database/operations/content-search.util.sqlite.spec.ts | 4 ++-- libs/services/src/lib/tmdb/tmdb-matcher.ts | 4 ++-- .../shared/database/src/lib/tmdb-search-cache-cleanup.spec.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/electron-backend/src/app/database/operations/content-search.util.sqlite.spec.ts b/apps/electron-backend/src/app/database/operations/content-search.util.sqlite.spec.ts index a4c74af9f..b732fd191 100644 --- a/apps/electron-backend/src/app/database/operations/content-search.util.sqlite.spec.ts +++ b/apps/electron-backend/src/app/database/operations/content-search.util.sqlite.spec.ts @@ -30,7 +30,7 @@ const TITLES = [ 'Şan Ve Şeref', 'Первый канал HD', 'ПЕРВЫЙ КАНАЛ', - 'Ёлки ТВ', + 'Ёжик ТВ', 'Йога для всех', 'Матч ТВ', 'Ελλάδα Σήμερα', @@ -179,7 +179,7 @@ describe('content-search.util against SQLite', () => { it.each([ ['Первый', 'первый', ['Первый канал HD', 'ПЕРВЫЙ КАНАЛ']], ['ПЕРВ', 'перв', ['Первый канал HD', 'ПЕРВЫЙ КАНАЛ']], - ['Ёлки', 'ёлки', ['Ёлки ТВ']], + ['Ёжик', 'ёжик', ['Ёжик ТВ']], ['Йога', 'йога', ['Йога для всех']], ['Ма', 'ма', ['Матч ТВ']], ['ΕΛΛ', 'ελλ', ['Ελλάδα Σήμερα']], diff --git a/libs/services/src/lib/tmdb/tmdb-matcher.ts b/libs/services/src/lib/tmdb/tmdb-matcher.ts index e7c862292..6c966bb5b 100644 --- a/libs/services/src/lib/tmdb/tmdb-matcher.ts +++ b/libs/services/src/lib/tmdb/tmdb-matcher.ts @@ -40,8 +40,8 @@ function stripLeadingLanguageToken(raw: string): string | null { /** * One search candidate: what to SEND to TMDB and what to COMPARE its * answers against. The two differ on purpose — see `cleanTitleForSearch`: - * a folded query ("леика") finds nothing on TMDB while the folded key is - * exactly what the confidence gate and the cache need. + * folding rewrites letters TMDB matches on, so the folded form finds nothing + * there, while it is exactly what the confidence gate and the cache need. */ export interface SearchTitleVariant { /** Provider spelling with tags/brackets/season/year stripped */ diff --git a/libs/shared/database/src/lib/tmdb-search-cache-cleanup.spec.ts b/libs/shared/database/src/lib/tmdb-search-cache-cleanup.spec.ts index 4a74ccea5..44352764e 100644 --- a/libs/shared/database/src/lib/tmdb-search-cache-cleanup.spec.ts +++ b/libs/shared/database/src/lib/tmdb-search-cache-cleanup.spec.ts @@ -63,7 +63,7 @@ it('drops only retired search rows across skipped, previous, pre-person, fresh a hooks.runMigrations(skipped); const skippedAfter = snapshot(skipped); // Next startup: a row written meanwhile under the current key survives - skipped.prepare("INSERT INTO tmdb_metadata (media_type, lookup_key, language, tmdb_id) VALUES ('tv', 'title:гудовы|year:2026|v4', 'ru-RU', 101103)").run(); + skipped.prepare("INSERT INTO tmdb_metadata (media_type, lookup_key, language, tmdb_id) VALUES ('tv', 'title:сосенка|year:2026|v4', 'ru-RU', 101103)").run(); hooks.runMigrations(skipped); const repeated = snapshot(skipped); // Previous release: the earlier cleanups already ran; only v3 rows go @@ -124,7 +124,7 @@ it('drops only retired search rows across skipped, previous, pre-person, fresh a markers: [V2_MARKER, V3_MARKER, V4_MARKER], }, repeated: { - keys: [...survivors, 'title:гудовы|year:2026|v4'].sort(), + keys: [...survivors, 'title:сосенка|year:2026|v4'].sort(), payloads: detailsPayloads, markers: [V2_MARKER, V3_MARKER, V4_MARKER], },