Initial commit - SOGOMS v1.0.0

- sogoctl: supervisor avec health checks et restart auto
- sogoway: gateway HTTP, auth JWT, routing par hostname
- sogoms-db: microservice MariaDB avec pool par application
- Protocol IPC Unix socket JSON length-prefixed
- Config YAML multi-application (prokov)
- Deploy script pour container Alpine gw3

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-15 19:09:00 +01:00
commit 7e27f87d6f
64 changed files with 7951 additions and 0 deletions

View File

@@ -0,0 +1,145 @@
<?php
/**
* Routeur simple pour API REST
*/
declare(strict_types=1);
class Router
{
private array $routes = [];
private Request $request;
public function __construct()
{
$this->request = new Request();
$this->registerRoutes();
}
private function registerRoutes(): void
{
// Auth (routes publiques)
$this->post('/auth/register', 'AuthController@register');
$this->post('/auth/login', 'AuthController@login');
$this->post('/auth/logout', 'AuthController@logout');
$this->get('/auth/me', 'AuthController@me');
// Projects
$this->get('/projects', 'ProjectController@index');
$this->get('/projects/{id}', 'ProjectController@show');
$this->post('/projects', 'ProjectController@store');
$this->put('/projects/{id}', 'ProjectController@update');
$this->delete('/projects/{id}', 'ProjectController@destroy');
// Tasks
$this->get('/tasks', 'TaskController@index');
$this->get('/tasks/{id}', 'TaskController@show');
$this->post('/tasks', 'TaskController@store');
$this->put('/tasks/{id}', 'TaskController@update');
$this->delete('/tasks/{id}', 'TaskController@destroy');
// Tags
$this->get('/tags', 'TagController@index');
$this->get('/tags/{id}', 'TagController@show');
$this->post('/tags', 'TagController@store');
$this->put('/tags/{id}', 'TagController@update');
$this->delete('/tags/{id}', 'TagController@destroy');
// Statuses
$this->get('/statuses', 'StatusController@index');
$this->get('/statuses/{id}', 'StatusController@show');
$this->post('/statuses', 'StatusController@store');
$this->put('/statuses/{id}', 'StatusController@update');
$this->delete('/statuses/{id}', 'StatusController@destroy');
}
private function addRoute(string $method, string $path, string $handler): void
{
$this->routes[] = [
'method' => $method,
'path' => $path,
'handler' => $handler,
];
}
public function get(string $path, string $handler): void
{
$this->addRoute('GET', $path, $handler);
}
public function post(string $path, string $handler): void
{
$this->addRoute('POST', $path, $handler);
}
public function put(string $path, string $handler): void
{
$this->addRoute('PUT', $path, $handler);
}
public function delete(string $path, string $handler): void
{
$this->addRoute('DELETE', $path, $handler);
}
public function dispatch(): void
{
$method = $this->request->getMethod();
$uri = $this->request->getUri();
foreach ($this->routes as $route) {
if ($route['method'] !== $method) {
continue;
}
$params = $this->matchRoute($route['path'], $uri);
if ($params !== false) {
$this->request->setParams($params);
$this->callHandler($route['handler']);
return;
}
}
Response::notFound('Route not found');
}
private function matchRoute(string $routePath, string $uri): array|false
{
// Convertir /projects/{id} en regex /projects/([^/]+)
$pattern = preg_replace('#\{(\w+)\}#', '([^/]+)', $routePath);
$pattern = '#^' . $pattern . '$#';
if (preg_match($pattern, $uri, $matches)) {
array_shift($matches); // Retirer le match complet
// Extraire les noms des paramètres
preg_match_all('#\{(\w+)\}#', $routePath, $paramNames);
$params = [];
foreach ($paramNames[1] as $index => $name) {
$params[$name] = $matches[$index] ?? null;
}
return $params;
}
return false;
}
private function callHandler(string $handler): void
{
[$controllerName, $methodName] = explode('@', $handler);
if (!class_exists($controllerName)) {
Response::error("Controller {$controllerName} not found", 500);
}
$controller = new $controllerName($this->request);
if (!method_exists($controller, $methodName)) {
Response::error("Method {$methodName} not found", 500);
}
$controller->$methodName();
}
}