docs: consolidate documentation into organized structure

- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
This commit is contained in:
2025-10-05 11:05:04 +02:00
parent 887847dde6
commit 5050c7d73a
36686 changed files with 196456 additions and 12398919 deletions

View File

@@ -0,0 +1,252 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Discovery\Analysis\DependencyAnalyzer;
use App\Framework\Discovery\Plugins\DependencyAnalysisPlugin;
use App\Framework\Reflection\CachedReflectionProvider;
use App\Framework\Core\ValueObjects\ClassName;
echo "=== Testing Dependency Graph Analysis System ===\n\n";
$reflectionProvider = new CachedReflectionProvider();
echo "1. Testing DependencyAnalyzer with sample framework classes:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Test with simpler, existing classes first
$classesToAnalyze = [
'App\\Framework\\Core\\ValueObjects\\ClassName',
'App\\Framework\\Http\\Method',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\Placeholder',
];
echo " 🔍 Analyzing classes: " . implode(', ', array_map(fn($c) => basename(str_replace('\\', '/', $c)), $classesToAnalyze)) . "\n";
$analysisResult = $analyzer->analyzeWithCircularDetection($classesToAnalyze);
$graph = $analysisResult->getGraph();
$statistics = $analysisResult->getStatistics();
echo " ✅ Analysis completed successfully\n";
echo " 📊 Statistics:\n";
echo " • Total nodes: {$statistics['node_count']}\n";
echo " • Total edges: {$statistics['edge_count']}\n";
echo " • Circular dependencies: {$statistics['circular_dependencies']}\n";
echo " • Leaf nodes: {$statistics['leaf_nodes']}\n";
echo " • Root nodes: {$statistics['root_nodes']}\n";
echo " • Average complexity: {$statistics['average_complexity']}\n";
echo " • Max dependencies: {$statistics['max_dependency_count']}\n\n";
echo " 📈 Type distribution:\n";
foreach ($statistics['type_distribution'] as $type => $count) {
echo "{$type}: {$count}\n";
}
echo "\n";
if ($analysisResult->hasCircularDependencies()) {
echo " ⚠️ Circular dependencies found:\n";
foreach ($analysisResult->getCircularDependencies() as $cycle) {
echo "" . implode(' -> ', $cycle) . "\n";
}
echo "\n";
} else {
echo " ✅ No circular dependencies found\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "2. Testing specific class analysis (DefaultContainer):\n";
try {
$containerClass = 'App\\Framework\\DI\\DefaultContainer';
$analyzer = new DependencyAnalyzer($reflectionProvider);
$analysisResult = $analyzer->analyzeWithCircularDetection([$containerClass]);
$graph = $analysisResult->getGraph();
$node = $graph->getNode(ClassName::create($containerClass));
if ($node !== null) {
echo " ✅ DefaultContainer analysis:\n";
echo " • Type: {$node->getType()->value}\n";
echo " • Dependencies: {$node->getDependencyCount()}\n";
echo " • Dependents: {$node->getDependentCount()}\n";
echo " • Complexity score: " . round($node->getComplexityScore(), 2) . "\n";
echo " • Is leaf: " . ($node->isLeaf() ? 'Yes' : 'No') . "\n";
echo " • Is root: " . ($node->isRoot() ? 'Yes' : 'No') . "\n\n";
if (!empty($node->getDependencies())) {
echo " 📋 Dependencies:\n";
foreach ($node->getDependencies() as $edge) {
echo "{$edge->getTarget()->getShortName()} ({$edge->getRelation()->value}, weight: {$edge->getWeight()})\n";
}
echo "\n";
}
// Test dependency depth
$depth = $graph->getDependencyDepth($node->getClassName());
echo " 📏 Dependency depth: {$depth}\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "3. Testing dependency recommendations:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Analyze a larger set of framework classes
$frameworkClasses = [
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\RouteGroup',
'App\\Framework\\TypeCaster\\TypeCasterRegistry',
'App\\Framework\\Discovery\\UnifiedDiscoveryService',
'App\\Framework\\Core\\Application',
'App\\Framework\\Http\\Request',
'App\\Framework\\Database\\EntityManager',
];
$analysisResult = $analyzer->analyzeWithCircularDetection($frameworkClasses);
$recommendations = $analyzer->getRecommendations($analysisResult->getGraph());
echo " 📝 Recommendations:\n";
if (isset($recommendations['high_complexity'])) {
echo " 🔺 High Complexity Classes:\n";
foreach ($recommendations['high_complexity'] as $item) {
echo "{$item['class']}: {$item['current']} (expected max: {$item['expected_max']})\n";
echo " {$item['suggestion']}\n";
}
echo "\n";
}
if (isset($recommendations['high_dependencies'])) {
echo " 🔗 High Dependency Classes:\n";
foreach ($recommendations['high_dependencies'] as $item) {
echo "{$item['class']}: {$item['dependency_count']} dependencies\n";
echo " {$item['suggestion']}\n";
}
echo "\n";
}
if (isset($recommendations['circular_dependencies'])) {
echo " 🔄 Circular Dependencies:\n";
echo " • Count: {$recommendations['circular_dependencies']['count']}\n";
echo "{$recommendations['circular_dependencies']['suggestion']}\n";
foreach ($recommendations['circular_dependencies']['cycles'] as $cycle) {
echo " Cycle: " . implode(' -> ', $cycle) . "\n";
}
echo "\n";
}
if (isset($recommendations['potentially_unused'])) {
echo " 🗑️ Potentially Unused Classes:\n";
foreach ($recommendations['potentially_unused'] as $item) {
echo "{$item['class']}: {$item['suggestion']}\n";
}
echo "\n";
}
if (empty($recommendations)) {
echo " ✅ No major issues found!\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "4. Testing dependency path finding:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
$analysisResult = $analyzer->analyzeWithCircularDetection([
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Reflection\\ReflectionProvider',
'App\\Framework\\Reflection\\CachedReflectionProvider',
]);
$graph = $analysisResult->getGraph();
$fromClass = ClassName::create('App\\Framework\\DI\\DefaultContainer');
$toClass = ClassName::create('App\\Framework\\Reflection\\ReflectionProvider');
$path = $graph->getDependencyPath($fromClass, $toClass);
if ($path !== null) {
echo " ✅ Dependency path found:\n";
echo " 📍 From: {$fromClass->getShortName()}\n";
echo " 📍 To: {$toClass->getShortName()}\n";
echo " 🛤️ Path: " . implode(' -> ', array_map(fn($class) => basename(str_replace('\\', '/', $class)), $path)) . "\n";
echo " 📏 Length: " . count($path) . "\n\n";
} else {
echo " No dependency path found between DefaultContainer and ReflectionProvider\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "5. Testing graph statistics and analysis:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Test with more comprehensive class set
$allClasses = [
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\RouteGroup',
'App\\Framework\\Router\\ValueObjects\\GroupRoute',
'App\\Framework\\TypeCaster\\TypeCasterRegistry',
'App\\Framework\\Core\\ValueObjects\\ClassName',
'App\\Framework\\Http\\Method',
];
$analysisResult = $analyzer->analyzeWithCircularDetection($allClasses);
$graph = $analysisResult->getGraph();
echo " 📊 Detailed Graph Analysis:\n";
// Top complex nodes
$topComplex = $graph->getHighestDependencyNodes(3);
echo " 🔺 Most Complex Classes:\n";
foreach ($topComplex as $node) {
echo "{$node->getClassName()->getShortName()}: complexity {$node->getComplexityScore()}\n";
}
echo "\n";
// Most used nodes
$mostUsed = $graph->getMostUsedNodes(3);
echo " 🌟 Most Used Classes:\n";
foreach ($mostUsed as $node) {
echo "{$node->getClassName()->getShortName()}: {$node->getDependentCount()} dependents\n";
}
echo "\n";
// Leaf nodes
$leafNodes = $graph->getLeafNodes();
echo " 🍃 Leaf Nodes (no dependencies):\n";
foreach (array_slice($leafNodes, 0, 5) as $node) {
echo "{$node->getClassName()->getShortName()} ({$node->getType()->value})\n";
}
echo "\n";
// Root nodes
$rootNodes = $graph->getRootNodes();
echo " 🌳 Root Nodes (no dependents):\n";
foreach (array_slice($rootNodes, 0, 5) as $node) {
echo "{$node->getClassName()->getShortName()} ({$node->getType()->value})\n";
}
echo "\n";
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "=== Dependency Graph Analysis Test Completed ===\n";