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

@@ -16,7 +16,8 @@ final readonly class DependencyAnalysisResult
private DependencyGraph $graph,
private array $circularDependencies,
private array $statistics
) {}
) {
}
/**
* Get the dependency graph
@@ -51,7 +52,7 @@ final readonly class DependencyAnalysisResult
*/
public function hasCircularDependencies(): bool
{
return !empty($this->circularDependencies);
return ! empty($this->circularDependencies);
}
/**
@@ -77,4 +78,4 @@ final readonly class DependencyAnalysisResult
'graph' => $this->graph->toArray(),
];
}
}
}

View File

@@ -10,15 +10,13 @@ use App\Framework\Discovery\ValueObjects\DependencyGraph;
use App\Framework\Discovery\ValueObjects\DependencyNode;
use App\Framework\Discovery\ValueObjects\DependencyRelation;
use App\Framework\Discovery\ValueObjects\DependencyType;
use App\Framework\Reflection\ReflectionProvider;
use App\Framework\Logging\Logger;
use App\Framework\Logging\ValueObjects\LogContext;
use App\Framework\Reflection\ReflectionProvider;
use App\Framework\Reflection\WrappedReflectionClass;
use ReflectionClass;
use ReflectionMethod;
use ReflectionParameter;
use ReflectionProperty;
use ReflectionException;
use ReflectionMethod;
use ReflectionProperty;
use Throwable;
final readonly class DependencyAnalyzer
@@ -26,7 +24,8 @@ final readonly class DependencyAnalyzer
public function __construct(
private ReflectionProvider $reflectionProvider,
private ?Logger $logger = null
) {}
) {
}
/**
* Analyze dependencies for a list of classes
@@ -373,13 +372,13 @@ final readonly class DependencyAnalyzer
}
}
if (!empty($highComplexityNodes)) {
if (! empty($highComplexityNodes)) {
$recommendations['high_complexity'] = $highComplexityNodes;
}
// Check for circular dependencies
$circularDependencies = $graph->findCircularDependencies();
if (!empty($circularDependencies)) {
if (! empty($circularDependencies)) {
$recommendations['circular_dependencies'] = [
'count' => count($circularDependencies),
'cycles' => $circularDependencies,
@@ -389,9 +388,9 @@ final readonly class DependencyAnalyzer
// Check for highly coupled classes
$highDependencyNodes = $graph->getHighestDependencyNodes(5);
if (!empty($highDependencyNodes)) {
if (! empty($highDependencyNodes)) {
$recommendations['high_dependencies'] = array_map(
fn(DependencyNode $node) => [
fn (DependencyNode $node) => [
'class' => $node->getClassName()->getShortName(),
'dependency_count' => $node->getDependencyCount(),
'suggestion' => 'Consider using dependency injection or factory patterns',
@@ -403,12 +402,12 @@ final readonly class DependencyAnalyzer
// Check for unused classes (leaf nodes with no dependents)
$unusedClasses = array_filter(
$graph->getLeafNodes(),
fn(DependencyNode $node) => $node->getDependentCount() === 0
fn (DependencyNode $node) => $node->getDependentCount() === 0
);
if (!empty($unusedClasses)) {
if (! empty($unusedClasses)) {
$recommendations['potentially_unused'] = array_map(
fn(DependencyNode $node) => [
fn (DependencyNode $node) => [
'class' => $node->getClassName()->getShortName(),
'suggestion' => 'Consider removing if truly unused',
],
@@ -433,24 +432,26 @@ final readonly class DependencyAnalyzer
if ($type instanceof \ReflectionUnionType) {
$types = [];
foreach ($type->getTypes() as $subType) {
if ($subType instanceof \ReflectionNamedType && !$subType->isBuiltin()) {
if ($subType instanceof \ReflectionNamedType && ! $subType->isBuiltin()) {
$types[] = $subType->getName();
}
}
return $types;
}
if ($type instanceof \ReflectionIntersectionType) {
$types = [];
foreach ($type->getTypes() as $subType) {
if ($subType instanceof \ReflectionNamedType && !$subType->isBuiltin()) {
if ($subType instanceof \ReflectionNamedType && ! $subType->isBuiltin()) {
$types[] = $subType->getName();
}
}
return $types;
}
// Fallback for unknown types
return [];
}
}
}