chartboard/app/Controllers/Alert/AlertController.php
2026-03-30 09:51:33 +05:30

233 lines
9.0 KiB
PHP

<?php
namespace App\Controllers\Alert;
use App\Controllers\BaseController;
use App\Models\AlertHistoryModel;
use App\Models\AlertModel;
use App\Models\ChartModel;
class AlertController extends BaseController
{
public function index()
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$alerts = (new AlertModel())->forWorkspace($workspaceId);
$recent = (new AlertHistoryModel())->recentForWorkspace($workspaceId, 12);
return view('alert/index', [
'title' => 'Alerts | Chart-Board',
'alerts' => $alerts,
'recent' => $recent,
]);
}
public function create()
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$charts = (new ChartModel())->forWorkspace($workspaceId);
return view('alert/create', [
'title' => 'New alert | Chart-Board',
'charts' => $charts,
]);
}
public function store()
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$userId = (int) $this->session->get('user_id');
$rules = [
'name' => 'required|min_length[2]|max_length[200]',
'chart_id' => 'required|integer',
'metric_field' => 'required|max_length[150]',
'condition' => 'required|in_list[gt,lt,eq,gte,lte]',
'threshold' => 'required|decimal',
'check_interval' => 'permit_empty|integer',
'notify_email' => 'permit_empty|in_list[0,1]',
'notify_slack' => 'permit_empty|in_list[0,1]',
'email_addresses' => 'permit_empty|max_length[2000]',
'slack_webhook' => 'permit_empty|max_length[500]',
];
if (! $this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$chartId = (int) $this->request->getPost('chart_id');
$chart = (new ChartModel())->where('workspace_id', $workspaceId)->find($chartId);
if (! $chart) {
return redirect()->back()->withInput()->with('error', 'Chart not found.');
}
$notifyEmail = (int) $this->request->getPost('notify_email') === 1 ? 1 : 0;
$notifySlack = (int) $this->request->getPost('notify_slack') === 1 ? 1 : 0;
(new AlertModel())->insert([
'workspace_id' => $workspaceId,
'chart_id' => $chartId,
'name' => strip_tags((string) $this->request->getPost('name')),
'metric_field' => trim((string) $this->request->getPost('metric_field')),
'condition' => (string) $this->request->getPost('condition'),
'threshold' => (float) $this->request->getPost('threshold'),
'check_interval' => max(1, (int) ($this->request->getPost('check_interval') ?: 15)),
'notify_email' => $notifyEmail,
'email_addresses' => trim((string) $this->request->getPost('email_addresses')) ?: null,
'notify_slack' => $notifySlack,
'slack_webhook' => trim((string) $this->request->getPost('slack_webhook')) ?: null,
'is_active' => 1,
'is_muted_until' => null,
'created_by' => $userId,
]);
return redirect()->to('/alert')->with('success', 'Alert created.');
}
public function edit(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$charts = (new ChartModel())->forWorkspace($workspaceId);
return view('alert/edit', [
'title' => 'Edit alert | Chart-Board',
'alert' => $alert,
'charts' => $charts,
]);
}
public function update(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$rules = [
'name' => 'required|min_length[2]|max_length[200]',
'chart_id' => 'required|integer',
'metric_field' => 'required|max_length[150]',
'condition' => 'required|in_list[gt,lt,eq,gte,lte]',
'threshold' => 'required|decimal',
'check_interval' => 'permit_empty|integer',
'notify_email' => 'permit_empty|in_list[0,1]',
'notify_slack' => 'permit_empty|in_list[0,1]',
'email_addresses' => 'permit_empty|max_length[2000]',
'slack_webhook' => 'permit_empty|max_length[500]',
'is_active' => 'permit_empty|in_list[0,1]',
];
if (! $this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$chartId = (int) $this->request->getPost('chart_id');
$chart = (new ChartModel())->where('workspace_id', $workspaceId)->find($chartId);
if (! $chart) {
return redirect()->back()->withInput()->with('error', 'Chart not found.');
}
$notifyEmail = (int) $this->request->getPost('notify_email') === 1 ? 1 : 0;
$notifySlack = (int) $this->request->getPost('notify_slack') === 1 ? 1 : 0;
$isActive = (int) $this->request->getPost('is_active') === 1 ? 1 : 0;
$model->update($id, [
'chart_id' => $chartId,
'name' => strip_tags((string) $this->request->getPost('name')),
'metric_field' => trim((string) $this->request->getPost('metric_field')),
'condition' => (string) $this->request->getPost('condition'),
'threshold' => (float) $this->request->getPost('threshold'),
'check_interval' => max(1, (int) ($this->request->getPost('check_interval') ?: 15)),
'notify_email' => $notifyEmail,
'email_addresses' => trim((string) $this->request->getPost('email_addresses')) ?: null,
'notify_slack' => $notifySlack,
'slack_webhook' => trim((string) $this->request->getPost('slack_webhook')) ?: null,
'is_active' => $isActive,
]);
return redirect()->back()->with('success', 'Alert updated.');
}
public function delete(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$model->delete($id);
return redirect()->to('/alert')->with('success', 'Alert deleted.');
}
public function mute(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$hours = (int) $this->request->getPost('hours');
if (! in_array($hours, [1, 4, 24], true)) {
$hours = 1;
}
$until = date('Y-m-d H:i:s', time() + $hours * 3600);
$model->update($id, ['is_muted_until' => $until]);
return redirect()->back()->with('success', 'Alert muted for ' . $hours . ' hour(s).');
}
public function unmute(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$model->update($id, ['is_muted_until' => null]);
return redirect()->back()->with('success', 'Mute cleared.');
}
public function history(int $id)
{
$workspaceId = (int) $this->session->get('active_workspace_id');
$model = new AlertModel();
$alert = $model->where('workspace_id', $workspaceId)->find($id);
if (! $alert) {
return redirect()->to('/alert')->with('error', 'Alert not found.');
}
$page = max(1, (int) $this->request->getGet('page'));
$perPage = 25;
$offset = ($page - 1) * $perPage;
$histModel = new AlertHistoryModel();
$rows = $histModel->forAlert($id, $perPage, $offset);
$total = $histModel->countForAlert($id);
return view('alert/history', [
'title' => 'Alert history | Chart-Board',
'alert' => $alert,
'history' => $rows,
'page' => $page,
'perPage' => $perPage,
'total' => $total,
]);
}
}