feat: add Auto Check MH Payment toggle with weekly schedule

Adds a toggle behind the Go button on the Payments page to automatically run the MH batch payment check on a user-selected day of week and hour. Default is off.

- Schema: added autoMhCheckEnabled, autoMhCheckDayOfWeek, autoMhCheckHour to User model
- Backend: new mhBatchPaymentService (shared logic), GET/PUT /auto-mh-check-setting routes, hourly cron job that fires on matching day+hour
- Frontend: toggle + day select (Mon–Sun) + time select (hourly) that persist immediately to DB

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 22:58:36 -04:00
co-authored by Claude Sonnet 4.6
parent 27d9132820
commit fc3e8c0e25
310 changed files with 2821 additions and 2015 deletions
+44
View File
@@ -9,6 +9,7 @@ import { runNetworkSync, runNetworkFilesSync } from "../services/networkSyncServ
import { readRcloneConfig, writeRcloneConfig } from "../services/rcloneConfigService";
import { runRclonePull } from "../services/rcloneService";
import { importLatestBackup } from "../services/autoImportService";
import { runMhBatchPaymentCheck } from "../services/mhBatchPaymentService";
// Local backup folder in the app root (apps/Backend/backups)
const LOCAL_BACKUP_DIR = path.resolve(process.cwd(), "backups");
@@ -267,4 +268,47 @@ export const startBackupCron = () => {
}
}
});
// ============================================================
// Every hour — Auto MH payment check (runs when day-of-week and hour match setting)
// ============================================================
cron.schedule("0 * * * *", async () => {
const admin = await getAdminUser();
if (!admin) return;
if (!admin.autoMhCheckEnabled) return;
const now = new Date();
const currentDayOfWeek = now.getDay(); // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
const currentHour = now.getHours();
const targetDay = admin.autoMhCheckDayOfWeek ?? 1;
const targetHour = admin.autoMhCheckHour ?? 13;
if (currentDayOfWeek !== targetDay || currentHour !== targetHour) return;
console.log(`🔄 [Auto MH Check] Running scheduled MH batch payment check...`);
const startedAt = new Date();
const log = await cronJobLogStorage.createJobLog("auto-mh-check", startedAt);
try {
// Check the past 7 days
const toDate = now.toISOString().split("T")[0];
const fromDateObj = new Date(now);
fromDateObj.setDate(fromDateObj.getDate() - 7);
const fromDate = fromDateObj.toISOString().split("T")[0];
const result = await runMhBatchPaymentCheck(admin.id, fromDate, toDate);
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
console.log(`✅ Auto MH Check done: ${result.importSummary ?? result.message ?? "complete"}`);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : String(err);
console.error("Auto MH Check failed:", err);
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
await storage.createNotification(
admin.id,
"BACKUP",
`❌ Auto MH payment check failed: ${errorMessage}`
);
}
});
};