# AGENTS.md — Socle de gestion

Ce dépôt est un **socle commun à plusieurs sociétés**. Une seule base de code, plusieurs
installations — chacune avec son hébergement, sa base, son `.env` et ses réglages. Deux tournent
aujourd'hui en production et portent des données comptables **réelles**.

`CLAUDE.md` décrit le projet en détail. Ce fichier ne retient que ce qui peut faire des dégâts.

---

## 1. La règle qui prime sur toutes les autres

> **Aucune commande ne touche des données sans avoir vérifié pour quelle société elle a été
> écrite.**

Les commandes `reprise:*` sont des outils à usage unique. Elles portent des identifiants
d'écritures, des noms de collaborateurs et des montants relevés sur les données d'UNE installation.
Sur la base d'une autre, ces identifiants désignent d'autres lignes.

`reprise:reventiler-caisse-banque` bascule les écritures 46, 152, 360, 720, 1160, 1161, 1203, 1334
et 1342 de la caisse vers la banque. Lancée ailleurs, elle déplacerait neuf opérations au hasard —
et son rapport d'exécution aurait l'air parfaitement normal. **Ce n'est pas une erreur qui plante,
c'est une erreur qui réussit.**

En conséquence, si vous écrivez ou modifiez une commande de reprise :

- elle vit dans `app/Console/Commands/Reprise/`, porte le préfixe `reprise:` et étend
  `CommandeDeReprise` ;
- elle déclare la société attendue **en dur**, dans `societeAttendue()`, **à côté** des
  identifiants qu'elle manipule ;
- cette valeur n'est **jamais** lue d'un réglage : la garde ne doit pas pouvoir être désarmée
  depuis une interface ;
- une installation sans code société est refusée comme une installation étrangère.

Même chose pour les semences : `database/seeders/Reprise/`, classe `SemenceDeReprise`.

Les outils **permanents** portent le préfixe `gestion:`.

---

## 2. Ce qu'il ne faut jamais faire

| Interdit | Pourquoi |
|---|---|
| Ajouter une colonne `company_id` ou filtrer par société | Ce n'est **pas** du multi-tenant. Les données ne se croisent nulle part parce qu'elles ne sont jamais dans la même base. |
| Écrire un repli qui nomme une société | Il s'appliquerait en silence chez les autres. Le repli est `config('app.name')` ou une palette neutre. |
| Mettre un logo, un favicon ou une couleur de charte dans le dépôt | L'archive livrée doit être **rigoureusement identique** pour toutes les sociétés. Ces fichiers se téléversent et vivent sur le disque public. |
| Écraser un réglage `company.*` déjà renseigné | Les installations en production ont leur identité saisie à la main. On n'écrit un réglage que s'il est **vide**. |
| `migrate:rollback` dans le chemin de mise à jour | Défaire une migration détruit des données. Restaurer une sauvegarde n'en détruit aucune. |
| Modifier une migration déjà commitée | Elle a déjà tourné en production. |
| Renommer `2026_08_02_100000_adapt_transactions_for_irada.php` | Elle a déjà tourné : la renommer la ferait rejouer. |
| Citer un montant, une raison sociale ou un identifiant réels dans la suite commune | Elle doit passer sur n'importe quelle installation. Ces tests-là vont dans le groupe `irada`. |

---

## 3. Avant de livrer

```bash
php artisan test               # suite commune du socle
php artisan test --group=irada # tests portant des chiffres réels
./vendor/bin/pint
npm run build
```

Puis `deploy/CHECKLIST-RESULTATS.md`, qui n'est pas un formulaire de politesse : chaque ligne
correspond à quelque chose qui a déjà cassé une fois.

---

## 4. Publier une version

**Construire n'est pas publier.** `bash deploy/build-zip.sh vX.Y.Z` fabrique une archive et ne
déclenche rien. Seul `php artisan gestion:publier-version` écrit le manifeste que les installations
viennent lire.

> ⚠️ Publier une version, c'est **modifier les applications de production la nuit suivante**.
> C'est le comportement voulu ; c'est aussi pourquoi la publication est un geste conscient, séparé
> de la construction.

Si la version embarque une commande de reprise, publiez-la avec `--reprise` : elle sera alors
téléchargée et signalée, mais jamais appliquée sans décision humaine.

---

## 5. Conventions d'écriture

- Code, tables, colonnes : **anglais**. UI, libellés, messages, commentaires **nouveaux** :
  **français**.
- Les commentaires disent **pourquoi**, pas quoi. Un commentaire qui cite une société à titre
  d'exemple doit être réécrit au nom du socle : c'est ce qui empêche le prochain lecteur de croire
  que le code est propre à l'une d'elles.
- Toute logique de calcul vit dans `app/Services/`, avec des tests. Jamais dans une ressource
  Filament.

---

## 📌 Guide de passation (contexte hors-code) — À LIRE AU DÉMARRAGE

Un guide compagnon **`GUIDE-PASSATION.md`** vit à la racine de ce dépôt (et en tête du dossier
« my apps » côté Cowork). Il couvre ce que ce `CLAUDE.md` ne dit pas :

- **Hébergement cPanel réel** : serveurs (saturn/mars), comptes (`mobdiema`/`ruwadcap`), bases, chemins, DNS, binaire PHP 8.3.
- **Déploiement manuel pas à pas** (le gérant applique lui-même ; Claude livre un zip à plat + procédure).
- **Historique récent** : trésorerie IRADA reconstruite via `reprise:repartir-alimentations` (6 leviers, garde société, refus d'écrire hors atterrissage, option `--jusqu-au=2026-07-31`), alignement RUWAD 3.6.2 → 3.8.6, refonte affichage marchés/dashboard v3.8.6.
- **Logique & préférences du gérant** : concision, commandes prêtes à copier-coller, décisions métier à l'exploitant, sécurité d'abord, 0 découvert, IRADA et RUWAD toujours sur la même version.

⚠️ Trésorerie IRADA **déjà reconstruite et écrite en prod** — ne pas relancer `reprise:*` sans demande explicite du gérant.
