From 3df892455fc5a0f00c8f65903440544147bc0ff0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Tr=C3=A1vn=C3=ADk?=
Date: Mon, 1 Dec 2025 11:29:39 +0100
Subject: [PATCH] optionaly exclude runtime info
---
app/client/components/export-dialog.tsx | 18 ++++++++++++++++++
.../lifecycle/config-export.controller.ts | 15 +++++++++++++--
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/app/client/components/export-dialog.tsx b/app/client/components/export-dialog.tsx
index 902e112b..13de35a4 100644
--- a/app/client/components/export-dialog.tsx
+++ b/app/client/components/export-dialog.tsx
@@ -26,6 +26,7 @@ export type SecretsMode = "exclude" | "encrypted" | "cleartext";
export type ExportOptions = {
includeIds?: boolean;
includeTimestamps?: boolean;
+ includeRuntimeState?: boolean;
includeRecoveryKey?: boolean;
includePasswordHash?: boolean;
secretsMode?: SecretsMode;
@@ -49,6 +50,7 @@ async function exportFromApi(endpoint: string, filename: string, options: Export
const params = new URLSearchParams();
if (options.includeIds === false) params.set("includeIds", "false");
if (options.includeTimestamps === false) params.set("includeTimestamps", "false");
+ if (options.includeRuntimeState === true) params.set("includeRuntimeState", "true");
if (options.includeRecoveryKey === true) params.set("includeRecoveryKey", "true");
if (options.includePasswordHash === true) params.set("includePasswordHash", "true");
if (options.secretsMode && options.secretsMode !== "exclude") params.set("secretsMode", options.secretsMode);
@@ -150,6 +152,7 @@ export function ExportDialog({
const [open, setOpen] = useState(false);
const [includeIds, setIncludeIds] = useState(true);
const [includeTimestamps, setIncludeTimestamps] = useState(true);
+ const [includeRuntimeState, setIncludeRuntimeState] = useState(false);
const [includeRecoveryKey, setIncludeRecoveryKey] = useState(false);
const [includePasswordHash, setIncludePasswordHash] = useState(false);
const [secretsMode, setSecretsMode] = useState("exclude");
@@ -168,6 +171,7 @@ export function ExportDialog({
await exportConfig(entityType, {
includeIds,
includeTimestamps,
+ includeRuntimeState,
includeRecoveryKey: isFullExport ? includeRecoveryKey : undefined,
includePasswordHash: isFullExport ? includePasswordHash : undefined,
secretsMode: hasSecrets ? secretsMode : undefined,
@@ -242,6 +246,20 @@ export function ExportDialog({
Include createdAt and updatedAt timestamps. Disable for cleaner exports when timestamps aren't needed.
+
+ setIncludeRuntimeState(checked === true)}
+ />
+
+
+
+ Include current status, health checks, and last backup information. Usually not needed for migration.
+
+
{hasSecrets && (
<>
diff --git a/app/server/modules/lifecycle/config-export.controller.ts b/app/server/modules/lifecycle/config-export.controller.ts
index 006a0327..16163494 100644
--- a/app/server/modules/lifecycle/config-export.controller.ts
+++ b/app/server/modules/lifecycle/config-export.controller.ts
@@ -43,10 +43,20 @@ function omitKeys>(obj: T, keys: string[]): Pa
return result;
}
-function getExcludeKeys(includeIds: boolean, includeTimestamps: boolean): string[] {
+function getExcludeKeys(includeIds: boolean, includeTimestamps: boolean, includeRuntimeState: boolean): string[] {
const idKeys = ["id", "volumeId", "repositoryId", "scheduleId", "destinationId"];
const timestampKeys = ["createdAt", "updatedAt"];
+ // Runtime state fields (status, health checks, last backup info, etc.)
+ const runtimeStateKeys = [
+ // Volume state
+ "status", "lastError", "lastHealthCheck",
+ // Repository state
+ "lastChecked",
+ // Backup schedule state
+ "lastBackupAt", "lastBackupStatus", "lastBackupError", "nextBackupAt",
+ ];
return [
+ ...(includeRuntimeState ? [] : runtimeStateKeys),
...(includeIds ? [] : idKeys),
...(includeTimestamps ? [] : timestampKeys),
];
@@ -56,8 +66,9 @@ function getExcludeKeys(includeIds: boolean, includeTimestamps: boolean): string
function parseExportParams(c: Context): ExportParams {
const includeIds = c.req.query("includeIds") !== "false";
const includeTimestamps = c.req.query("includeTimestamps") !== "false";
+ const includeRuntimeState = c.req.query("includeRuntimeState") === "true";
const secretsMode = (c.req.query("secretsMode") as SecretsMode) || "exclude";
- const excludeKeys = getExcludeKeys(includeIds, includeTimestamps);
+ const excludeKeys = getExcludeKeys(includeIds, includeTimestamps, includeRuntimeState);
return { includeIds, includeTimestamps, secretsMode, excludeKeys };
}