feat(admin): add cache purge controls to settings

Add `purgeMetadataCache` and `purgeImageCache` procedures that let admins free disk space on demand. Metadata purge removes un-enriched stub titles not in any user's library plus orphaned person records; image purge deletes all cached TMDB files from disk.

Expose both as POST endpoints under `/admin/cache/` via the oRPC contract, implement the core logic in a new `@sofa/core/cache` module, and surface them in a new "Danger Zone" section on the Settings page with individual confirmation dialogs and a combined "Purge all" action.
This commit is contained in:
2026-03-15 10:37:35 -04:00
parent 33fd871114
commit 297eb6b550
12 changed files with 544 additions and 7 deletions
+19 -1
View File
@@ -43,6 +43,12 @@ _openapi:
- depth: 2
title: Trigger cron job
url: '#trigger-cron-job'
- depth: 2
title: Purge metadata cache
url: '#purge-metadata-cache'
- depth: 2
title: Purge image cache
url: '#purge-image-cache'
structuredData:
headings:
- content: List backups
@@ -71,6 +77,10 @@ _openapi:
id: toggle-telemetry
- content: Trigger cron job
id: trigger-cron-job
- content: Purge metadata cache
id: purge-metadata-cache
- content: Purge image cache
id: purge-image-cache
contents:
- content: Fetch all database backups with their sizes and creation times.
heading: list-backups
@@ -110,8 +120,16 @@ _openapi:
Manually trigger a background cron job by name. The job runs
asynchronously.
heading: trigger-cron-job
- content: >-
Delete un-enriched stub titles not in any user's library and clean up
orphaned person records.
heading: purge-metadata-cache
- content: >-
Delete all cached TMDB images from disk. Images will be re-downloaded
on demand.
heading: purge-image-cache
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./openapi.json"} webhooks={[]} operations={[{"path":"/admin/backups","method":"get"},{"path":"/admin/backups","method":"post"},{"path":"/admin/backups/{filename}","method":"delete"},{"path":"/admin/backups/restore","method":"post"},{"path":"/admin/backups/schedule","method":"get"},{"path":"/admin/backups/schedule","method":"put"},{"path":"/admin/registration","method":"get"},{"path":"/admin/registration","method":"put"},{"path":"/admin/update-check","method":"get"},{"path":"/admin/update-check","method":"put"},{"path":"/admin/telemetry","method":"get"},{"path":"/admin/telemetry","method":"put"},{"path":"/admin/jobs/trigger","method":"post"}]} showTitle={true} />
<APIPage document={"./openapi.json"} webhooks={[]} operations={[{"path":"/admin/backups","method":"get"},{"path":"/admin/backups","method":"post"},{"path":"/admin/backups/{filename}","method":"delete"},{"path":"/admin/backups/restore","method":"post"},{"path":"/admin/backups/schedule","method":"get"},{"path":"/admin/backups/schedule","method":"put"},{"path":"/admin/registration","method":"get"},{"path":"/admin/registration","method":"put"},{"path":"/admin/update-check","method":"get"},{"path":"/admin/update-check","method":"put"},{"path":"/admin/telemetry","method":"get"},{"path":"/admin/telemetry","method":"put"},{"path":"/admin/jobs/trigger","method":"post"},{"path":"/admin/cache/purge-metadata","method":"post"},{"path":"/admin/cache/purge-images","method":"post"}]} showTitle={true} />
+84
View File
@@ -5584,6 +5584,90 @@
]
}
},
"/admin/cache/purge-metadata": {
"post": {
"operationId": "admin.purgeMetadataCache",
"summary": "Purge metadata cache",
"description": "Delete un-enriched stub titles not in any user's library and clean up orphaned person records.",
"tags": [
"Admin"
],
"responses": {
"200": {
"description": "Counts of deleted titles and persons",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"deletedTitles": {
"type": "number",
"description": "Number of un-enriched stub titles deleted"
},
"deletedPersons": {
"type": "number",
"description": "Number of orphaned person records deleted"
}
},
"required": [
"deletedTitles",
"deletedPersons"
],
"description": "Result of purging un-enriched metadata from the database"
}
}
}
}
},
"security": [
{
"session": []
}
]
}
},
"/admin/cache/purge-images": {
"post": {
"operationId": "admin.purgeImageCache",
"summary": "Purge image cache",
"description": "Delete all cached TMDB images from disk. Images will be re-downloaded on demand.",
"tags": [
"Admin"
],
"responses": {
"200": {
"description": "Count of deleted files and bytes freed",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"deletedFiles": {
"type": "number",
"description": "Number of image files deleted from disk"
},
"freedBytes": {
"type": "number",
"description": "Total bytes freed from disk"
}
},
"required": [
"deletedFiles",
"freedBytes"
],
"description": "Result of purging the image cache from disk"
}
}
}
}
},
"security": [
{
"session": []
}
]
}
},
"/account/name": {
"put": {
"operationId": "account.updateName",