import { NextResponse } from "next/server"; import { withAdminAuth } from "@/lib/middleware/auth"; import { exec } from "child_process"; import { promisify } from "util"; import fs from "fs"; import path from "path"; const execAsync = promisify(exec); // Check if we're running in a Linux/Docker environment const isLinux = process.platform === "linux"; async function getCronStatus() { if (!isLinux) { return { available: false, running: false, jobs: [], message: "Cron is only available in Linux/Docker environment", lastBackup: getLastBackupInfo(), lastReminder: getLastReminderInfo() }; } try { // Check if cron daemon is running let cronRunning = false; try { await execAsync("pgrep -x cron || pgrep -x crond"); cronRunning = true; } catch { cronRunning = false; } // Get current crontab let jobs = []; try { const { stdout } = await execAsync("crontab -l 2>/dev/null"); jobs = stdout.trim().split("\n").filter(line => line && !line.startsWith("#")); } catch { jobs = []; } return { available: true, running: cronRunning, jobs: jobs, jobCount: jobs.length, lastBackup: getLastBackupInfo(), lastReminder: getLastReminderInfo() }; } catch (error) { return { available: false, running: false, jobs: [], error: error.message, lastBackup: getLastBackupInfo(), lastReminder: getLastReminderInfo() }; } } function getLastBackupInfo() { try { const backupDir = path.join(process.cwd(), "backups"); if (!fs.existsSync(backupDir)) { return { exists: false, message: "No backups directory" }; } const files = fs.readdirSync(backupDir) .filter(f => f.startsWith("backup-") && f.endsWith(".sqlite")) .map(f => ({ name: f, path: path.join(backupDir, f), mtime: fs.statSync(path.join(backupDir, f)).mtime })) .sort((a, b) => b.mtime - a.mtime); if (files.length === 0) { return { exists: false, message: "No backups found" }; } const latest = files[0]; return { exists: true, filename: latest.name, date: latest.mtime.toISOString(), count: files.length }; } catch (error) { return { exists: false, error: error.message }; } } function getLastReminderInfo() { try { const logPath = path.join(process.cwd(), "data", "reminders.log"); if (!fs.existsSync(logPath)) { return { exists: false, message: "No reminders log" }; } const stats = fs.statSync(logPath); return { exists: true, lastModified: stats.mtime.toISOString() }; } catch (error) { return { exists: false, error: error.message }; } } async function getHandler() { const status = await getCronStatus(); return NextResponse.json(status); } async function postHandler(request) { const { action } = await request.json(); if (!isLinux) { return NextResponse.json({ success: false, message: "Cron operations are only available in Linux/Docker environment" }, { status: 400 }); } try { if (action === "restart") { // Run the setup-cron.sh script const scriptPath = path.join(process.cwd(), "setup-cron.sh"); if (!fs.existsSync(scriptPath)) { return NextResponse.json({ success: false, message: "setup-cron.sh script not found" }, { status: 500 }); } // Make sure script is executable await execAsync(`chmod +x ${scriptPath}`); // Run the script const { stdout, stderr } = await execAsync(`bash ${scriptPath}`); // Get updated status const status = await getCronStatus(); return NextResponse.json({ success: true, message: "Cron jobs restarted successfully", output: stdout, status }); } else if (action === "run-backup") { // Manually trigger backup const backupScript = path.join(process.cwd(), "backup-db.mjs"); const { stdout } = await execAsync(`cd ${process.cwd()} && node ${backupScript}`); return NextResponse.json({ success: true, message: "Backup completed", output: stdout }); } else if (action === "run-reminders") { // Manually trigger reminders const reminderScript = path.join(process.cwd(), "send-due-date-reminders.mjs"); const { stdout } = await execAsync(`cd ${process.cwd()} && node ${reminderScript}`); return NextResponse.json({ success: true, message: "Reminders sent", output: stdout }); } else { return NextResponse.json({ success: false, message: "Unknown action" }, { status: 400 }); } } catch (error) { return NextResponse.json({ success: false, message: error.message, stderr: error.stderr }, { status: 500 }); } } export const GET = withAdminAuth(getHandler); export const POST = withAdminAuth(postHandler);