Skip to content

Commit 79a96e5

Browse files
authored
Refactor/layer explicit namespaces (#2)
* Domain and application namespaces for consistency * Update namespaces and interfaces for clarity and consistency
1 parent b01e697 commit 79a96e5

33 files changed

+548
-280
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ on:
88

99
jobs:
1010
test:
11+
name: Test on PHP ${{ matrix.php-version }}
1112
runs-on: ubuntu-latest
1213

1314
strategy:
1415
matrix:
15-
php-version: [ '8.1', '8.2', '8.3' ]
16+
php-version: [ '8.2', '8.3', '8.4' ]
1617

1718
steps:
1819
- name: Checkout source code
@@ -28,7 +29,7 @@ jobs:
2829
tools: composer:v2
2930

3031
- name: Cache dependencies
31-
uses: actions/cache@v2
32+
uses: actions/cache@v4.3.0
3233
with:
3334
path: ~/.composer/cache
3435
key: php-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}
@@ -37,9 +38,15 @@ jobs:
3738
- name: Validate composer.json and composer.lock
3839
run: composer validate
3940

40-
- name: Install dependencies
41+
- name: Install Dependencies
4142
if: steps.composer-cache.outputs.cache-hit != 'true'
42-
run: composer install --prefer-dist --no-progress --no-suggest
43+
run: composer install --prefer-dist --no-progress
44+
45+
- name: Check Code Style
46+
run: composer pint-test
4347

4448
- name: Execute Static Code analysis
45-
run: composer analyse
49+
run: composer analyse
50+
51+
- name: Execute Unit, Integration and Acceptance Tests
52+
run: composer test

.gitignore

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
composer.phar
22
/vendor/
33
.idea/
4-
/infrastructure
4+
/infrastructure/
5+
/coverage/
56
*[N|n]o[G|g]it*
6-
*coverage*
7+
coverage.xml
8+
test.xml
79
.phpunit.result.cache
810
composer.lock
11+
wiki/Home.md
12+
/.phpunit.cache
13+
.phpactor.json
14+
/.serena/

README.md

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,62 @@
66

77
Common interfaces for PHP Complex Heart SDK.
88

9-
## Domain Modeling
10-
11-
- Aggregate
12-
- Entity
13-
- ValueObject
14-
- Identity
15-
16-
## Service Bus
17-
18-
- ServiceBus
19-
- Command
20-
- CommandBus
21-
- CommandHandler
22-
- Event
23-
- EventBus
24-
- EventHandler
25-
- Query
26-
- QueryBus
27-
- QueryHandler
28-
- QueryResponse
9+
## Domain Layer
10+
11+
### Model
12+
Core building blocks for domain-driven design:
13+
- **Aggregate** - Root entity with domain event publishing
14+
- **Entity** - Domain object with unique identity
15+
- **ValueObject** - Immutable domain value with equality
16+
- **Identifier** - Unique identifier representation
17+
18+
### Events
19+
Domain event interfaces following ISP (Interface Segregation Principle):
20+
- **Event** - Base domain event (eventId, eventName, payload, occurredOn)
21+
- **Traceable** - Distributed tracing (correlationId, causationId)
22+
- **Sourceable** - Event sourcing (aggregateId, aggregateType, eventVersion)
23+
- **EventBus** - Publishes domain events
24+
25+
## Application Layer
26+
27+
### Command
28+
Write operations (CQRS):
29+
- **Command** - Marker interface for state-changing operations
30+
- **CommandBus** - Dispatches commands to handlers
31+
- **CommandHandler** - Executes commands
32+
33+
### Query
34+
Read operations (CQRS):
35+
- **Query** - Marker interface for data retrieval
36+
- **QueryResponse** - Marker interface for query results
37+
- **QueryBus** - Routes queries to handlers
38+
- **QueryHandler** - Executes queries and returns responses
39+
40+
### Handler
41+
Event handlers:
42+
- **EventHandler** - Reacts to domain events
43+
44+
### Service Bus
45+
Unified message bus facade:
46+
- **ServiceBus** - Provides access to CommandBus, QueryBus, and EventBus
47+
48+
## Architecture
49+
50+
This library follows Clean Architecture principles with explicit layer separation:
51+
- **Domain → Application** - Domain layer is independent, Application depends on Domain
52+
- **Layer-Explicit Namespaces** - Clear architectural boundaries in namespace structure
53+
- **Interface Segregation** - Compose only needed capabilities (e.g., Event + Traceable + Sourceable)
54+
55+
### Architecture Testing
56+
57+
The project includes automated architecture tests using Pest PHP:
58+
59+
```bash
60+
composer test
61+
```
62+
63+
Tests enforce:
64+
- Domain layer independence (no Application dependencies)
65+
- Correct interface placement and usage
66+
- Clean Architecture dependency rules
67+
- PHP and security best practices (via arch presets)

composer.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,29 @@
1111
],
1212
"minimum-stability": "stable",
1313
"require": {
14-
"php": "^8.1"
14+
"php": "^8.2"
1515
},
1616
"require-dev": {
1717
"phpstan/phpstan": "^1.0",
18-
"phpstan/extension-installer": "^1.3"
18+
"phpstan/extension-installer": "^1.3",
19+
"laravel/pint": "^1.25",
20+
"pestphp/pest": "^3.8.4",
21+
"pestphp/pest-plugin-arch": "^3.1.1"
1922
},
2023
"autoload": {
2124
"psr-4": {
2225
"ComplexHeart\\": "src/"
2326
}
2427
},
2528
"scripts": {
26-
"analyse": "vendor/bin/phpstan analyse src --no-progress --level=9"
29+
"test": "vendor/bin/pest --configuration=phpunit.xml --coverage --coverage-clover=coverage.xml --log-junit=test.xml",
30+
"analyse": "vendor/bin/phpstan analyse src --no-progress --memory-limit=4G --level=9",
31+
"pint-test": "vendor/bin/pint --preset=psr12 --test",
32+
"pint": "vendor/bin/pint --preset=psr12"
2733
},
2834
"config": {
2935
"allow-plugins": {
36+
"pestphp/pest-plugin": true,
3037
"phpstan/extension-installer": true
3138
}
3239
}

phpunit.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
bootstrap="vendor/autoload.php"
4+
colors="true"
5+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
6+
cacheDirectory=".phpunit.cache">
7+
<coverage>
8+
<report>
9+
<clover outputFile="./coverage.xml"/>
10+
</report>
11+
</coverage>
12+
<testsuites>
13+
<testsuite name="unit">
14+
<directory>./tests</directory>
15+
</testsuite>
16+
</testsuites>
17+
<logging/>
18+
<source>
19+
<include>
20+
<directory suffix=".php">./src</directory>
21+
</include>
22+
</source>
23+
</phpunit>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ComplexHeart\Application\Command;
6+
7+
/**
8+
* Interface Command
9+
*
10+
* Marker interface for CQRS write commands.
11+
* Commands represent the intention to change the system state.
12+
*
13+
* @author Unay Santisteban <usantisteban@othercode.io>
14+
*/
15+
interface Command
16+
{
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ComplexHeart\Application\Command;
6+
7+
/**
8+
* Interface CommandBus
9+
*
10+
* @author Unay Santisteban <usantisteban@othercode.io>
11+
*/
12+
interface CommandBus
13+
{
14+
/**
15+
* Dispatch the given command.
16+
*/
17+
public function dispatch(Command $command): void;
18+
}

src/Domain/Contracts/ServiceBus/CommandHandler.php renamed to src/Application/Handler/CommandHandler.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
declare(strict_types=1);
44

5-
namespace ComplexHeart\Domain\Contracts\ServiceBus;
5+
namespace ComplexHeart\Application\Handler;
6+
7+
use ComplexHeart\Application\Command\Command;
68

79
/**
810
* Interface CommandHandler
911
*
10-
* @author Unay Santisteban <usantisteban@othercode.es>
11-
* @package ComplexHeart\Domain\Contracts\ServiceBus
12+
* @author Unay Santisteban <usantisteban@othercode.io>
1213
*/
1314
interface CommandHandler
1415
{
1516
/**
1617
* Handle the command execution.
17-
*
18-
* @param Command $command
1918
*/
2019
public function __invoke(Command $command): void;
2120
}

src/Domain/Contracts/ServiceBus/EventHandler.php renamed to src/Application/Handler/EventHandler.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
declare(strict_types=1);
44

5-
namespace ComplexHeart\Domain\Contracts\ServiceBus;
5+
namespace ComplexHeart\Application\Handler;
6+
7+
use ComplexHeart\Domain\Events\Event;
68

79
/**
810
* Interface EventHandler
911
*
10-
* @author Unay Santisteban <usantisteban@othercode.es>
11-
* @package ComplexHeart\Domain\Contracts\ServiceBus
12+
* @author Unay Santisteban <usantisteban@othercode.io>
1213
*/
1314
interface EventHandler
1415
{
1516
/**
1617
* Handle the event execution.
17-
*
18-
* @param Event $event
1918
*/
2019
public function __invoke(Event $event): void;
2120
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ComplexHeart\Application\Handler;
6+
7+
use ComplexHeart\Application\Query\Query;
8+
use ComplexHeart\Application\Query\QueryResponse;
9+
10+
/**
11+
* Interface QueryHandler
12+
*
13+
* @author Unay Santisteban <usantisteban@othercode.io>
14+
*/
15+
interface QueryHandler
16+
{
17+
/**
18+
* Handle the query execution.
19+
*/
20+
public function __invoke(Query $query): QueryResponse;
21+
}

0 commit comments

Comments
 (0)