feat(metadata): overview falls back to Chinese variants only (MD-2)

- adapters: overviewLanguages() limits overview/tagline chain to Chinese
  variants (zh-CN→zh-SG→zh-TW→zh-HK); titles keep full chain; season
  supplement fetch skips languages useless for overview
- setting metadata.overviewNonChineseFallback (default off) + UI switch
- media detail shows "暂无简介" for empty entity/episode overview
- scripts/overview-recompute.ts: recompute stored non-Chinese overviews
  from kv_cache only (no TMDB requests), dry-run by default, --apply
- tests: chain unit tests, Heart Signal (103147) fixture, server
  recompute test, MP differential for episode overview
- runbook + CHANGELOG

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 18:04:23 +08:00
1 parent 081db4651c
commit f9901b514b
22 files changed
+887 -38

No files matched your search

+3 -3
View File
@@ -28,7 +28,7 @@ import type { z } from "zod";
import { type AuthEnv, requireScope } from "../../http/auth.ts";
import { ApiException } from "../../http/errors.ts";
import type { SourcesRuntime } from "../sources-identity/runtime.ts";
import { metadataLanguages } from "../sources-identity/service/metadata-rich.ts";
import { metadataLanguages, metadataTextOptions } from "../sources-identity/service/metadata-rich.ts";
import { upsertSiteRelease } from "../sources-identity/service/snapshot.ts";
import type { ModuleApp, ServerContext } from "../types.ts";
import { matchActions } from "./actions.ts";
@@ -169,7 +169,7 @@ export function registerSearchRoutes(app: ModuleApp, ctx: ServerContext, d: Sear
try {
const langs = await metadataLanguages(ctx);
return await raceAbort(
fetchRichDetail(client, type, id, langs),
fetchRichDetail(client, type, id, langs, await metadataTextOptions(ctx)),
AbortSignal.timeout(d.siteTimeoutMs),
"TMDB 查询超时",
);
@@ -413,7 +413,7 @@ export function registerSearchRoutes(app: ModuleApp, ctx: ServerContext, d: Sear
try {
const langs = await metadataLanguages(ctx);
const sd = await raceAbort(
fetchRichSeason(client, p.id, p.season, langs),
fetchRichSeason(client, p.id, p.season, langs, await metadataTextOptions(ctx)),
AbortSignal.timeout(d.siteTimeoutMs * 2),
"TMDB 查询超时",
);