settings: add factory reset button that wipes every table incl. config
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled

the existing clear-scan button only drops media_items + related; settings
survived. useful when schema changes or corrupt state make you want a full
do-over on a running container without ssh-ing in to rm data/netfelix.db.

POST /api/settings/reset truncates everything (config included) then re-seeds
DEFAULT_CONFIG via the exported reseedDefaults helper. env-var overrides keep
working through getConfig's env fallback. ui lives next to clear-scan in the
danger zone with a double confirm and reload to /, so the setup wizard shows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 15:16:07 +02:00
parent c06172f412
commit f4859317fa
4 changed files with 53 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
import { Hono } from "hono";
import { getAllConfig, getDb, getEnvLockedKeys, setConfig } from "../db/index";
import { getAllConfig, getDb, getEnvLockedKeys, reseedDefaults, setConfig } from "../db/index";
import { getUsers, testConnection as testJellyfin } from "../services/jellyfin";
import { testConnection as testRadarr } from "../services/radarr";
import { getScheduleConfig, type ScheduleConfig, updateScheduleConfig } from "../services/scheduler";
@@ -122,4 +122,26 @@ app.post("/clear-scan", (c) => {
return c.json({ ok: true });
});
/**
* Full factory reset. Truncates every table including config, re-seeds the
* defaults so the setup wizard reappears, and returns. Env-backed config
* keys (JELLYFIN_URL, etc.) continue to resolve via getConfig's env fallback
* — they don't live in the DB to begin with.
*/
app.post("/reset", (c) => {
const db = getDb();
db.transaction(() => {
// Order matters when ON DELETE CASCADE isn't consistent across versions.
db.prepare("DELETE FROM stream_decisions").run();
db.prepare("DELETE FROM jobs").run();
db.prepare("DELETE FROM subtitle_files").run();
db.prepare("DELETE FROM review_plans").run();
db.prepare("DELETE FROM media_streams").run();
db.prepare("DELETE FROM media_items").run();
db.prepare("DELETE FROM config").run();
})();
reseedDefaults();
return c.json({ ok: true });
});
export default app;

View File

@@ -102,6 +102,11 @@ function seedDefaults(db: Database): void {
}
}
/** Re-seed config defaults after a truncating reset. Caller owns the delete. */
export function reseedDefaults(): void {
seedDefaults(getDb());
}
export function getConfig(key: string): string | null {
// Env vars take precedence over DB
const fromEnv = envValue(key);