Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
568 lines
15 KiB
Markdown
568 lines
15 KiB
Markdown
# Custom PHP Framework - Source Code Architecture Analysis
|
|
|
|
**Analysis Date**: 2025-01-28
|
|
**Project**: Custom PHP Framework
|
|
**Analysis Scope**: Complete `src/` directory structure
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
**Overall Assessment**: Grade C+ (75%) - "Good foundation with critical architectural flaws"
|
|
|
|
**Key Metrics**:
|
|
- **Total Files**: 4,551 PHP files
|
|
- **Total Directories**: 1,052 directories
|
|
- **Framework Layer**: 85.3% (3,883 files) - **TOO LARGE**
|
|
- **Application Layer**: 9.2% (420 files)
|
|
- **Domain Layer**: 4.0% (184 files) - **TOO THIN**
|
|
- **Infrastructure Layer**: 1.5% (64 files)
|
|
|
|
**Critical Issues Identified**: 3 architectural violations requiring immediate attention
|
|
|
|
---
|
|
|
|
## Layer Distribution Analysis
|
|
|
|
### Current Distribution
|
|
|
|
| Layer | Files | Percentage | Expected | Status |
|
|
|-------|-------|------------|----------|--------|
|
|
| Framework | 3,883 | 85.3% | 40-50% | ❌ TOO LARGE |
|
|
| Application | 420 | 9.2% | 25-35% | ⚠️ BELOW TARGET |
|
|
| Domain | 184 | 4.0% | 20-30% | ❌ TOO THIN |
|
|
| Infrastructure | 64 | 1.5% | 5-10% | ⚠️ BELOW TARGET |
|
|
|
|
**Problem**: The Framework layer has absorbed too much application and domain logic, violating Clean Architecture principles.
|
|
|
|
---
|
|
|
|
## Critical Architectural Violations (Priority 1)
|
|
|
|
### 1. HTTP Layer in Domain Layer
|
|
|
|
**Location**: `src/Domain/Meta/Http/`
|
|
|
|
**Files**:
|
|
- `Controller/MetaAdminController.php` (406 lines)
|
|
- `Middleware/MetaMiddleware.php` (106 lines)
|
|
|
|
**Issue**: Domain layer contains HTTP-specific code (controllers with `#[Route]` attributes, HTTP middleware)
|
|
|
|
**Example Violation**:
|
|
```php
|
|
// src/Domain/Meta/Http/Controller/MetaAdminController.php
|
|
namespace App\Domain\Meta\Http\Controller;
|
|
|
|
use App\Framework\Attributes\Route;
|
|
use App\Framework\Http\Method;
|
|
|
|
final readonly class MetaAdminController
|
|
{
|
|
#[Route(path: '/admin/meta', method: Method::GET)]
|
|
public function index(): ViewResult
|
|
{
|
|
// Controller in Domain layer - WRONG!
|
|
}
|
|
}
|
|
```
|
|
|
|
**Fix**: Move to Application layer
|
|
```
|
|
src/Domain/Meta/Http/Controller/MetaAdminController.php
|
|
→ src/Application/Admin/Controllers/Meta/MetaAdminController.php
|
|
|
|
src/Domain/Meta/Http/Middleware/MetaMiddleware.php
|
|
→ src/Framework/Http/Middlewares/MetaMiddleware.php
|
|
OR src/Application/Middleware/MetaMiddleware.php
|
|
```
|
|
|
|
**Impact**: HIGH - Violates Dependency Inversion Principle, breaks Clean Architecture
|
|
|
|
---
|
|
|
|
### 2. DI Container Setup in Domain Layer
|
|
|
|
**Locations**: Multiple domains contain DI initializers
|
|
|
|
**Files**:
|
|
1. `src/Domain/Asset/DI/AssetServiceInitializer.php` (124 lines)
|
|
2. `src/Domain/Cms/DI/CmsServiceInitializer.php` (89 lines)
|
|
3. `src/Domain/Console/DI/ConsoleServiceInitializer.php` (67 lines)
|
|
4. `src/Domain/User/DI/UserServiceInitializer.php` (156 lines)
|
|
5. `src/Domain/Order/DI/OrderServiceInitializer.php` (201 lines)
|
|
|
|
**Issue**: Domain layer contains framework-specific dependency injection setup
|
|
|
|
**Example Violation**:
|
|
```php
|
|
// src/Domain/Asset/DI/AssetServiceInitializer.php
|
|
namespace App\Domain\Asset\DI;
|
|
|
|
use App\Framework\DI\Container;
|
|
use App\Framework\DI\Initializer;
|
|
|
|
final readonly class AssetServiceInitializer
|
|
{
|
|
#[Initializer]
|
|
public function __invoke(Container $container): void
|
|
{
|
|
// DI configuration in Domain - WRONG!
|
|
$container->singleton(AssetRepository::class, ...);
|
|
$container->singleton(AssetService::class, ...);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Fix**: Move to Infrastructure layer
|
|
```
|
|
src/Domain/*/DI/*ServiceInitializer.php
|
|
→ src/Infrastructure/ServiceProviders/*ServiceProvider.php
|
|
```
|
|
|
|
**Recommended Structure**:
|
|
```
|
|
src/Infrastructure/ServiceProviders/
|
|
├── AssetServiceProvider.php
|
|
├── CmsServiceProvider.php
|
|
├── ConsoleServiceProvider.php
|
|
├── UserServiceProvider.php
|
|
└── OrderServiceProvider.php
|
|
```
|
|
|
|
**Impact**: HIGH - Violates Dependency Rule (Domain depends on Framework)
|
|
|
|
---
|
|
|
|
### 3. Infrastructure Nested in Application Layer
|
|
|
|
**Location**: `src/Application/Website/Infrastructure/GeoIp/`
|
|
|
|
**Issue**: Infrastructure layer nested inside Application layer - wrong dependency direction
|
|
|
|
**Files**:
|
|
- `GeoIpService.php`
|
|
- `GeoIpProvider.php`
|
|
- `MaxMindProvider.php`
|
|
|
|
**Fix**: Move to top-level Infrastructure
|
|
```
|
|
src/Application/Website/Infrastructure/GeoIp/
|
|
→ src/Infrastructure/GeoIp/
|
|
```
|
|
|
|
**Impact**: MEDIUM - Confusing architecture, but less critical than Domain violations
|
|
|
|
---
|
|
|
|
## Structural Issues (Priority 2)
|
|
|
|
### 1. Naming Inconsistencies
|
|
|
|
**Problem**: Mix of singular and plural directory names
|
|
|
|
**Examples**:
|
|
```
|
|
src/Domain/User/ (singular)
|
|
src/Domain/Users/ (plural - inconsistent)
|
|
|
|
src/Application/Admin/Controllers/ (plural)
|
|
src/Application/Admin/Controller/ (singular - inconsistent)
|
|
```
|
|
|
|
**Recommendation**: Standardize on **singular** naming throughout
|
|
- `src/Domain/User/` ✅
|
|
- `src/Domain/Asset/` ✅
|
|
- `src/Application/Admin/Controller/` ✅
|
|
|
|
---
|
|
|
|
### 2. PSR-4 Violations
|
|
|
|
**Problem**: Namespace mismatches with directory structure
|
|
|
|
**Examples**:
|
|
```php
|
|
// File: src/Framework/Mcp/Tools/Categories/Analysis/DependencyAnalysisTools.php
|
|
namespace App\Framework\Mcp\Tools\Categories\Analysis;
|
|
// ✅ Correct PSR-4
|
|
|
|
// File: src/Domain/Meta/Http/Controller/MetaAdminController.php
|
|
namespace App\Domain\Meta\Http\Controller;
|
|
// ❌ Incorrect - should not be in Domain
|
|
```
|
|
|
|
**Recommendation**: After moving files per Priority 1 fixes, verify all namespaces match PSR-4
|
|
|
|
---
|
|
|
|
### 3. Deep Nesting (11 levels)
|
|
|
|
**Problem**: Some directories nested too deeply
|
|
|
|
**Example**:
|
|
```
|
|
src/Framework/View/Components/Admin/Dashboard/Widgets/Analytics/Reports/
|
|
```
|
|
|
|
**Impact**: Reduced readability, harder navigation
|
|
|
|
**Recommendation**: Flatten to max 5-6 levels where possible
|
|
|
|
---
|
|
|
|
## Framework Layer Analysis
|
|
|
|
### Size Problem
|
|
|
|
**Current State**: 85.3% of codebase (3,883 files)
|
|
|
|
**Breakdown**:
|
|
```
|
|
src/Framework/
|
|
├── Core/ (245 files)
|
|
├── Database/ (387 files)
|
|
├── Http/ (156 files)
|
|
├── Queue/ (89 files)
|
|
├── Cache/ (67 files)
|
|
├── ExceptionHandling/ (124 files)
|
|
├── Discovery/ (78 files)
|
|
├── View/ (201 files)
|
|
└── [36 more directories]
|
|
```
|
|
|
|
**Issue**: Framework has absorbed too much application-specific logic
|
|
|
|
**Recommendation**: Extract application-specific code from Framework
|
|
- Move application logic to `Application/` layer
|
|
- Keep only reusable framework components in `Framework/`
|
|
- Target: Reduce Framework to 40-50% of codebase
|
|
|
|
---
|
|
|
|
## Domain Layer Analysis
|
|
|
|
### Thinness Problem
|
|
|
|
**Current State**: 4.0% of codebase (184 files) - **TOO THIN**
|
|
|
|
**Breakdown**:
|
|
```
|
|
src/Domain/
|
|
├── User/ (23 files)
|
|
├── Asset/ (18 files)
|
|
├── Cms/ (15 files)
|
|
├── Order/ (29 files)
|
|
├── Product/ (12 files)
|
|
├── Console/ (11 files)
|
|
├── Meta/ (34 files) - includes HTTP violations
|
|
└── [5 more domains]
|
|
```
|
|
|
|
**Issue**: Domain layer is underdeveloped - missing core business logic
|
|
|
|
**Missing Components**:
|
|
- **Value Objects**: Email, OrderId, ProductSku, etc.
|
|
- **Domain Events**: OrderPlacedEvent, UserRegisteredEvent, etc.
|
|
- **Aggregates**: Order with OrderItems, User with Profile, etc.
|
|
- **Domain Services**: PricingService, DiscountCalculator, etc.
|
|
|
|
**Recommendation**: Strengthen Domain layer
|
|
- Extract business logic from Application/Framework
|
|
- Create Value Objects for all domain concepts
|
|
- Implement Domain Events for significant state changes
|
|
- Build proper Aggregates with invariants
|
|
- Target: Increase to 20-30% of codebase
|
|
|
|
---
|
|
|
|
## Application Layer Analysis
|
|
|
|
**Current State**: 9.2% of codebase (420 files)
|
|
|
|
**Breakdown**:
|
|
```
|
|
src/Application/
|
|
├── Website/ (89 files)
|
|
├── Admin/ (234 files)
|
|
├── Api/ (67 files)
|
|
├── Contact/ (8 files)
|
|
└── Console/ (22 files)
|
|
```
|
|
|
|
**Issues**:
|
|
1. **Infrastructure nested inside** (`Website/Infrastructure/GeoIp/`)
|
|
2. **Admin section dominates** (234 files = 56% of Application layer)
|
|
|
|
**Recommendations**:
|
|
1. Move Infrastructure to top-level
|
|
2. Consider splitting Admin into sub-applications:
|
|
```
|
|
src/Application/Admin/
|
|
├── Analytics/
|
|
├── Content/
|
|
├── Infrastructure/
|
|
├── Notifications/
|
|
└── System/
|
|
```
|
|
|
|
---
|
|
|
|
## Proposed Target Structure
|
|
|
|
### Ideal Layer Distribution
|
|
|
|
```
|
|
src/
|
|
├── Domain/ (20-30% - business logic)
|
|
│ ├── User/
|
|
│ │ ├── Entity/ (User.php)
|
|
│ │ ├── ValueObject/ (Email.php, UserId.php)
|
|
│ │ ├── Event/ (UserRegisteredEvent.php)
|
|
│ │ ├── Repository/ (UserRepositoryInterface.php)
|
|
│ │ └── Service/ (UserService.php)
|
|
│ ├── Order/
|
|
│ └── Product/
|
|
│
|
|
├── Application/ (25-35% - use cases)
|
|
│ ├── Website/
|
|
│ │ ├── Controller/
|
|
│ │ ├── Command/
|
|
│ │ └── Query/
|
|
│ ├── Admin/
|
|
│ │ ├── Analytics/
|
|
│ │ ├── Content/
|
|
│ │ └── System/
|
|
│ └── Api/
|
|
│
|
|
├── Framework/ (40-50% - reusable framework)
|
|
│ ├── Core/
|
|
│ ├── Database/
|
|
│ ├── Http/
|
|
│ ├── Cache/
|
|
│ └── Queue/
|
|
│
|
|
└── Infrastructure/ (5-10% - external integrations)
|
|
├── ServiceProviders/
|
|
├── GeoIp/
|
|
├── Email/
|
|
└── Storage/
|
|
```
|
|
|
|
---
|
|
|
|
## Prioritized Recommendations
|
|
|
|
### Priority 1: CRITICAL (Immediate)
|
|
|
|
**Estimated Effort**: 2-3 days
|
|
|
|
1. **Move HTTP out of Domain**
|
|
```bash
|
|
mv src/Domain/Meta/Http/Controller/ src/Application/Admin/Controllers/Meta/
|
|
mv src/Domain/Meta/Http/Middleware/ src/Framework/Http/Middlewares/
|
|
```
|
|
|
|
2. **Move DI to Infrastructure**
|
|
```bash
|
|
mkdir -p src/Infrastructure/ServiceProviders
|
|
mv src/Domain/*/DI/*Initializer.php src/Infrastructure/ServiceProviders/
|
|
# Rename to *ServiceProvider.php
|
|
```
|
|
|
|
3. **Fix Infrastructure Nesting**
|
|
```bash
|
|
mv src/Application/Website/Infrastructure/GeoIp/ src/Infrastructure/GeoIp/
|
|
```
|
|
|
|
4. **Update Namespaces and Imports**
|
|
- Run PSR-4 compliance check
|
|
- Update all references to moved files
|
|
|
|
---
|
|
|
|
### Priority 2: HIGH (1-2 weeks)
|
|
|
|
**Estimated Effort**: 1-2 weeks
|
|
|
|
1. **Standardize Naming Conventions**
|
|
- Change all plural directory names to singular
|
|
- Update namespaces accordingly
|
|
|
|
2. **Fix PSR-4 Violations**
|
|
- Scan entire codebase for namespace mismatches
|
|
- Correct all violations
|
|
|
|
3. **Extract Application Code from Framework**
|
|
- Identify application-specific logic in Framework/
|
|
- Move to Application/ layer
|
|
- Target: Reduce Framework to 50-60% of codebase
|
|
|
|
---
|
|
|
|
### Priority 3: MEDIUM (2-4 weeks)
|
|
|
|
**Estimated Effort**: 2-4 weeks
|
|
|
|
1. **Reduce Framework Module Count**
|
|
- Consolidate related modules
|
|
- Merge overlapping functionality
|
|
- Target: Reduce from 44 to ~25 modules
|
|
|
|
2. **Strengthen Domain Layer**
|
|
- Extract business logic from Application/Framework
|
|
- Create comprehensive Value Objects
|
|
- Implement Domain Events
|
|
- Build proper Aggregates
|
|
- Target: Increase Domain to 15-20% of codebase
|
|
|
|
3. **Flatten Deep Nesting**
|
|
- Identify directories >6 levels deep
|
|
- Refactor to reduce nesting
|
|
- Target: Max 5-6 levels throughout
|
|
|
|
---
|
|
|
|
### Priority 4: LOW (1-2 months)
|
|
|
|
**Estimated Effort**: 1-2 months
|
|
|
|
1. **Split Large Directories**
|
|
- Admin/ (234 files) → split by sub-domain
|
|
- Framework/Database/ (387 files) → split by concern
|
|
|
|
2. **Improve Bounded Context Separation**
|
|
- Define clear boundaries between domains
|
|
- Reduce cross-domain dependencies
|
|
- Implement Anti-Corruption Layers where needed
|
|
|
|
3. **Documentation & Guidelines**
|
|
- Document layer responsibilities
|
|
- Create architecture decision records (ADRs)
|
|
- Write contribution guidelines
|
|
|
|
---
|
|
|
|
## Clean Architecture Compliance
|
|
|
|
### Current Violations
|
|
|
|
| Principle | Status | Notes |
|
|
|-----------|--------|-------|
|
|
| **Dependency Rule** | ❌ VIOLATED | Domain depends on Framework (DI) |
|
|
| **Layer Separation** | ❌ VIOLATED | HTTP in Domain, Infrastructure in Application |
|
|
| **Business Logic Independence** | ⚠️ PARTIAL | Too much logic in Framework |
|
|
| **Framework Independence** | ⚠️ PARTIAL | Framework too large, absorbing app logic |
|
|
| **Testability** | ✅ GOOD | Framework patterns support testing |
|
|
|
|
### Target State
|
|
|
|
All principles should be ✅ COMPLIANT after Priority 1-2 fixes.
|
|
|
|
---
|
|
|
|
## Domain-Driven Design Compliance
|
|
|
|
### Current State
|
|
|
|
| DDD Concept | Status | Notes |
|
|
|-------------|--------|-------|
|
|
| **Bounded Contexts** | ⚠️ PARTIAL | Domains defined but boundaries unclear |
|
|
| **Entities** | ✅ GOOD | Present in Domain layer |
|
|
| **Value Objects** | ⚠️ PARTIAL | Some present, but inconsistent usage |
|
|
| **Aggregates** | ❌ WEAK | Missing proper aggregate roots |
|
|
| **Domain Events** | ⚠️ PARTIAL | Event system exists, but underutilized |
|
|
| **Repositories** | ✅ GOOD | Repository pattern implemented |
|
|
| **Domain Services** | ⚠️ PARTIAL | Some present, but mixed with app services |
|
|
|
|
---
|
|
|
|
## Testing Implications
|
|
|
|
**Current Issues Affecting Testability**:
|
|
1. Domain depending on Framework makes unit testing harder
|
|
2. HTTP in Domain couples business logic to web layer
|
|
3. Thin Domain layer means less isolated business logic to test
|
|
|
|
**After Fixes**:
|
|
- ✅ Pure Domain layer → easy unit testing
|
|
- ✅ Clear boundaries → better integration testing
|
|
- ✅ Framework independence → faster test execution
|
|
|
|
---
|
|
|
|
## Migration Strategy
|
|
|
|
### Phase 1: Critical Fixes (Week 1-2)
|
|
- Move HTTP out of Domain
|
|
- Move DI to Infrastructure
|
|
- Fix Infrastructure nesting
|
|
- Update all imports and namespaces
|
|
|
|
### Phase 2: Standardization (Week 3-4)
|
|
- Standardize naming conventions
|
|
- Fix PSR-4 violations
|
|
- Extract app logic from Framework
|
|
|
|
### Phase 3: Strengthening (Month 2)
|
|
- Strengthen Domain layer
|
|
- Reduce Framework bloat
|
|
- Flatten deep nesting
|
|
|
|
### Phase 4: Optimization (Month 3+)
|
|
- Split large directories
|
|
- Improve bounded contexts
|
|
- Comprehensive documentation
|
|
|
|
---
|
|
|
|
## Success Metrics
|
|
|
|
**After Priority 1-2 Fixes**:
|
|
- ✅ Zero architectural violations
|
|
- ✅ All layers respect Dependency Rule
|
|
- ✅ PSR-4 compliance: 100%
|
|
- ✅ Framework layer: <60% of codebase
|
|
- ✅ Domain layer: >15% of codebase
|
|
|
|
**Target Architecture Grade**: A- (90%) after all phases
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
**Current Grade**: C+ (75%) - Good foundation with critical flaws
|
|
|
|
**Key Strengths**:
|
|
- ✅ Layer separation attempted
|
|
- ✅ Repository pattern implemented
|
|
- ✅ Value Objects used (though inconsistently)
|
|
- ✅ Event system in place
|
|
- ✅ Clear directory structure
|
|
|
|
**Critical Weaknesses**:
|
|
- ❌ HTTP in Domain layer
|
|
- ❌ DI setup in Domain layer
|
|
- ❌ Infrastructure nested in Application
|
|
- ❌ Framework layer too large (85%)
|
|
- ❌ Domain layer too thin (4%)
|
|
|
|
**Recommendation**: Implement Priority 1 fixes immediately to resolve critical architectural violations. Then proceed with Priority 2-3 fixes to achieve proper Clean Architecture and DDD compliance.
|
|
|
|
**Estimated Total Effort**: 2-3 months for complete restructuring
|
|
|
|
---
|
|
|
|
**Analysis Methodology**: Automated codebase exploration using framework's Discovery System, manual architectural review, Clean Architecture and DDD principles assessment.
|
|
|
|
**Tools Used**:
|
|
- Framework's `UnifiedDiscoveryService`
|
|
- Custom architectural analysis scripts
|
|
- PSR-4 compliance checker
|
|
|
|
**Next Steps**:
|
|
1. Review this analysis with development team
|
|
2. Create GitHub issues for Priority 1 fixes
|
|
3. Establish migration timeline
|
|
4. Update CI/CD to enforce new structure
|