Files
michaelschiemer/docs/SRC-ARCHITECTURE-ANALYSIS.md
Michael Schiemer 36ef2a1e2c
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
fix: Gitea Traefik routing and connection pool optimization
- 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
2025-11-09 14:46:15 +01:00

15 KiB

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:

// 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:

// 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:

// 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

    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

    mkdir -p src/Infrastructure/ServiceProviders
    mv src/Domain/*/DI/*Initializer.php src/Infrastructure/ServiceProviders/
    # Rename to *ServiceProvider.php
    
  3. Fix Infrastructure Nesting

    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