feat: Setup projet Classeo avec infrastructure Docker et architecture DDD

Configure l'environnement de développement complet avec Docker Compose,
structure DDD 4 Bounded Contexts, et pipeline CI/CD GitHub Actions.

Corrections compatibilité CI:
- Symfony 8 nécessite monolog-bundle ^4.0 (la v3.x ne supporte que jusqu'à Symfony 7)
- ESLint v9 nécessite flat config (eslint.config.js) - le format .eslintrc.cjs est obsolète
This commit is contained in:
2026-01-30 09:55:58 +01:00
parent ddefa927c7
commit 6da5996340
125 changed files with 10032 additions and 0 deletions

13
backend/src/Kernel.php Normal file
View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
final class Kernel extends BaseKernel
{
use MicroKernelTrait;
}

View File

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain;
abstract class AggregateRoot
{
/** @var DomainEvent[] */
private array $domainEvents = [];
protected function recordEvent(DomainEvent $event): void
{
$this->domainEvents[] = $event;
}
/** @return DomainEvent[] */
public function pullDomainEvents(): array
{
$events = $this->domainEvents;
$this->domainEvents = [];
return $events;
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain;
use DateTimeImmutable;
interface Clock
{
public function now(): DateTimeImmutable;
}

View File

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain;
use Ramsey\Uuid\Uuid;
final readonly class CorrelationId
{
private function __construct(
private string $value,
) {
}
public static function generate(): self
{
return new self(Uuid::uuid4()->toString());
}
public static function fromString(string $value): self
{
return new self($value);
}
public function value(): string
{
return $this->value;
}
public function __toString(): string
{
return $this->value;
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain;
use DateTimeImmutable;
use Ramsey\Uuid\UuidInterface;
interface DomainEvent
{
public function occurredOn(): DateTimeImmutable;
public function aggregateId(): UuidInterface;
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace App\Shared\Domain;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/**
* @phpstan-consistent-constructor
*/
abstract readonly class EntityId
{
protected function __construct(
public UuidInterface $value,
) {
}
public static function generate(): static
{
return new static(Uuid::uuid4());
}
public static function fromString(string $value): static
{
return new static(Uuid::fromString($value));
}
public function equals(EntityId $other): bool
{
return $this->value->equals($other->value);
}
public function __toString(): string
{
return $this->value->toString();
}
}

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace App\Shared\Infrastructure\Clock;
use App\Shared\Domain\Clock;
use DateTimeImmutable;
final readonly class SystemClock implements Clock
{
public function now(): DateTimeImmutable
{
return new DateTimeImmutable();
}
}