feat: add Job Monitor page with cron job logging and Selenium queue status
This commit is contained in:
@@ -3,6 +3,7 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import { storage } from "../storage";
|
||||
import { backupDatabaseToPath } from "../services/databaseBackupService";
|
||||
import { cronJobLogStorage } from "../storage/cron-job-log-storage";
|
||||
|
||||
// Local backup folder in the app root (apps/Backend/backups)
|
||||
const LOCAL_BACKUP_DIR = path.resolve(process.cwd(), "backups");
|
||||
@@ -45,17 +46,26 @@ export const startBackupCron = () => {
|
||||
|
||||
if (!admin.autoBackupEnabled) {
|
||||
console.log("✅ [8 PM] Auto-backup is disabled for admin, skipped.");
|
||||
const startedAt = new Date();
|
||||
const log = await cronJobLogStorage.createJobLog("local-backup", startedAt);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "skipped", new Date());
|
||||
return;
|
||||
}
|
||||
|
||||
const startedAt = new Date();
|
||||
const log = await cronJobLogStorage.createJobLog("local-backup", startedAt);
|
||||
|
||||
try {
|
||||
const filename = `dental_backup_${Date.now()}.sql`;
|
||||
await backupDatabaseToPath({ destinationPath: LOCAL_BACKUP_DIR, filename });
|
||||
await storage.createBackup(admin.id);
|
||||
await storage.deleteNotificationsByType(admin.id, "BACKUP");
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
console.log(`✅ Local backup done → ${filename}`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("Local backup failed:", err);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -80,11 +90,19 @@ export const startBackupCron = () => {
|
||||
|
||||
if (!admin.usbBackupEnabled) {
|
||||
console.log("✅ [9 PM] USB backup is disabled for admin, skipped.");
|
||||
const startedAt = new Date();
|
||||
const log = await cronJobLogStorage.createJobLog("usb-backup", startedAt);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "skipped", new Date());
|
||||
return;
|
||||
}
|
||||
|
||||
const startedAt = new Date();
|
||||
const log = await cronJobLogStorage.createJobLog("usb-backup", startedAt);
|
||||
|
||||
const destination = await storage.getActiveBackupDestination(admin.id);
|
||||
if (!destination) {
|
||||
const errorMessage = "No backup destination configured.";
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -96,6 +114,8 @@ export const startBackupCron = () => {
|
||||
const usbBackupPath = path.join(destination.path, USB_BACKUP_FOLDER_NAME);
|
||||
|
||||
if (!fs.existsSync(usbBackupPath)) {
|
||||
const errorMessage = `Folder "${USB_BACKUP_FOLDER_NAME}" not found on the drive.`;
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
@@ -109,9 +129,12 @@ export const startBackupCron = () => {
|
||||
await backupDatabaseToPath({ destinationPath: usbBackupPath, filename });
|
||||
await storage.createBackup(admin.id);
|
||||
await storage.deleteNotificationsByType(admin.id, "BACKUP");
|
||||
await cronJobLogStorage.completeJobLog(log.id, "success", new Date());
|
||||
console.log(`✅ USB backup done → ${usbBackupPath}/${filename}`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
console.error("USB backup failed:", err);
|
||||
await cronJobLogStorage.completeJobLog(log.id, "failed", new Date(), errorMessage);
|
||||
await storage.createNotification(
|
||||
admin.id,
|
||||
"BACKUP",
|
||||
|
||||
Reference in New Issue
Block a user