# Domain

Le Domain est le **cœur métier** du projet. C'est ici que vivent les règles business pures de SpecFlow — ce que le système **sait faire**, indépendamment de toute technologie.


## C'est quoi le Domain ?

On y trouve les entités métier, les value objects, et les événements domaine. Rien d'autre.

Imagine que tu expliques SpecFlow à quelqu'un qui ne connait pas le code.

Tu lui dirais : "Un utilisateur peut créer un projet, y ajouter des modules, exporter le résultat en PDF, et s'abonner pour débloquer plus de fonctionnalités. Un compte peut être bloqué par un admin. Un utilisateur doit vérifier son email avant de se connecter."

**Tout ça, c'est le Domain.** Ce sont les règles du produit, pas de la technique.

Le Domain ne sait pas que tu utilises MySQL, Symfony, ou JWT. Il ne sait pas qu'il y a une API. Il représente uniquement **ce que fait le produit** et **comment il se comporte**.

> Si demain tu changes MySQL pour MongoDB, ou Symfony pour Laravel — le Domain ne bouge pas. Les règles métier restent les mêmes.

> Règle absolue : aucune dépendance externe. Pas de Symfony, pas de Doctrine, pas de lib tierce. PHP pur uniquement.

---

## Structure

```
Domain/
├── User/            → Tout ce qui concerne un utilisateur
├── Project/         → Tout ce qui concerne un projet (cahier des charges)
├── Module/          → Tout ce qui concerne un module (section d'un projet)
├── Subscription/    → Tout ce qui concerne un abonnement
├── History/         → Tout ce qui concerne l'historique des modifications
├── Admin/           → Règles spécifiques au superadmin
└── Shared/          → Éléments partagés entre plusieurs domaines
    ├── Event/       → Événements domaine
    └── ValueObject/ → Objets valeur réutilisables
```

---

## `User/`

**Rôle** : représente un utilisateur du SaaS et toutes les règles qui le concernent.

**Ce qu'on y trouve** : l'entité `User` avec ses données (email, mot de passe hashé, rôle, état...) et ses règles métier sous forme de méthodes (`estActif()`, `bloquer()`, `verifierEmail()`...).

**Comment on l'utilise** : les Use Cases récupèrent un `User` via le repository, appellent ses méthodes pour appliquer les règles, puis le sauvegardent.

```php
$user = $this->userRepository->findByEmail($email);

if (!$user->estActif()) {
    throw new \RuntimeException('Compte bloqué.');
}

$user->bloquer(); // règle métier dans l'entité
$this->userRepository->save($user);
```

**Fichiers existants** : `User.php`

---

## `Project/`

**Rôle** : représente un projet (cahier des charges fonctionnel) et ses règles métier.

**Ce qu'on y trouve** : l'entité `Project` avec ses données (titre, description, état, propriétaire...) et ses règles (archiver, dupliquer, changer de statut...).

**Fichiers à créer** : `Project.php`

---

## `Module/`

**Rôle** : représente un module, c'est-à-dire une section à l'intérieur d'un projet.

**Ce qu'on y trouve** : l'entité `Module` avec ses données (titre, contenu, ordre, projet parent...) et ses règles (réordonner, activer, désactiver...).

**Fichiers à créer** : `Module.php`

---

## `Subscription/`

**Rôle** : représente l'abonnement d'un utilisateur au SaaS.

**Ce qu'on y trouve** : l'entité `Subscription` avec ses données (plan, date de début, date de fin, état...) et ses règles (`estActif()`, `estExpire()`, `annuler()`...).

**Fichiers à créer** : `Subscription.php`

---

## `History/`

**Rôle** : représente une entrée dans l'historique des modifications d'un projet.

**Ce qu'on y trouve** : l'entité `History` avec ses données (action effectuée, utilisateur, date, projet concerné...).

**Fichiers à créer** : `History.php`

---

## `Admin/`

**Rôle** : contient les règles métier spécifiques au superadmin qui ne s'appliquent pas aux utilisateurs normaux.

**Ce qu'on y trouve** : règles de modération, de gestion globale des comptes et des projets.

**Fichiers à créer** : à définir selon les besoins.

---

## `Shared/`

**Rôle** : contient les éléments réutilisables par plusieurs domaines.

### `Shared/ValueObject/`

**Rôle** : objets immuables qui encapsulent une valeur avec ses règles de validation.

**Pourquoi** : plutôt que de passer une `string $email` partout et de valider à plusieurs endroits, on crée un objet `Email` qui valide à la construction. Une seule fois, partout.

**Fichiers à créer** : `Email.php`, `Uuid.php`

### `Shared/Event/`

**Rôle** : événements qui représentent quelque chose qui s'est passé dans le système.

**Pourquoi** : découpler les actions. Quand un user s'inscrit, on émet un `UserRegisteredEvent`. L'Infrastructure peut écouter cet événement pour envoyer un email de confirmation, sans que le Use Case le sache.

**Fichiers à créer** : `UserRegisteredEvent.php`, `UserBlockedEvent.php`

---

## Règles à respecter

- **Aucune dépendance externe** — PHP pur uniquement
- Les entités ne savent pas comment elles sont persistées en base
- Les règles métier vivent dans les entités, pas dans les Use Cases
- Un Use Case appelle les méthodes de l'entité — il ne recalcule pas les règles lui-même