adding new features
Deploy / deploy (push) Successful in 13s

This commit is contained in:
2026-05-16 12:35:01 +02:00
parent fa559ba4be
commit 0c3b75d7a8
5 changed files with 623 additions and 28 deletions
+12
View File
@@ -181,5 +181,17 @@ $this->pdo->exec("
created_at TEXT DEFAULT (datetime('now'))
)
");
$this->pdo->exec("
CREATE TABLE IF NOT EXISTS audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
action TEXT NOT NULL,
entity_type TEXT NOT NULL,
entity_id INTEGER,
details TEXT,
username TEXT,
created_at TEXT DEFAULT (datetime('now'))
)
");
}
}
+136 -13
View File
@@ -121,7 +121,7 @@ class Repository
return $row ? Alert::fromRow($row) : null;
}
public function getAlerts(int $limit = 100, int $offset = 0, ?string $status = null, ?string $severity = null): array
public function getAlerts(int $limit = 100, int $offset = 0, ?string $status = null, ?string $severity = null, ?string $since = null, ?string $until = null): array
{
$where = [];
$params = [];
@@ -134,6 +134,14 @@ class Repository
$where[] = 'severity = ?';
$params[] = $severity;
}
if ($since) {
$where[] = 'created_at >= ?';
$params[] = $since;
}
if ($until) {
$where[] = 'created_at <= ?';
$params[] = $until;
}
$sql = "SELECT * FROM alerts";
if ($where) {
@@ -187,29 +195,52 @@ class Repository
$stmt->execute([$line, $sourceId, $sourceName, $level]);
}
public function searchLogEntries(string $query, int $limit = 200, int $offset = 0): array
public function searchLogEntries(string $query, int $limit = 200, int $offset = 0, ?string $since = null, ?string $until = null): array
{
$query = trim($query);
if ($query === '') {
return [];
}
$where = [];
$params = [];
if ($since) {
$where[] = 'e.created_at >= ?';
$params[] = $since;
}
if ($until) {
$where[] = 'e.created_at <= ?';
$params[] = $until;
}
if ($query === '*') {
$stmt = $this->db->pdo()->prepare(
"SELECT * FROM log_entries ORDER BY created_at DESC LIMIT ? OFFSET ?"
);
$stmt->execute([$limit, $offset]);
$sql = "SELECT * FROM log_entries e";
if ($where) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$sql .= " ORDER BY e.created_at DESC LIMIT ? OFFSET ?";
$params[] = $limit;
$params[] = $offset;
$stmt = $this->db->pdo()->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
$like = $this->toLikePattern($query);
$stmt = $this->db->pdo()->prepare(
"SELECT e.* FROM log_entries e
WHERE e.line LIKE ?
ORDER BY e.created_at DESC
LIMIT ? OFFSET ?"
);
$stmt->execute([$like, $limit, $offset]);
$where[] = 'e.line LIKE ?';
$params[] = $like;
$sql = "SELECT e.* FROM log_entries e";
if ($where) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$sql .= " ORDER BY e.created_at DESC LIMIT ? OFFSET ?";
$params[] = $limit;
$params[] = $offset;
$stmt = $this->db->pdo()->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
@@ -338,4 +369,96 @@ class Repository
}
return false;
}
// --- Audit Log ---
public function logAudit(string $action, string $entityType, ?int $entityId = null, ?string $details = null, ?string $username = null): void
{
$stmt = $this->db->pdo()->prepare(
"INSERT INTO audit_log (action, entity_type, entity_id, details, username) VALUES (?, ?, ?, ?, ?)"
);
$stmt->execute([$action, $entityType, $entityId, $details, $username]);
}
public function getAuditLog(int $limit = 50): array
{
return $this->db->pdo()->prepare(
"SELECT * FROM audit_log ORDER BY created_at DESC LIMIT ?"
)->execute([$limit])->fetchAll();
}
// --- Retention ---
public function purgeOldData(int $logDays = 30, int $alertDays = 90): array
{
$deletedLogs = $this->db->pdo()->prepare(
"DELETE FROM log_entries WHERE created_at < datetime('now', ?)"
)->execute(['-' . $logDays . ' days'])->rowCount();
$deletedAlerts = $this->db->pdo()->prepare(
"DELETE FROM alerts WHERE status = 'resolved' AND created_at < datetime('now', ?)"
)->execute(['-' . $alertDays . ' days'])->rowCount();
$this->db->pdo()->exec("DELETE FROM rate_limiter WHERE window_start < " . (time() - 86400));
return ['log_entries_deleted' => $deletedLogs, 'alerts_deleted' => $deletedAlerts];
}
// --- Log Context ---
public function getLogContext(int $id, int $before = 5, int $after = 5): array
{
$beforeStmt = $this->db->pdo()->prepare(
"SELECT * FROM log_entries WHERE id < ? ORDER BY id DESC LIMIT ?"
);
$beforeStmt->execute([$id, $before]);
$beforeRows = array_reverse($beforeStmt->fetchAll());
$current = $this->db->pdo()->prepare("SELECT * FROM log_entries WHERE id = ?");
$current->execute([$id]);
$currentRow = $current->fetch();
$afterStmt = $this->db->pdo()->prepare(
"SELECT * FROM log_entries WHERE id > ? ORDER BY id ASC LIMIT ?"
);
$afterStmt->execute([$id, $after]);
$afterRows = $afterStmt->fetchAll();
return [
'before' => $beforeRows,
'current' => $currentRow,
'after' => $afterRows,
];
}
// --- Bulk Operations ---
public function bulkUpdateAlertStatus(array $ids, AlertStatus $status): int
{
if (empty($ids)) return 0;
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $this->db->pdo()->prepare(
"UPDATE alerts SET status = ? WHERE id IN ($placeholders)"
);
$stmt->execute(array_merge([$status->value], $ids));
return $stmt->rowCount();
}
public function exportAlerts(array $ids): array
{
if (empty($ids)) return [];
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $this->db->pdo()->prepare("SELECT * FROM alerts WHERE id IN ($placeholders) ORDER BY id");
$stmt->execute($ids);
return array_map(fn(array $r) => Alert::fromRow($r), $stmt->fetchAll());
}
public function exportLogs(array $ids): array
{
if (empty($ids)) return [];
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $this->db->pdo()->prepare("SELECT * FROM log_entries WHERE id IN ($placeholders) ORDER BY id");
$stmt->execute($ids);
return $stmt->fetchAll();
}
}