A professional architectural boilerplate for building scalable Enterprise Systems.
This project demonstrates a reference implementation of a Modular Monolith using Domain-Driven Design (DDD), Hexagonal Architecture (Ports & Adapters), and Clean Architecture. It is designed for long-term projects with complex business logic requiring high reliability.
The project follows strict principles of layer and module isolation, designed to achieve two key code quality metrics:
- High Cohesion: All code related to a specific business task (e.g., "Reservation") resides in one place (Domain).
- Low Coupling: Modules are unaware of each other's internals and communicate only through stable contracts (Ports).
Data flow is always unidirectional, and business logic is completely decoupled from the framework and infrastructure.
HTTP Request
│
▼
[Controller] (Presentation)
│
│ (DTO)
▼
[UseCase] (Application) ────┬──────> [Domain Event] ──(Async Side Effect)──> [Listener]
│ │
│ (Direct Call) │ (Port / Interface)
│ │
▼ ▼
[Domain Service] [Adapter] ──> [External Module]
(Reader/Writer) │
│ │
▼ │
[Entity & Factory] │
(Rich Model) │
│ │
▼ │
[Repository] ───────────────────┘
│
▼
[Database]
I have prepared detailed documentation for each aspect of the system:
-
Modular Monolith & Hexagonal Architecture
- How do modules communicate?
- Why doesn't
Authknow about theuserstable? - Data isolation and Cross-Module Communication.
-
- Why I don't use standard Models.
- Rich Domain Model vs Anemic Model.
- Strict Patch pattern for partial updates.
-
Clean Architecture & Request Flow
- Request lifecycle: from controller to database.
- The role of UseCase as an orchestrator.
- Why DTOs are mandatory.
-
- Marker Interfaces.
- Controllers without
try-catch. - Centralized error handling.
I moved away from the standard Laravel structure (app/Http, app/Models) in favor of domain grouping.
app/
├── Core/ # Shared Kernel: Base classes, System components, Infrastructure
│ ├── Database/Eloquent/
│ │ └── Entity.php # Base class for all models (UUID support)
│ ├── Exceptions/ # Marker Exception Interfaces
│ └── Http/ # Shared Request/Response classes
│
└── Domains/ # Isolated business modules
├── Common/ # Shared components for domains
│ ├── Contracts/
│ └── Rules/
│
├── Auth/ # Authentication Module
│ ├── Contracts/ # Ports (Interfaces) for other modules
│ └── ...
│
├── User/ # Users Module
│ ├── Adapters/ # Port implementations (AuthUserProvider)
│ └── ...
│
├── Reservation/ # Reservation Module
│ ├── DTOs/ # Data Transfer Objects
│ ├── Entities/ # Rich Domain Models
│ ├── Enums/ # Enums
│ ├── Events/ # Domain Events
│ ├── Exceptions/ # Domain Exceptions
│ ├── Factories/ # Factories for complex objects
│ ├── Http/
│ │ ├── Controllers/ # Thin Controllers
│ │ ├── Requests/ # Validation and DTO mapping
│ │ └── Resources/ # JSON Presenters
│ ├── Listeners/ # Event Listeners
│ ├── Providers/ # Event Registration
│ ├── Repositories/ # Strict Repositories
│ ├── UseCases/ # Orchestrators (Application Services)
│ └── routes.php # Routes
The project is fully dockerized. You will need Docker and Docker Compose to run it.
The project is configured for automatic initialization (composer install, migrations, and key generation happen on first container start).
git clone https://github.com/your-org/laravel-modular-monolith.git
cd laravel-modular-monolith
docker compose up -d --buildOn first launch, it may take 1-2 minutes to install dependencies. You can follow the process via docker compose logs -f backend.
Tests are run manually on demand:
docker exec -it laravel-modular-monolith-backend php artisan test- Framework: Laravel 12
- Language: PHP 8.3+
- Database: PostgreSQL (UUID Primary Keys)
- Cache/Queue: Redis
- Server: Nginx
- DevOps: Docker, Docker Compose
When adding new functionality, follow this rule:
Dependencies always point inward. Domain logic must not depend on external libraries or the framework.
See the Architecture Guide for more details.