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 }; }