# AGENTS.md : règles d'architecture de ce projet

> À déposer à la racine du repo. Claude Code, Cursor, Codex et la plupart des agents le lisent
> avant de coder. Remplace les `<…>` par ce qui correspond à ta stack.

## Les couches (règle 1)

Trois couches, une seule direction : `présentation → métier → données`. Jamais l'inverse.

| Couche | Dossier | Contient | N'importe JAMAIS |
|---|---|---|---|
| Présentation | `<dossier ui>` | écrans, composants, état d'écran | les données directement |
| Métier (domaine) | `<dossier domain>` | entités, règles, cas d'usage, interfaces de repository, erreurs typées | l'UI, la base, une API, un SDK |
| Données | `<dossier data>` | implémentations des repositories, sources (API, base, cache), mappers | l'UI |

Le seul endroit qui connaît tout le monde : le point d'entrée (assemblage, injection de dépendances).

## Les règles que tu dois respecter

1. **Une entité est pure** : elle ne connaît ni la base, ni l'API, ni l'UI, ni l'horloge système
   (une date « maintenant » se passe en paramètre).
2. **Les erreurs sont typées** : une exception technique (réseau, base) est traduite en erreur
   métier dans la couche données. Un type fermé par catégorie, traité de façon exhaustive.
3. **On teste le métier** : chaque règle métier a un test unitaire, sans mock du métier lui-même.
4. **Un nom dit où vit la classe** : `<Techno>UserRepository` (ex. `PostgresUserRepository`),
   jamais `UserRepositoryImpl`.
5. **Un cas d'usage fait une seule chose.** Un fichier dépasse 200 lignes : on découpe.
6. **Imports internes par chemin de module**, pas en relatif profond (`../../../`).

## Avant chaque modification

- Dire dans quelle couche tu interviens, et pourquoi.
- Si la modification oblige à importer une couche interdite : **t'arrêter et le dire**, ne pas
  contourner.
- Correction de bug : suivre le skill `bugfix-sans-regression`.
- Nouvelle fonctionnalité : suivre le skill `nouvelle-fonctionnalite`.
- Avant de rendre la main : suivre le skill `revue-avant-merge`.

## Le garde-fou mécanique (à brancher une fois)

Les règles écrites ne suffisent pas, il faut qu'une machine refuse une violation :
`<ta stack>` → un lint ou une règle d'imports qui interdit `domain → data` et `domain → ui`
(ex. règles de dépendances du linter, modules séparés, frontières de packages).
