Move database backup policy and scheduling to shared global configuration. - Split project memory backups from cluster-wide database backup settings. - Migrate legacy backup values and routines safely into central global storage. - Schedule and dispatch one shared PostgreSQL backup routine across project engines. Files changed: .changeset/fn-8129-backup-settings-scope-split.md | 7 + docs/dashboard-guide.md | 2 + docs/settings-reference.md | 10 +- packages/cli/src/commands/backup.ts | 3 +- .../__tests__/backup-settings-migration.test.ts | 50 ++++++ .../src/__tests__/backup-settings-scope.test.ts | 27 +++ packages/core/src/backup-settings-migration.ts | 188 +++++++++++++++++++++ packages/core/src/backup.ts | 77 +++++---- packages/core/src/global-routine-store.ts | 104 ++++++++++++ packages/core/src/index.gate.ts | 6 +- packages/core/src/index.ts | 6 +- .../core/src/postgres/migrations/0000_initial.sql | 19 +++ .../postgres/migrations/0015_global_routines.sql | 19 +++ packages/core/src/postgres/schema-applier.ts | 19 ++- packages/core/src/postgres/schema/central.ts | 21 ++- packages/core/src/postgres/startup-factory.ts | 11 ++ packages/core/src/settings-schema.ts | 14 +- packages/core/src/types.ts | 31 +++- .../dashboard/app/components/SettingsModal.tsx | 10 +- .../settings/__tests__/section-keys.test.ts | 1 + .../app/components/settings/save-split.ts | 2 + .../search/__tests__/settings-search-index.test.ts | 1 + .../settings/search/entries.ts | 2 + .../app/components/settings/section-keys.ts | 4 - .../settings/sections/BackupsSection.search.ts | 40 ----- .../settings/sections/BackupsSection.tsx | 112 +----------- .../sections/DatabaseBackupsSection.search.ts | 51 ++++++ .../settings/sections/DatabaseBackupsSection.tsx | 142 ++++++++++++++++ .../settings-default-descriptions.test.tsx | 1 + packages/dashboard/src/routes.ts | 12 +- .../src/routes/register-settings-memory-routes.ts | 41 ++--- .../engine/src/__tests__/routine-scheduler.test.ts | 55 +++++- packages/engine/src/cron-runner.ts | 4 +- packages/engine/src/routine-runner.ts | 67 +++++--- packages/engine/src/routine-scheduler.ts | 35 +++- 35 files changed, 929 insertions(+), 265 deletions(-) Fusion-Task-Id: FN-8129 Fusion-Task-Lineage: af17f39a-7f1c-40ff-8a4a-cd63895cd532 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
/**
|
|
* Search entries for the Backups section.
|
|
*
|
|
* FNXC:SettingsSearch 2026-07-15-17:35:
|
|
* One entry per settings control the section renders, co-located so a setting and its index entry change in the same edit. Labels and help mirror the section's `t()` calls verbatim: the index matches on the copy operators actually read, so a paraphrase here would make search miss the words on screen.
|
|
* The section's backup-stats panel and "Backup Now" button are deliberately absent — they report and trigger, they do not configure.
|
|
*/
|
|
import type { SettingsSearchEntry } from "../search/types";
|
|
|
|
export const backupsSearchEntries: SettingsSearchEntry[] = [
|
|
{
|
|
sectionId: "backups",
|
|
key: "memoryBackupEnabled",
|
|
labelKey: "settings.backups.enableAutomaticMemoryBackups",
|
|
labelFallback: " Enable automatic memory backups ",
|
|
helpKey: "settings.backups.whenEnabledProjectAndAgentMemoryFilesAre",
|
|
helpFallback:
|
|
"When enabled, project and agent memory files are backed up automatically on a schedule. Default: disabled.",
|
|
keywords: ["snapshot", "restore"],
|
|
},
|
|
{
|
|
sectionId: "backups",
|
|
key: "memoryBackupSchedule",
|
|
labelKey: "settings.backups.memoryBackupScheduleCron",
|
|
labelFallback: "Memory Backup Schedule (Cron)",
|
|
helpKey: "settings.backups.cronExpressionForMemoryBackupTimingDefault0",
|
|
helpFallback:
|
|
"Cron expression for memory backup timing. Default: 0 3 * * * (daily at 3 AM).",
|
|
keywords: ["timing", "frequency"],
|
|
},
|
|
{
|
|
sectionId: "backups",
|
|
key: "memoryBackupRetention",
|
|
labelKey: "settings.backups.memoryRetentionCount",
|
|
labelFallback: "Memory Retention Count",
|
|
helpKey: "settings.backups.numberOfMemoryBackupsToKeepOldestAre",
|
|
helpFallback:
|
|
"Number of memory backups to keep (oldest are deleted first). Range: 1-100. Default: 14.",
|
|
keywords: ["how many", "prune", "rotation"],
|
|
},
|
|
{
|
|
sectionId: "backups",
|
|
key: "memoryBackupDir",
|
|
labelKey: "settings.backups.memoryBackupDirectory",
|
|
labelFallback: "Memory Backup Directory",
|
|
helpKey: "settings.backups.directoryForMemoryBackupsRelativeToProjectRoot",
|
|
helpFallback:
|
|
"Directory for memory backups, relative to project root. Default: .fusion/backups/memory.",
|
|
keywords: ["location", "folder", "destination"],
|
|
},
|
|
{
|
|
sectionId: "backups",
|
|
key: "memoryBackupScope",
|
|
labelKey: "settings.backups.memoryBackupScope",
|
|
labelFallback: "Memory Backup Scope",
|
|
helpKey: "settings.backups.memoryBackupScopeHint",
|
|
helpFallback: "Default: all (project + agents).",
|
|
/*
|
|
FNXC:SettingsSearch 2026-07-15-17:35:
|
|
The paths this setting selects between (.fusion/memory, .fusion/agent-memory) live in the option labels, which the index does not read — only the row's label and help. They are keywords so an operator searching a path they saw in the dropdown still lands here.
|
|
*/
|
|
keywords: ["agent memory", ".fusion/memory", ".fusion/agent-memory", "what to back up"],
|
|
},
|
|
];
|