feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -45,21 +45,22 @@ final readonly class RouteInspector
$controller = $route->controller ?? null;
$action = $route->action ?? null;
if (!is_string($controller) || $controller === '' || !class_exists($controller)) {
if (! is_string($controller) || $controller === '' || ! class_exists($controller)) {
$issues[] = $this->issue('controller_missing', 'error', $method, $subdomain, $path, $routeName, "Controller class not found or invalid: " . var_export($controller, true));
continue; // skip further checks for this route
}
// Action existence and visibility
if (!is_string($action) || $action === '') {
if (! is_string($action) || $action === '') {
$issues[] = $this->issue('action_missing', 'error', $method, $subdomain, $path, $routeName, 'Action method not defined or invalid');
} else {
$refClass = new ReflectionClass($controller);
if (!$refClass->hasMethod($action)) {
if (! $refClass->hasMethod($action)) {
$issues[] = $this->issue('action_missing', 'error', $method, $subdomain, $path, $routeName, "Action method '{$action}' not found in {$controller}");
} else {
$refMethod = $refClass->getMethod($action);
if (!$refMethod->isPublic()) {
if (! $refMethod->isPublic()) {
$issues[] = $this->issue('action_not_public', 'warning', $method, $subdomain, $path, $routeName, "Action method '{$action}' is not public");
}
// Parameter consistency check (placeholders vs method signature)
@@ -109,11 +110,11 @@ final readonly class RouteInspector
$keys = array_keys($route->parameters);
$expected = array_values(array_filter(
count($keys) !== count($route->parameters) ? $route->parameters : $keys,
fn($v) => is_string($v) && $v !== ''
fn ($v) => is_string($v) && $v !== ''
));
} else {
$expected = array_map(
static fn(\ReflectionParameter $p) => $p->getName(),
static fn (\ReflectionParameter $p) => $p->getName(),
$refMethod->getParameters()
);
}
@@ -124,7 +125,7 @@ final readonly class RouteInspector
// Missing placeholders in path for expected parameters
$missingInPath = array_values(array_diff($expectedSet, $pathSet));
if (!empty($missingInPath)) {
if (! empty($missingInPath)) {
$issues[] = $this->issue(
'param_mismatch',
'warning',
@@ -138,7 +139,7 @@ final readonly class RouteInspector
// Extra placeholders not expected by the action
$extraInPath = array_values(array_diff($pathSet, $expectedSet));
if (!empty($extraInPath)) {
if (! empty($extraInPath)) {
$issues[] = $this->issue(
'param_mismatch',
'warning',
@@ -162,7 +163,7 @@ final readonly class RouteInspector
foreach ($namedRoutes as $name => $route) {
// Minimal: ensure a path exists
$path = $route->path ?? null;
if (!is_string($path) || $path === '') {
if (! is_string($path) || $path === '') {
$issues[] = [
'type' => 'invalid_named_route',
'severity' => 'error',