feat(metadata): cache metadata provider answers

Repeated searches and refreshes asked every provider again, which is slow and runs into provider
rate limits. Keep each provider's answer in Postgres, shared by all users, and reuse it until an
admin-set lifetime runs out. Search screens mark saved results and offer a fresh search, and
explicit refreshes stay live, falling back to a saved answer only when a provider fails.

Empty answers are only kept for API providers that report failures reliably, and a cache-only
request never calls a provider in cooldown. Book Dock's manual refetch stays live-only because
the dock has nowhere to report a fallback. Released iOS builds keep working: every new request
field is optional and newer clients gate it on the metadata-search-cache server feature.
This commit is contained in:
neon
2026-10-10 22:26:26 +00:00
parent c91648eaac
commit 7bb51a7a0b
200 changed files with 35972 additions and 566 deletions
+22
View File
@@ -169,6 +169,28 @@ export const E2E_SUITES = Object.freeze({
...SHARED_DB_AND_HELPER_PATHS,
],
},
"metadata-cache": {
id: "metadata-cache",
name: "Metadata Cache",
timeout: 60,
lane: "full",
description: "Metadata provider cache repository, executor and admin API suite",
vitestTarget: "test/metadata-cache.e2e-spec.ts",
junitOutput: `${TEST_RESULTS_DIR}/metadata-cache-e2e-junit.xml`,
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/metadata-cache/**",
"server/src/common/provider-cache/**",
"server/src/modules/metadata-fetch/**",
"server/src/modules/authors/metadata/**",
"server/src/modules/app-info/**",
"server/test/metadata-cache.e2e-spec.ts",
".github/workflows/e2e-runner.yml",
...SHARED_TYPES_PATHS,
...SHARED_DB_AND_HELPER_PATHS,
],
},
"metadata-lock": {
id: "metadata-lock",
name: "Metadata Lock",