feat(identity): source-aware short-drama enrichment with snippet mode and hit rate (META-2)

- classify enrich sources: encyclopedia, platform pages (hongguo, kuaikaw, video
  platforms), douban (search snippet only) and other sites' search snippets
  (snippet mode, pages never opened); one extractor per source, fields carry
  source kind and confidence, merged by noisy-OR across hosts
- new cast field (applied as MediaCredit with placeholder ids)
- robots.txt check (cached per host 1 day) and login-wall/captcha give-up
- per-enrichment source attempts + GET /identity/enrich-stats, 30-day hit-rate
  table under settings -> metadata -> identity
- setting identity.enrichSnippetAllSites (default on); default domains add
  baike.com and kuaikaw.cn
- replay fixtures from the real run on the 4 user-library short dramas
  (sanitized Brave responses, hongguo page, robots.txt)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 18:40:19 +08:00
1 parent 081db4651c
commit 9489e40e0c
23 files changed
+2615 -323

No files matched your search

+11
View File
@@ -4,6 +4,7 @@ import {
type EnrichApplyInput,
EnrichApplyResult,
type EnrichRequest,
EnrichStats,
ExternalIdentity,
type IdentityCandidateReason,
type IdentityCandidateStatus,
@@ -28,6 +29,7 @@ export const identityKeys = {
identities: (f: IdentityFilters) => ["identity", "external", f] as const,
revisions: (id: string) => ["identity", "revisions", id] as const,
aliases: (f: AliasFilters) => ["identity", "aliases", f] as const,
enrichStats: (days: number) => ["identity", "enrich-stats", days] as const,
};
export type PoolFilters = { status?: IdentityCandidateStatus; reason?: IdentityCandidateReason; q?: string };
@@ -159,6 +161,15 @@ export function useDeleteAlias() {
});
}
/** 元数据补全命中率(最近 N 天,按来源类别;META-2) */
export function useEnrichStats(days = 30) {
return useQuery({
queryKey: identityKeys.enrichStats(days),
queryFn: ({ signal }) => getParsed(EnrichStats, "/identity/enrich-stats", { days }, signal),
staleTime: 60_000,
});
}
/** 元数据补全建议(metadata.enrich;不改作品,同一标题 7 天内返回上次结果) */
export function useEnrichPool() {
return useMutation({