feat: add auto-import toggle to restore latest backup after rclone pull
Adds autoImportEnabled/autoImportHour to rclone config. A separate hourly cron finds the latest .zip in backups/ and restores it to the database (drop schema, psql restore, apply migrations). Frontend shows toggle + time picker + Import Now button in the Receiver PC section. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { readSyncConfig, writeSyncConfig } from "../services/networkSyncConfigSe
|
||||
import { runNetworkSync, runNetworkFilesSync } from "../services/networkSyncService";
|
||||
import { readRcloneConfig, writeRcloneConfig } from "../services/rcloneConfigService";
|
||||
import { runRclonePull } from "../services/rcloneService";
|
||||
import { importLatestBackup } from "../services/autoImportService";
|
||||
|
||||
// Local backup folder in the app root (apps/Backend/backups)
|
||||
const LOCAL_BACKUP_DIR = path.resolve(process.cwd(), "backups");
|
||||
@@ -194,6 +195,42 @@ export const startBackupCron = () => {
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// Every hour — Auto-import latest backup (runs when hour matches config)
|
||||
// ============================================================
|
||||
cron.schedule("0 * * * *", async () => {
|
||||
const importConfig = readRcloneConfig();
|
||||
if (!importConfig.autoImportEnabled) return;
|
||||
|
||||
const currentHour = new Date().getHours();
|
||||
if (currentHour !== importConfig.autoImportHour) return;
|
||||
|
||||
console.log(`[${importConfig.autoImportHour}:00] Running auto-import of latest backup...`);
|
||||
|
||||
const admin = await getAdminUser();
|
||||
const startedAt = new Date();
|
||||
const log = await cronJobLogStorage.createJobLog("auto-import", startedAt);
|
||||
|
||||
try {
|
||||
await importLatestBackup();
|
||||
writeRcloneConfig({ lastImportAt: new Date().toISOString(), lastImportStatus: "success", lastImportError: null });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
console.log(`Auto-import complete.`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Auto-import failed:", err);
|
||||
writeRcloneConfig({ lastImportAt: new Date().toISOString(), lastImportStatus: "failed", lastImportError: errorMessage });
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
if (admin) {
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
`Auto-import failed: ${errorMessage}`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// Every hour — Network sync (runs only when hour matches config)
|
||||
// ============================================================
|
||||
|
||||
Reference in New Issue
Block a user