feat: add configurable backup time for local and USB backups

Replace hardcoded 8 PM / 9 PM backup schedules with user-selectable
hour dropdowns. Adds autoBackupHour and usbBackupHour fields to User
model. Cron jobs now check every hour against the configured time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-06-24 23:37:34 -04:00
co-authored by Claude Sonnet 4.6
parent 5e881c9ff7
commit 70b5e2ba47
5 changed files with 74 additions and 76 deletions
+14 -14
View File
@@ -308,7 +308,7 @@ router.get("/usb-backup-setting", async (req, res) => {
const user = await storage.getUser(userId);
if (!user) return res.status(404).json({ error: "User not found" });
res.json({ usbBackupEnabled: user.usbBackupEnabled });
res.json({ usbBackupEnabled: user.usbBackupEnabled, usbBackupHour: user.usbBackupHour ?? 21 });
});
// PUT usb backup setting
@@ -316,15 +316,15 @@ router.put("/usb-backup-setting", async (req, res) => {
const userId = req.user?.id;
if (!userId) return res.status(401).json({ error: "Unauthorized" });
const { usbBackupEnabled } = req.body;
if (typeof usbBackupEnabled !== "boolean") {
return res.status(400).json({ error: "usbBackupEnabled must be a boolean" });
}
const { usbBackupEnabled, usbBackupHour } = req.body;
const patch: any = {};
if (typeof usbBackupEnabled === "boolean") patch.usbBackupEnabled = usbBackupEnabled;
if (typeof usbBackupHour === "number") patch.usbBackupHour = usbBackupHour;
const updated = await storage.updateUser(userId, { usbBackupEnabled });
const updated = await storage.updateUser(userId, patch);
if (!updated) return res.status(404).json({ error: "User not found" });
res.json({ usbBackupEnabled: updated.usbBackupEnabled });
res.json({ usbBackupEnabled: updated.usbBackupEnabled, usbBackupHour: updated.usbBackupHour ?? 21 });
});
// GET auto backup setting
@@ -335,7 +335,7 @@ router.get("/auto-backup-setting", async (req, res) => {
const user = await storage.getUser(userId);
if (!user) return res.status(404).json({ error: "User not found" });
res.json({ autoBackupEnabled: user.autoBackupEnabled });
res.json({ autoBackupEnabled: user.autoBackupEnabled, autoBackupHour: user.autoBackupHour ?? 20 });
});
// PUT auto backup setting
@@ -343,15 +343,15 @@ router.put("/auto-backup-setting", async (req, res) => {
const userId = req.user?.id;
if (!userId) return res.status(401).json({ error: "Unauthorized" });
const { autoBackupEnabled } = req.body;
if (typeof autoBackupEnabled !== "boolean") {
return res.status(400).json({ error: "autoBackupEnabled must be a boolean" });
}
const { autoBackupEnabled, autoBackupHour } = req.body;
const patch: any = {};
if (typeof autoBackupEnabled === "boolean") patch.autoBackupEnabled = autoBackupEnabled;
if (typeof autoBackupHour === "number") patch.autoBackupHour = autoBackupHour;
const updated = await storage.updateUser(userId, { autoBackupEnabled });
const updated = await storage.updateUser(userId, patch);
if (!updated) return res.status(404).json({ error: "User not found" });
res.json({ autoBackupEnabled: updated.autoBackupEnabled });
res.json({ autoBackupEnabled: updated.autoBackupEnabled, autoBackupHour: updated.autoBackupHour ?? 20 });
});
router.post("/backup-path", async (req, res) => {