initial commit

This commit is contained in:
2026-05-06 11:28:41 +02:00
commit 39ee31debb
23 changed files with 1645 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
<?php
namespace Jakach\Logging\Api;
use Jakach\Logging\Model\{LogSourceType, AlertStatus};
use Jakach\Logging\Storage\{Database, Repository};
class Router
{
private Repository $repo;
public function __construct()
{
$db = new Database();
$this->repo = new Repository($db);
}
public function handle(): void
{
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$path = rtrim($path, '/');
header('Content-Type: application/json');
try {
$result = match (true) {
$path === '/sources' && $method === 'GET' => $this->repo->getSources(),
$path === '/sources' && $method === 'POST' => $this->createSource(),
$path === '/rules' && $method === 'GET' => $this->repo->getRules(),
$path === '/rules' && $method === 'POST' => $this->createRule(),
$path === '/alerts' && $method === 'GET' => $this->getAlerts(),
preg_match('#^/alerts/(\d+)/ack$#', $path, $m) && $method === 'POST' => $this->ackAlert((int) $m[1]),
preg_match('#^/alerts/counts$#', $path) && $method === 'GET' => $this->repo->getAlertCounts(),
$path === '/health' && $method === 'GET' => ['status' => 'ok'],
default => throw new \RuntimeException('Not found', 404),
};
if ($result instanceof \UnitEnum || is_scalar($result)) {
$result = ['data' => $result];
} elseif (is_array($result) && !empty($result) && $result[array_key_first($result)] instanceof \UnitEnum) {
$result = ['data' => $result];
} elseif (is_array($result)) {
$needsWrap = false;
foreach ($result as $key => $val) {
if (is_object($val) && method_exists($val, 'toArray')) {
$result[$key] = $val->toArray();
} else {
$needsWrap = true;
}
}
if ($needsWrap || empty($result)) {
$result = ['data' => $result];
}
} elseif (is_object($result) && method_exists($result, 'toArray')) {
$result = ['data' => $result->toArray()];
}
http_response_code(200);
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
} catch (\RuntimeException $e) {
http_response_code($e->getCode() ?: 500);
echo json_encode(['error' => $e->getMessage()]);
}
}
private function createSource(): array
{
$body = json_decode(file_get_contents('php://input'), true);
$type = LogSourceType::from($body['type'] ?? '');
return $this->repo->createSource(
name: $body['name'],
type: $type,
address: $body['address'],
labels: $body['labels'] ?? [],
);
}
private function createRule(): array
{
$body = json_decode(file_get_contents('php://input'), true);
return $this->repo->createRule(
name: $body['name'],
pattern: $body['pattern'],
severity: $body['severity'] ?? 'warning',
rateLimitSeconds: $body['rate_limit_seconds'] ?? null,
);
}
private function getAlerts(): array
{
$limit = (int) ($_GET['limit'] ?? 100);
$offset = (int) ($_GET['offset'] ?? 0);
$status = $_GET['status'] ?? null;
$severity = $_GET['severity'] ?? null;
return $this->repo->getAlerts($limit, $offset, $status, $severity);
}
private function ackAlert(int $id): array
{
$this->repo->updateAlertStatus($id, AlertStatus::Acknowledged);
return ['status' => 'acknowledged', 'id' => $id];
}
}