 # AGENTS.md

## Exclusions

- Les fichiers sous le dossier `jane/` sont régénérés via Jane (`make jane-generate`) : ne pas les modifier manuellement, mais accepter les changements produits par la génération.
- Ne **jamais** écrire dans un fichier exclu par le fichier `.gitignore`.

## Contexte du projet

`noahvet/reef-api-client` est une **librairie PHP** (Symfony bundle) permettant à des projets Symfony de se connecter au reef NoahVet. Elle fournit : authentification IAM, vérification des permissions, audit logging, sérialisation Jane/JSON, itérateurs API, parseur multipart.

Le code source est dans `lib/` (namespace `NoahVet\Reef\`). Le code Jane généré est dans `jane/` (namespace `NoahVet\Jane\`).

> **Migration en cours** : le projet migre progressivement vers une architecture hexagonale. Les dossiers à la racine de `lib/` (`Factory/`, `Iterator/`, `Paginator/`, `Repository/`, `Controller/`, `Mapper/`, etc.) sont du code legacy qui sera progressivement déplacé. Ne pas refactoriser ce code sans demande explicite.

---

## Architecture — Clean / Hexagonale

### Règle fondamentale des dépendances

```
Infrastructure → Application → Domain
```

- `Domain` : aucune dépendance vers `Application`, `Infrastructure`, ou un framework Symfony.
- `Application` : dépend uniquement de `Domain`. Orchestre sans contenir de logique métier.
- `Infrastructure` : dépend de `Domain` et `Application`. Implémente les interfaces définies dans ces couches.

### Structure `lib/`

```
lib/
├── Domain/
│   ├── Serialization/     # Interfaces de sérialisation (domaine pur)
│   │   └── Jane/          # Interfaces Jane spécifiques
│   ├── Validation/        # Interfaces et services de validation
│   └── Http/              # Modèles HTTP (Multipart…)
│
├── Application/
│   ├── Port/              # Interfaces vers l'extérieur (services applicatifs)
│   └── Query/             # Objets Query (DTOs lecture)
│
├── Infrastructure/
│   ├── Console/           # Commandes bin/console (symfony commands)
│   ├── Http/Get/          # Implémentations des services applicatifs HTTP (GetOne, GetAll)
│   └── Serialization/
│       ├── Jane/          # Implémentations des interfaces Jane
│       └── Json/          # Implémentation du sérialiseur JSON (JsonSerializerFacade, JsonSerializerFactory)
│
│ — Code legacy (migration en cours) —
├── Controller/
├── Factory/
├── Iterator/
├── Mapper/
├── Paginator/
├── Repository/
├── Security/
└── [autres dossiers legacy]
```

### Règles par couche

**Application/**
- Orchestre le domaine, ne contient pas de logique métier.
- Les `*Query` sont des interfaces ou readonly classes (DTOs purs, pas de logique).
- Les `*Port` sont des interfaces exposant ce que l'infrastructure doit fournir.

**Domain/**
- Aucune dépendance extérieure : uniquement les primitives du langage PHP et le Domain lui-même. Tout `use` vers Symfony, Doctrine, ou tout autre package vendor est interdit.
- Les interfaces de services de domaine définissent les contrats métier purs.

**Infrastructure/**
- Implémente les interfaces du Domain et de l'Application.
- Les classes sont `readonly` avec injection par constructeur (jamais `final` — c'est une lib).
- Utilise `#[\Override]` sur toutes les méthodes implémentant une interface.

---

## Standards de codage

- Toute classe non anémique doit posséder sa propre interface, placée dans le même dossier qu'elle. Sont exemptées : entités, Value Objects, Enums, DTOs (`*Query`, `*Command`, `*Response`), Exceptions.
- Lorsqu'une interface suffixée `Interface` porte le même nom que la classe qui l'implémente, importer l'interface avec l'alias `SelfInterface` (ex : `use NoahVet\Reef\Domain\Serialization\GetAllServiceInterface as SelfInterface`).
- Toujours utiliser les **named arguments** pour chaque paramètre dans les appels de fonctions et de méthodes (ex : `$this->serializer->normalize(data: $objects, context: $context)`).
- Lors de l'ajout d'une nouvelle notion (classe, méthode, constante, configuration, etc.), elle doit toujours être rangée par **ordre alphabétique**, sauf pour `id`, `createdDate` et `updatedDate` qui sont toujours en premier.
- `declare(strict_types=1);` obligatoire en tête de chaque fichier PHP.
- Ne jamais utiliser `final` sur une classe. Utiliser `readonly` sur chaque propriété du constructeur (`private readonly Type $prop`) — le modificateur `readonly class` (PHP 8.2) est interdit car le projet supporte PHP 8.1.

---

## Tests

### Tests unitaires

- Les tests unitaires se trouvent exclusivement dans `tests/A_Unit/`.
- La classe testée doit toujours être instanciée dans un attribut nommé `subject`.
- `subject` doit toujours être une instance créée avec `new` de la classe à tester.

### Tests fonctionnels

- Les tests fonctionnels se trouvent exclusivement dans `tests/B_Functional/`.

---

## Commandes utiles

```bash
# Démarrer le projet (Docker + composer install)
make start

# Corriger le style de code + PHPStan + Psalm
make cs-fix
# ou via composer
composer run quality

# Lancer les tests avec couverture
make run-test
# ou
composer run phpunit-coverage

# Régénérer les fichiers Jane
make jane-generate

# Vérifications avant push
make pre-push
```

---

## À savoir

- Le namespace source est `NoahVet\Reef\` → `lib/`.
- Le namespace Jane généré est `NoahVet\Jane\` → `jane/`.
- Le namespace de test est `NoahVet\Reef\Test\` → `tests/`.
- Les projets consommateurs (`noahvet/reef-bsm-client`, etc.) embarquent ce package via Composer.
- Pour un test local sans release, utiliser les targets `deploy-*` du Makefile (`make deploy-iam`, `make deploy-bsm`…).