query("SELECT setting_value FROM settings WHERE setting_key = 'worker_heartbeat'"); $lastHeartbeat = (int)$stmtStatus->fetchColumn(); $workerActive = (time() - $lastHeartbeat < 10); $stmt = db()->query("SELECT * FROM monitors ORDER BY created_at DESC"); $monitors = $stmt->fetchAll(); foreach ($monitors as &$m) { // Fetch last 30 logs $logStmt = db()->prepare("SELECT status_code, latency, checked_at FROM monitor_logs WHERE monitor_id = ? ORDER BY checked_at DESC LIMIT 30"); $logStmt->execute([$m['id']]); $m['history'] = array_reverse($logStmt->fetchAll()); } echo json_encode([ 'success' => true, 'data' => $monitors, 'worker_active' => $workerActive ]); } catch (Exception $e) { echo json_encode(['success' => false, 'error' => $e->getMessage()]); } break; case 'add': $data = json_decode(file_get_contents('php://input'), true); $name = $data['name'] ?? ''; $url = $data['url'] ?? ''; $interval = (int)($data['interval'] ?? 1); if (empty($name) || empty($url)) { echo json_encode(['success' => false, 'error' => 'Name and URL are required.']); exit; } try { $stmt = db()->prepare("INSERT INTO monitors (name, url, interval_min) VALUES (?, ?, ?)"); $stmt->execute([$name, $url, $interval]); echo json_encode(['success' => true]); } catch (Exception $e) { echo json_encode(['success' => false, 'error' => $e->getMessage()]); } break; case 'delete': $id = $_GET['id'] ?? null; if (!$id) { echo json_encode(['success' => false, 'error' => 'Missing ID.']); exit; } try { $stmt = db()->prepare("DELETE FROM monitors WHERE id = ?"); $stmt->execute([$id]); // Also cleanup logs $stmt = db()->prepare("DELETE FROM monitor_logs WHERE monitor_id = ?"); $stmt->execute([$id]); echo json_encode(['success' => true]); } catch (Exception $e) { echo json_encode(['success' => false, 'error' => $e->getMessage()]); } break; default: echo json_encode(['success' => false, 'error' => 'Invalid action.']); break; }