# Journal des versions — STE MOBDIE PRIVÉ

Ce qui a changé, version par version, de la plus récente à la plus ancienne.

Chaque entrée renvoie au rapport d'origine, conservé dans
[`docs/rapports/`](docs/rapports/) : le journal dit ce qui a changé, le rapport
dit pourquoi et ce qu'il fallait vérifier après déploiement.

> Les treize rapports vivaient à la racine du dépôt, sans ordre ni sommaire. Il
> fallait les ouvrir un à un pour savoir lequel parlait de quoi. Ils n'ont pas
> été réécrits — ils sont rangés, et résumés ici.

---

## v1.21.0 — Le connecteur fait tout ce que fait l'écran, et la recherche du haut vérifiée

*[Rapport](docs/rapports/RAPPORT-V1.21.0.md) — partie MOBDIE du lot `PROMPT-LOT-socle-v4.36.0-mobdie-v1.21.0.md` ;
**aucune migration** ; aucune dépendance ; aucun asset recompilé (`public/build` inchangé) ; aucun
fichier supprimé ni déplacé. Déploiement v1.20.0 → v1.21.0.*

- **Tout écran atteignable par le connecteur, par l'écran lui-même** : `ecrans_lister` (le plan :
  champs, actions, filtres, colonnes), `objets_chercher`, `objet_lire`, `recherche_globale` ;
  `objet_creer`, `objet_modifier`, `objet_corbeille`, `objet_restaurer`, `objet_action` — simuler
  puis confirmer, avant / après, annulation 7 jours, admis dans un plan. Une case Administrateur par
  famille d'écrans (7), éteintes par défaut. 40 → 50 outils (23 lecture, 27 action).
- **Interdits tenus PENDANT le geste** : un montant encaissé, une prime versée, un numéro de facture
  émis ne changent pas ; aucune sortie d'argent ni versement créés ; aucune suppression définitive ;
  aucun compte, rôle ou jeton touché ; réglages, utilisateurs, permissions, mot de passe, Accès Claude
  et boîte de réception fermés ; comptes bancaires en lecture seule ; envois à un tiers en mode
  « préparer ».
- **Rattacher une facture à un dossier** (34/2026) : bouton « Rattacher à un dossier » (liste des
  factures) et `facture_rattacher_dossier` ; seul le dossier change ; une facture ne change jamais de
  client. Ensuite `facture_remplacer_hors_tresorerie` passe.
- **« Hors trésorerie remplaçables »** : le MÊME client seulement (contrôle, bouton, connecteur,
  contrôle de mise en ligne).
- **Encaissement libre** : la facture « hors trésorerie » du même client et du même montant, réglée au
  plus tard ce jour-là, est proposée AVANT toute échéance (contrôle 9 et
  `encaissement_rattacher_echeance` — PARAMAP 1810 ↔ 22/2026) ; une échéance postérieure à
  l'encaissement vient après.
- **Test qui ferme la porte** (`CouvertureConnecteurTest`) et **recherche du haut** balayée sur
  toutes les ressources (`RechercheGlobaleBarreTest`).
- `mobdie:deployer-v1210` (lecture seule).

---

## v1.20.0 — Le connecteur en mode administrateur, et des écrans qui ne bloquent plus

*[Rapport](docs/rapports/RAPPORT-V1.20.0.md) — partie MOBDIE du lot `PROMPT-LOT-socle-v4.35.0-mobdie-v1.20.0.md` ;
**3 migrations additives et idempotentes** (niveau Administrateur et go de session des jetons ; clé
anti-doublon ; détail du journal) ; aucune dépendance ; `public/build` recompilé ; aucun fichier
supprimé. Déploiement v1.19.2 → v1.20.0.*

- **Accès Claude — niveau « Administrateur »** : tout ce que peut un jeton « actions », plus cinq
  droits cochés un par un (tous éteints à la création) : modifier librement une opération ;
  corbeille / restauration ; couper une opération ; rattacher un encaissement à une échéance ou
  remplacer un « payé hors trésorerie » ; modifier contrats, échéances et clients au-delà du
  périmètre « actions ». Sans la case, l'outil refuse en la nommant. Chaque case et chaque go de
  session est journalisé (Journal Claude, `acces.droits` : avant, après, qui). Restent interdits à
  tous : montants encaissés, primes versées, numéros émis, envoi à un tiers, suppression
  définitive, mots de passe, jetons, utilisateurs, rôles, comptes bancaires.
- **`plan_executer`** : jusqu'à 200 actions de types mélangés, UNE simulation, UN avant / après,
  UN code, tout ou rien ; une entrée de journal, annulable d'un bloc. **Clé `idempotence`** sur
  toute action : rejouée, elle rend le résultat déjà obtenu sans rien réappliquer. **120 appels /
  minute** (au lieu de 60), au-delà **429** + `Retry-After`. **Go de session** (30 min, par jeton) :
  un code n'expire qu'à la fin du go. **Annulation sur 7 jours** ; le journal garde l'avant / après
  (écran « Détail », `journal_claude`). **`lecture_libre`** : consultation par objet, filtres et
  champs, sans jamais un champ secret.
- **Outils** : 32 → **40** (18 → 19 lecture, 14 → 21 action) : `lecture_libre`, `plan_executer`,
  `encaissement_rattacher_echeance`, `facture_remplacer_hors_tresorerie`, `operation_couper`,
  `corbeille`, `echeance_modifier`, `contrat_modifier` ; `operation_modifier` gagne le **sens** et,
  en administrateur, les opérations rattachées (le paiement suit compte et date) ; `client_modifier`
  gagne l'identité légale (administrateur) ; `client_fiche` liste les **factures** (payées par
  quoi) et les **paiements**.
- **Corbeille des factures** : filtre « Corbeille » sur la liste (badge « rang NN/AAAA tenu »),
  **contrôle 14** « Rang tenu par une pièce à la corbeille » ; `mobdie:deployer-*` lit statut et
  client à une seule source (`EtatDeLaPiece`).
- **Appariement à 90 jours** (`facture_emettre_depuis_echeance`, `reprise:facturer-echeances-payees`) :
  même client, même montant, de 10 jours avant à 90 jours après l'échéance, la plus proche
  d'abord — toujours proposé, jamais appliqué sans désignation (TIRIMI : 21/05 ↔ 03/07).
- **Contrôle 9** propose l'échéance échue du même client au même montant ; bouton « Rattacher à
  cette échéance » (simulation, puis confirmation), aucune opération créée (PARAMAP, 700 DH).
- **« Remplacer par l'encaissement réel »** sur une facture payée hors trésorerie (ou historique
  reprise) : un paiement pointe une opération libre du même montant ; statut « Payée » inchangé,
  aucune opération créée (34/2026 ↔ 3 500 DH). À l'écran et par le connecteur, un seul service
  (`RattachementEncaissements`).
- **`mobdie:deployer-v1200`** (lecture seule).

## v1.19.2 — Reprise du dossier du comptable : les rangs tenus par la corbeille se libèrent aussi

*[Rapport](docs/rapports/RAPPORT-V1.19.2.md) — correctif court ; aucune migration ; aucune
dépendance ; `public/build` inchangé ; aucun fichier supprimé. Déploiement v1.19.1 → v1.19.2.*

- **`reprise:factures-cabinet`** : en prod le 07/11 à 15 h, 35 et 36/2026 (Fakhar Naima) étaient
  passées **à la corbeille** — la simulation refusait. Un rang tenu par une pièce à la corbeille se
  libère désormais, avec les mêmes garde-fous que l'annulée : aucun paiement, aucune opération au
  journal, aucune échéance — sinon refus global, rien n'est écrit. La pièce est renumérotée comme
  les autres (note « Renumérotée le 07/11/2026 : n° initial X… ») et **reste à la corbeille** :
  jamais restaurée, jamais supprimée définitivement. Tableau 1 : Statut « À la corbeille ».
- **`mobdie:deployer-v1190`** : le premier tableau (« Rangs du dossier du comptable ») tient compte
  de la corbeille et nomme la pièce comme le second (nom du dossier avant le nom porté par la
  pièce) — il affichait « Annulée / Brouillon » pour des pièces à la corbeille, et un autre client
  pour 38.

## v1.19.1 — Reprise du dossier du comptable : libérer aussi 35 et 36/2026

*[Rapport](docs/rapports/RAPPORT-V1.19.1.md) — correctif court ; aucune migration ; aucune
dépendance ; `public/build` inchangé ; aucun fichier supprimé. Déploiement v1.19.0 → v1.19.1.*

- **`reprise:factures-cabinet`** : en prod, 35 et 36/2026 étaient tenues par Fakhar Naima
  (2026-98), une annulée et un brouillon — la simulation refusait. Décision du gérant : elles cèdent
  leur rang comme les quatre annulées. `RANGS_A_LIBERER = [35, 36, 38, 39, 42, 43]` ; un rang se
  libère s'il est tenu par une **annulée** (sans paiement, opération ni échéance — inchangé) ou un
  **brouillon** (sans paiement ni opération ; son échéance est **conservée**, seul son numéro
  change). Tout autre statut → refus, rien n'est écrit. Statut inchangé, note « Renumérotée le
  07/11/2026 : n° initial X… ». Tableau 1 : colonnes **Statut** et **Échéance**. Dernière ligne :
  « 6 pièces renumérotées (N à N+5) ; 6 factures créées, 3 840,00 DH TTC… ».
- **`mobdie:deployer-v1190`** : un tableau par rang à libérer — statut, paiement, opération,
  échéance (oui/non).

## v1.19.0 — Le dossier du comptable, les échéances payées sans facture, le connecteur sans Chrome

*[Rapport](docs/rapports/RAPPORT-V1.19.0.md) — 1 679 tests (1 678 au vert, 1 échec préexistant propre au poste) ;
**2 migrations additives** (prix unitaires à 4
décimales ; réponse gardée sur les codes de confirmation) ; aucune dépendance ; `public/build`
recompilé ; aucun fichier supprimé. Déploiement v1.18.0 → v1.19.0.*

- **`reprise:factures-cabinet`** : les six factures remises au cabinet Rami Expertise (35, 36, 38,
  39, 42, 43/2026) créées à leur numéro, réglées en espèces HORS trésorerie ; les quatre annulées
  jamais déclarées qui tenaient 38/39/42/43 prennent les numéros suivants (décision du gérant).
  Simulation par défaut ; 0 opération, 0 paiement, 0 e-mail.
- **Échéances payées sans facture** : la cause était le bouton « Enregistrer un paiement » de la
  fiche client, qui ne proposait pas la facture — il la propose désormais (cochée) et passe par le
  chemin unique de l'échéancier. Contrôle 13 dans `mobdie:controler-factures` ;
  `reprise:facturer-echeances-payees` et l'outil `facture_emettre_depuis_echeance` les facturent par
  le chemin normal, rattachées au paiement, sans mouvement d'argent.
- **Connecteur : 12 outils de plus** (32 : 18 lecture, 14 action) — opérations (recherche, détail,
  reclassement, modification, rattachement à une facture), catégories, factures (fiche, liste,
  correction des lignes), échéancier des prêts et affectation d'un versement. Un code de
  confirmation rejoué après une coupure rend le résultat déjà appliqué, sans rien rejouer. La page
  Accès Claude décrit chaque outil.
- **Prix unitaires à 4 décimales** (devis, factures) et champ « P.U. TTC » : 2 × 500,00 TTC font
  1 000,00, plus 1 000,01. Totaux calculés sur les valeurs exactes, arrondis une fois.
- `mobdie:deployer-v1190` : contrôle de mise en ligne, lecture seule.

---

## v1.18.0 — Le connecteur Claude : lire et agir, simuler puis confirmer

*[Rapport](docs/rapports/RAPPORT-V1.18.0.md) — **4 migrations additives** (tables `claude_*` et
réglages `claude.*`, accès coupé par défaut) ; aucune dépendance ; `public/build` recompilé ; aucun
fichier supprimé. Déploiement v1.17.0 → v1.18.0.*

- **`POST https://app.mobdie.ma/mcp`** : un serveur MCP écrit à la main (Streamable HTTP en JSON,
  sans état), jeton fixe `Authorization: Bearer mobdie_…`, interrupteur, contrôle d'Origin,
  60 appels par minute, journal de chaque appel (purge à 12 mois).
- **12 outils de lecture** branchés sur les services des écrans : tableau de bord, trésorerie,
  recherche des clients (le moteur tolérant aux fautes), fiche client, impayés (J+1), fins de
  contrat, demandes, courrier reçu, cabinets et primes, résiliations, anomalies (diagnostic), journal.
- **8 outils d'action qui simulent d'abord** (code de 6 caractères, 10 minutes, une fois) :
  encaissement d'une échéance désignée, demande avancée d'une étape, relance ou mise en demeure
  PRÉPARÉE (jamais envoyée), coordonnées d'un client, prolongation d'un contrat, renouvellement en
  brouillon, versement de primes rattaché à une opération déjà au journal, annulation du jour.
- **Paramétrage → Accès Claude** (jetons hachés affichés une fois, révocation) et **Journal Claude**
  (filtres, export Excel).

---

## v1.17.0 — Domicilier une association ; lire toutes les pièces, même abîmées

*[Rapport](docs/rapports/RAPPORT-V1.17.0.md) — 1 643 tests (1 642 au vert, 1 échec préexistant propre au poste), 10 678 assertions ; **1 migration
additive** (`2026_10_28_100000_les_associations`) ; 1 commande (`mobdie:banc-lecture`, lecture
seule) ; aucun fichier supprimé. Déploiement v1.16.1 → v1.17.0.*

- **Associations** (dahir n° 1-58-376) : personne morale de forme « association »,
  partout (admin, assistant, formulaire en ligne, espace cabinet). Récépissé de
  déclaration (n°, date, nature, autorité) ; pièces : statuts, récépissé, PV
  constitutif, liste du bureau ; ni certificat négatif, ni RC, ni greffe.
- **Neuf gabarits « association »** (2026-11-A) : siège sur le dahir, contrat sur le
  DOC, 544-4 / 544-7 seulement pour les devoirs de MOBDIE, tribunal de première
  instance de Fès. Absent ou désactivé → génération refusée, jamais le texte d'une
  société. Société et personne physique : HTML rendu identique octet pour octet.
- **Récépissé à recevoir** à J+60 (pré-réglage) au lieu de « RC dans les 3 mois »,
  fermé à la validation ; résiliation sans lettre au greffe ; registre « toute
  personne domiciliée » avec Forme et récépissé ; loi 43-05 : président et bureau.
- **Lecture des pièces** : plus de refus pour une photo petite ou floue (lue, puis
  signalée) ; vues recadrées et corrigées, passe de cadrage, PDF scanné rendu en
  images ; MRZ prouvée par ses clés (`App\Support\Mrz`) ; champs « sûr / douteux » ;
  seconde lecture sur champ clé manquant ; au portail, lecture hors de la requête.
  `mobdie:banc-lecture` : aucune valeur fausse donnée pour sûre sur le banc.

---

## v1.16.1 — Plus jamais de SQL à la main : les gestes qui manquaient, les homonymes, le paiement d'avance

*[Rapport](docs/rapports/RAPPORT-V1.16.1.md) — 1 604 tests, 10 093 assertions ; **3 migrations
additives** (`2026_10_16_200000_les_versements_de_prime`, `2026_10_16_210000_les_constats_ecartes`,
`2026_10_16_220000_l_expediteur_des_modeles`) ; 1 commande de reprise
(`reprise:versement-de-prime`) ; aucun fichier supprimé. Déploiement v1.16.0 → v1.16.1.*

- **Homonymes sans compte** : une personne sans compte = son nom et son cabinet ;
  `--beneficiaire` ambigu exige `--prime=` ; « Changer le bénéficiaire… » ; contact du
  cabinet lisible et modifiable.
- **Prime versée en plusieurs fois** : versements par opération, « Versée en partie —
  reste N DH », Dû(D) exact ; « Rattacher un versement déjà au journal… » ;
  « Corriger le montant… » ; contrôles de la famille Primes.
- **Paiement d'avance** : tout « Enregistrer un paiement » décompose ce qui dépasse
  (choix explicite, reliquat dit) ; « Encaisser d'avance… » ; le même contrat est
  prolongé, une facture par échéance, aucune prime.
- **Contrats** : dates proposées, chevauchement signalé (« prolonger plutôt »),
  écart durée / échéances, « Corriger les dates… » même payé.
- **« C'est voulu »** sur les constats à vérifier ; diagnostic résumé en tête.
- **Liens de fichier signés au clic** ; **expéditeur par modèle d'e-mail**.

---

## v1.16.0 — Retrouver un client par n'importe quel nom ; l'espace des cabinets ; le rapport des primes

*[Rapport](docs/rapports/RAPPORT-V1.16.0.md) — 1 561 tests, 9 660 assertions ; **1 migration
additive** (`2026_10_16_100000_les_cabinets_et_leurs_primes`) ; 1 vue supprimée
(`portail/cabinet/commissions.blade.php`). Se déploie avec v1.15.3, en un seul paquet v1.15.2 → v1.16.0.*

- **Recherche des clients** : un seul moteur (gérant, associés, personnes
  autorisées, e-mail, cabinet, CIN, code, ICE, téléphone, RC — même mal écrits),
  dans la liste Clients, la recherche du haut, tous les champs « Client »,
  les colonnes « Client », « Mes clients » du cabinet, l'assistance et le doublon
  possible ; chaque résultat dit par quoi il a été trouvé. `mobdie:banc-recherche`.
- **Rapport des primes** à toute date, pour tout périmètre et tout bénéficiaire,
  en PDF et en Excel ; « Envoyer au cabinet » ; une seule source
  (`SituationDesPrimes`) — l'espace du cabinet voit enfin les primes de ses
  collaborateurs.
- **Prime « Rachida »** : `reprise:rattacher-au-cabinet --beneficiaire`.
- **Espace des cabinets** : accueil avec « Quoi de neuf », Mes clients avec export
  Excel, Mes primes (relevé), nouveau client express (les pièces d'abord).
- **E-mail du lundi** aux cabinets (`portail:recap-cabinets`), éteint au déploiement.

---

## v1.15.3 — Un contrat marqué Expiré ne laisse plus de dette derrière lui

*[Rapport](docs/rapports/RAPPORT-V1.15.3.md) — 1 480 tests, 8 931 assertions ; aucune
migration. Se déploie avec v1.16.0, en un seul paquet v1.15.2 → v1.16.0.*

- **`reprise:contrat-en-double`** reconnaît le contrat déjà marqué « Expiré » à
  la main qui chevauche un contrat actif sans rien avoir encaissé (NOVERA
  2026-116-C1, DEVANO 2026-121-C1) : il le propose au retrait, garde l'actif ;
  un contrat résilié est refusé avec la raison.
- **« Modifier » un contrat** vers Expiré, Annulé ou Résilié : « N échéance(s)
  non payée(s) resteront dues : les annuler ? » — Annuler / Les garder dues,
  choix obligatoire, jamais d'annulation muette.
- **`mobdie:diagnostic`** : nouvelle cause « échéance due sur un contrat
  expiré/annulé », avec la commande ou le geste de la fiche.

---

## v1.15.2 — Le diagnostic profond, et les écarts du groupe WhatsApp du cabinet Rami

*[Rapport](docs/rapports/RAPPORT-V1.15.2.md) — 1 472 tests, 8 867 assertions ; **1 migration
additive** (`users.apporteur_id`, le collaborateur d'un cabinet) ; 2 commandes de
reprise (`reprise:paiement-hors-echeancier`, `reprise:rattacher-au-cabinet`,
simulation par défaut) ; `mobdie:diagnostic` à dix familles. Se déploie avec
v1.15.1, en un seul paquet v1.15.0 → v1.15.2.*

- **Paiement partiel** : un acompte laisse l'échéance due pour le reste ; la
  facture et la prime attendent le solde ; tous les impayés lisent le reste dû
  (EAGLE IT : 267 reçus, 453 dus).
- **« Classer sans suite… » / « Rouvrir le dossier »** sur la fiche client :
  échéances non payées annulées avec le motif, contrat annulé, relances
  écartées, refus si paiement ou facture émise (METAIRIE BRUNO).
- **« Rééditer »** un contrat : même contrat, mêmes échéances, nouveau
  document — la réédition par « Ajouter un contrat » faisait les 1 440 DH de
  NOVERA et DEVANO. `reprise:contrat-en-double` retire aussi un doublon sans
  argent, en proposant la dernière édition.
- **Cabinet Rami** : Salima déclarée collaboratrice du cabinet ;
  `reprise:rattacher-au-cabinet` rattache les clients de ses primes et liste
  les candidats ; **relevé des primes** sur l'onglet « Commission » du cabinet,
  avec le texte prêt à copier pour WhatsApp.
- **`reprise:paiement-hors-echeancier`** : contrat + échéance n° 1 +
  rattachement pour un paiement rangé hors échéancier ; la prime qui manque
  (FAKHAR ZAKIA — sous contrat et payée, sans prime).
- **Balayages gardés dans la suite** : chaque page et ressource pour les
  quatre rôles, chaque onglet, widget, page du portail, gabarit et modèle
  d'e-mail ; chaque geste ouvert sans effet de bord.
- **Défauts corrigés** : onglets de fiche en « Chargement… » (rendus avec la
  page, état vide expliqué) ; variables des e-mails du portail échappées ;
  pages allégées (1,5 Mo → 0,4–0,6 Mo) ; remboursement d'un financement qui ne
  s'ouvrait pas depuis sa fiche ; brouillon qui proposait « Annuler » (numéro
  consommé), « Avoir » et « Relancer » ; contrôle 11 qui proposait de relier
  une facture au contrat en double.
- **`mobdie:diagnostic`** : après la configuration, dix familles de données
  (en retard par cause, factures, primes, cabinets, relances, conformité,
  trésorerie, Forsa, CCA, documents), nominatives, avec la commande ou le
  geste de chacune. Lecture seule.

---

## v1.15.1 — Un contrat saisi deux fois se retire proprement (WELLPHARM), et « ce qui change » en langage client

*[Rapport](docs/rapports/RAPPORT-V1.15.1.md) — 1 431 tests, 8 370 assertions ;
aucune migration ; 1 commande de reprise (`reprise:contrat-en-double`,
simulation par défaut).*

- **`reprise:contrat-en-double`** : liste les contrats actifs qui se
  chevauchent et propose la commande ; annule la facture en trop (elle garde
  son numéro, pas d'avoir), retire le paiement sans argent (opération laissée
  à la corbeille), annule le contrat en double et ses échéances (jamais
  supprimés), écarte leurs relances. Aucun mouvement d'argent ; refus motivés.
- **Contrôle 12** de `mobdie:controler-factures` : « Deux contrats actifs qui
  se chevauchent », avec la commande proposée (WELLPHARM, MOHAMED MEZIAN au
  01/10). Le contrôle 3 propose la même commande pour un dossier en double ;
  `reprise:paiement-en-double` refuse de reporter une facture sur un paiement
  déjà facturé.
- **La cause** : « Ajouter un contrat », utilisé pour refaire le document après
  un changement de représentant. Un second contrat actif chevauchant demande
  désormais une confirmation explicite (« Ce client a déjà le contrat … actif
  jusqu'au … ») — « Ajouter un contrat », « Saisie détaillée », « Transformer
  en contrat ».
- **« Ce qui change » en phrases** — e-mail, espace client, aperçu, texte
  WhatsApp : « Nous avons ajouté à votre contrat : … », « … comprises dans
  votre redevance, inchangée, de 1 200 DH TTC par semestre », « La redevance
  passe de 840 à 1 200 DH TTC par semestre », « Nous avons retiré : … » ; le
  nom de la formule seulement s'il est seul à changer. WhatsApp :
  « Bonjour M. Chabrak, je viens de vous envoyer par e-mail la version 2 de
  votre contrat. … ».

---

## v1.15.0 — L'offre qui se négocie et s'envoie en un clic, les options au formulaire, les demandes du client, le courrier numérisé

*[Rapport](docs/rapports/RAPPORT-V1.15.0.md) — 1 414 tests, 8 241 assertions ; 5 migrations
additives (catalogue des prestations, versions de l'offre, demandes du client,
courrier numérisé, 9 modèles d'e-mail) ; 1 commande de reprise
(`reprise:gabarit-prestations`, simulation par défaut).*

- **Le catalogue des prestations** (Formules en ligne → Prestations) : quatre
  de base, cinq options semées masquées, prix par semestre ramené à la
  périodicité ; options incluses dans une formule ; l'instantané posé sur le
  contrat ; `{{prestations}}`, `{{phrase_redevance}}`, `{{periode}}` pour
  l'article 2 ; `reprise:gabarit-prestations` en fait une nouvelle version du
  gabarit (2026-10.1), sans rien écraser.
- **Le formulaire en ligne en quatre étapes** : Société · Dirigeant · Pièces ·
  **Formule & options** — le total qui monte à chaque case, le rythme de
  paiement, le conseil (jamais de bascule), l'article 2 dépliable ; devis à une
  ligne par option, version 1 de l'offre, contrat qui naît avec l'instantané.
- **« Ajuster l'offre »** (fiche → Offre & contrat) : formule ou prix libre,
  prestations, clause libre ; ce qui change en direct ; envoi éteint sans
  changement ; devis modifié avant signature, avenant après (échéances non
  payées recalculées à l'acceptation seulement) ; acceptation en ligne dans
  l'espace client (page Contrat) ; texte WhatsApp à copier.
- **Les demandes du client** : une seule file (page Demandes, badge, onglet de
  la fiche), créées par le client ou notées par le gérant, un e-mail à chaque
  étape, gestes guidés (attestation, personne autorisée, version d'offre).
- **Le courrier reçu** : saisie rapide, scan envoyé par e-mail si la
  numérisation est au contrat, sinon l'avis d'arrivée que l'espace client
  annonçait ; original suivi jusqu'au retrait (`retire_par`) ; « Télécharger
  le scan » dans l'espace client.
- Relecture indépendante : neuf corrections (version 1 jamais acceptée,
  brouillon visible du client, échéance à facture brouillon, scan non envoyé
  servi, prix suggéré…), et deux trouvées par la suite (compteur des modèles,
  rangs du menu Domiciliation).

## v1.14.1 — La pièce de la société lue comme la CIN

*[Rapport](docs/rapports/RAPPORT-V1.14.1.md) — 1 361 tests, 7 717 assertions ; 1 migration
(données seulement : la forme juridique en clé).*

- **La pièce de la société d'abord, lue comme la CIN** (formulaire public et
  « Nouveau client » du cabinet) : certificat négatif ou modèle J obligatoire
  à l'étape 1 ; la dénomination, la forme et l'activité se remplissent, à
  vérifier, sans jamais écraser une saisie ; « Identique » ou « Différent »
  comparés à la pièce, et joints à la pièce pour le gérant.
- **La CIN en un seul PDF scanné recto-verso** : le verso n'est plus exigé à
  part.
- **La forme juridique en clé de l'admin** : le formulaire en ligne écrivait
  « SARL AU » là où l'admin attend `sarl_au` (forme vide sur la fiche, titre
  « Gérant » pour une SA) ; corrigé à la source, dans les écrans de l'admin qui
  appliquent une lecture, et pour les demandes déjà reçues.
- Relecture indépendante : dix corrections (lecture d'une pièce remplacée,
  saisie jamais écrasée, situation verrouillée, brouillon repris, envoi
  repris…).

## v1.14.0 — Le portail refait, la saisie contrôlée, les pièces validées

*[Rapport](docs/rapports/RAPPORT-V1.14.0.md) — 1 342 tests, 7 598 assertions ; 1 migration
(additive). Police Manrope servie par le serveur (`public/fonts/manrope`).*

- **Nouvelle interface du portail** (`domiciliation.mobdie.ma`), d'après la
  maquette validée le 07/10 : vrai logo, écran partagé pour le public,
  formulaire en trois étapes avec résumé des points à corriger, espaces client
  et cabinet à menu fixe (onglets en bas sur téléphone), frise de la demande et
  prochaine étape, « Mes clients » en tableau, bouton « Télécharger ».
- **Contrôle de saisie, les mêmes règles partout** (`App\Support\Saisie`) :
  téléphone mis en forme, e-mail et faute de frappe proposée, n° de pièce selon
  son type, adresse, RC, ICE, total des parts ; jugés à la sortie du champ.
- **Pièces contrôlées au dépôt** : illisible, trop petite, ni photo ni PDF →
  refusée ; peu nette, nom ou n° différent de la pièce lue → signalé. Le verso
  de la CIN est demandé.
- **Validation des pièces par le gérant** (À valider → Pièces) : valider, ou
  refuser avec un motif envoyé au client, cabinet en copie ; « Remplacer » dans
  les espaces, filtre « Pièces à reprendre ». Un RC ne ferme l'alerte du délai
  qu'une fois validé. L'expiration de la CIN n'est plus une tâche.

## v1.13.3 — Les montants TTC des anciens contrats, refaire une facture émise

*[Rapport](docs/rapports/RAPPORT-V1.13.3.md) — 1 323 tests, 7 447 assertions ; aucune migration.
Livrée avec la v1.13.2 (jamais déployée seule).*

- **Reprise `reprise:tva-des-anciens-contrats`** (simulation par défaut) : les
  64 contrats repris le 27/07 passent en hors taxe (600 → 500), leurs 196
  échéances prennent la TVA comprise, TTC inchangé ; brouillons recalculés,
  factures émises intactes.
- **Le générateur d'échéances** applique la TVA par défaut (celle de
  l'échéancier en place, sinon celle du réglage) : « Régénérer les échéances »
  depuis l'onglet Contrats ne sort plus d'échéances sans TVA.
- **« Refaire la facture… »** : un avoir total annule une facture émise, une
  remplaçante au nom actuel du client prend le rang suivant, son échéance et
  son paiement — rien n'est ré-encaissé. La facture refaite dit « Annulée par
  avoir » et sort des contrôles.

## v1.13.2 — Le tout lié : devis, contrat, échéance, facture, prime

*[Rapport](docs/rapports/RAPPORT-V1.13.2.md) — 1 319 tests, 7 379 assertions ; aucune migration.*

- **Le devis créé avec un contrat lui est relié** (assistant, contrat client
  existant, onglet Contrats) : plus de second contrat tiré du même devis, et
  « Transformer en facture » propose l'échéance du contrat — la facture devient
  la sienne, son encaissement la règle, la prime naît sur elle.
- **Le brouillon de renouvellement est la facture de son échéance** : son
  montant (plus de 20 % de trop sur les anciens contrats), sa période, ses
  liens ; jamais pour une échéance déjà facturée ; l'échéance suivante naît
  quand l'échéancier s'arrête.
- **« Affecter à une échéance » emmène la prime** : échéance, événement, base.
- **Reprise `reprise:relier-factures-aux-echeances`** (simulation par défaut) :
  devis ↔ contrat, factures 54 à 57/2026 sur leur échéance n° 1, brouillons de
  renouvellement refaits ; le dossier en double (WELLPHARM) reste à l'exploitant.
- **Liste des factures** : la colonne « Échéance » nomme chaque cas (échéance,
  échéances groupées, reprise, devis à relier, facture libre) ; **contrôle 11**
  « Facture de devis sans échéance » ; le bandeau ne compte plus l'historique
  payé avant la plateforme comme « à encaisser ».
- **Le nom du client** : la facture d'un devis prend l'identité actuelle du
  client ; une correction de la fiche gagne les devis et brouillons qui
  portaient l'ancienne.
- **Bouton « Signature du domicilié… »** plus rendu pour un impayé (et six
  actions jumelles gardées de la même façon).

## v1.13.1 — La signature du domicilié, le prix d'une demande

*[Rapport](docs/rapports/RAPPORT-V1.13.1.md) — 1 310 tests, 7 286 assertions ; deux migrations additives.*

- **« Faire signer le domicilié »** sur l'acte de résiliation **et** l'attestation
  de fin (demande du client, commun accord ; jamais pour un impayé) : une case
  « Le domicilié » et son cadre de légalisation. Au prononcé, ou après coup
  depuis la fiche (« Signature du domicilié… ») : les deux documents sont
  refaits, les anciens restent dans l'archive.
- **« Modifier le prix… »** d'une demande en ligne, tant que le contrat n'est pas
  établi : nouveau devis et projet de contrat au prix convenu, l'ancien devis
  « expiré », envoi au client (cabinet en copie) ou brouillon. Le contrat et
  ses renouvellements reprennent ce prix. Le prix du devis se lit dans la liste.

---

## v1.13.0 — Les tarifs et le lien des cabinets

*[Rapport](docs/rapports/RAPPORT-V1.13.0.md) — 1 305 tests, 7 230 assertions ; une migration additive.*

- **Un prix spécial par formule pour chaque cabinet** (onglet « Tarifs » de sa
  fiche ; vide : prix public), pour tout le contrat : devis, contrat,
  échéances et renouvellements. Un tarif changé ne touche rien de déjà né.
- **Le lien client du cabinet** (`/c/rami-7k2p`) : le client fait sa demande
  lui-même, rattachée au cabinet, à ses prix, le cabinet en copie. Il s'ouvre
  dès que le n° CNDP est saisi, même formulaire public fermé ; le gérant le
  désactive ou le remplace depuis la fiche.
- **« Lien client » dans l'espace du cabinet** : le lien et « Copier », ses
  tarifs, et « Envoyer à un client » (l'e-mail part de MOBDIE, la demande est
  déjà au nom du client).

---

## v1.12.1 — Le portail sur domiciliation.mobdie.ma

*[Rapport](docs/rapports/RAPPORT-V1.12.1.md) — 1 297 tests, 7 130 assertions ; aucune migration.*

- **Le sous-domaine** : avec `PORTAIL_DOMAIN=domiciliation.mobdie.ma`, la racine
  du sous-domaine ouvre l'accueil du portail (la redirection de « / » vers
  l'administration passait avant) ; les anciennes adresses `app.mobdie.ma/espace/…`
  mènent pour de bon (301) à la même page du sous-domaine, paramètres compris.
  Sans la clé, rien ne change.
- **Les messages de validation en français** : un champ refusé affichait la clé
  brute « validation.required » (formulaire en ligne, espace cabinet, connexion).
- **La fiche d'un cabinet** : le nom du cabinet pour titre, compteurs sur toute
  la largeur, « Nouveau cabinet », colonne « Origine » remplie (« Gérant »).

---

## v1.12.0 — L'espace client, l'espace des cabinets, et des relances qui partent seules

*[Rapport](docs/rapports/RAPPORT-V1.12.0.md) — 1 285 tests, 7 027 assertions ; onze migrations additives.*

- **Le formulaire en ligne** en trois étapes, rien que ce que la loi exige :
  le dossier naît avec son devis et son projet de contrat (filigrané
  « PROJET »), envoyés au client ; aucune facture. Fermé au public tant qu'il
  manque le n° CNDP ou un prix ; mode essai pour le gérant.
- **« Nouvelles demandes »** : de la demande reçue au contrat légalisé, un geste
  par étape ; le dépôt du contrat légalisé active le dossier, émet la facture et
  l'envoie au client avec le contrat.
- **L'espace client** (connexion par code, sans mot de passe) : état du dossier,
  « À faire » (RC dans les 3 mois), documents visibles du client, paiements et
  reçus déclarés (rien n'est encaissé sans le gérant), courrier physique reçu,
  profil facultatif ; rappels du RC à J-30 et J-7.
- **« Vérifiez votre dossier »** pour les anciens clients : les anciens liens
  restent valables ; manques en tête, avenant 2026-10 accepté en ligne (sans
  valeur de signature), envoi groupé avec aperçu, « Copier le lien » sans e-mail.
- **Les relances qui partent seules** : interrupteur éteint à la livraison ;
  quatre étapes « part seule », mise en demeure et résiliation toujours sur clic ;
  « Mises en demeure prêtes ce matin », par e-mail seulement quand le contrat le
  permet.
- **Les cabinets apporteurs** : espace partenaires (clients, nouveau client,
  paiements déclarés, demandes de résiliation, commissions, courrier), isolation
  stricte ; commission fixe au premier encaissement d'un nouveau client.
- **« À valider »**, section « Espace client et vigilance » de la fiche, tuiles du
  tableau de bord ; conservation des pièces portée à **dix ans** (loi 43-05,
  art. 7).

---

## v1.11.2 — La mise en demeure part là où le client la reçoit vraiment

*[Rapport](docs/rapports/RAPPORT-V1.11.2.md) — 1 198 tests, 6 408 assertions ; une migration additive.*

- **L'adresse de notification du domicilié** : la mise en demeure part à son
  élection de domicile (adresse personnelle du représentant), jamais au siège de
  MOBDIE, où un recommandé reviendrait chez l'expéditeur. Adresse d'envoi
  obligatoire et vérifiée à l'écran, enregistrable sur la fiche ; repère
  « adresse de notification manquante » sur la fiche, complétude et suivi légal
  alignés ; `reprise:adresses-de-notification` (9 nettoyées, 36 inutilisables
  sur l'export du 01/10).
- **« Rien » choisi se voit** dans l'assistant de résiliation.
- **Le compte d'encaissement pré-rempli** par le dernier compte employé, sur
  toutes les actions d'encaissement — sans mémoire, aucun compte deviné.

---

## v1.11.1 — Trois finitions vues en production après la v1.11.0

*[Rapport](docs/rapports/RAPPORT-V1.11.1.md) — 1 189 tests, 6 334 assertions ; une migration additive.*

- **Le libellé des périodes** du tiroir « Facturer des impayés » se lit sur le
  mois de début (janvier-juin S1, juillet-décembre S2 ; T = mois / 3) : la même
  période de novembre ne s'appelle plus S1 une année et S2 l'année suivante.
- **Les valeurs par défaut de l'assistant de résiliation** sont enfin
  appliquées : « Ville du RC » remplie, « Prorata » posé dans l'état et visible
  sur la ligne de l'échéance à cheval. Six jumeaux corrigés (mode de paiement,
  périodes de facture, pièce et nationalité du nouveau dossier, relevé de compte
  courant, adresse d'expédition, RC du suivi légal).
- **L'article 15 du contrat** : MOBDIE élit domicile en son siège social, et non
  à l'adresse personnelle du gérant ; `mobdie:documents-article-15` liste les
  pièces à régénérer.

---

## v1.11.0 — Une fin de domiciliation conforme à la loi, des impayés qui se facturent au mois près, et un contrat qui protège MOBDIE

*[Rapport](docs/rapports/RAPPORT-V1.11.0.md) — 1 175 tests, 6 284 assertions ; six migrations additives (sauvegarde avant `migrate`).*

- **Le cadre légal dans l'app.** Une seule date d'effet (la fiche, à défaut
  l'acte) lue par l'échéancier, le registre légal, la fiche, le recouvrement et
  l'assistance ; références légales justes (loi n° 15-95 modifiée par la loi
  n° 89-17, art. 544-1 et suivants) ; onglet « Cadre légal » des réglages ;
  géométrie des documents portée par le gabarit, variante « lettre ».
- **Des dossiers clos qui disent vrai.** Règle `>=`, scission au prorata de
  l'échéance à cheval, facturées listées « à régulariser par avoir » ; verrous
  sur « (Re)générer » et sur les relances ; Échu et À venir séparés partout ;
  détection quotidienne ; `reprise:dossiers-clos` (18 échéances / 14 100 DH sur
  l'export du 01/10).
- **Les modèles versionnés et le contrat 2026-10** (15 articles : salle de
  réunion, obligations 544-4 / 544-6, clause résolutoire après mise en demeure,
  préavis, effets de la fin, indemnité d'occupation, garantie, données
  personnelles, notifications) ; avenant 2026-10 qui embarque les conditions ;
  écran « Modèles de documents » (Aperçu, Comparer, Adopter).
- **La mise en demeure** (art. 255 DOC) préparée, envoyée, reçue, expirée ou
  réglée — depuis la fiche, son bandeau rouge et le recouvrement.
- **« Résilier… »** : l'assistant en trois étapes (motif et date, reste dû,
  documents), fondement affiché sans blocage, prononcé dans une transaction ;
  lettre selon le motif, attestation de fin, lettres au greffe, aux impôts, à
  la TGR et à la douane ; suivi légal avec date limite d'un mois et
  conservation cinq ans ; liste Résiliations « x/4 informés ».
- **Facturer des impayés** : un tiroir par période et par mois, scission au
  mois près, ligne par période ou récapitulative, numéro à l'émission seulement.
- **Les documents sortent comme les autres** : Ouvrir, Partager ou enregistrer,
  Envoyer ; « Tout partager » (feuille de partage ou ZIP) et « Tout envoyer par
  e-mail ».
- **Plis recommandés du fisc non remis** (art. 544-4, 8°) : alerte à quinze
  jours et lettre d'information.

---

## v1.10.3 — Un paiement en double qui se retire proprement, et un contrat qui suit l'année payée

*[Rapport](docs/rapports/RAPPORT-V1.10.3.md) — 1 102 tests, 5 761 assertions ; aucune migration.*

- **Paiement en double.** `reprise:paiement-en-double <garder> <retirer>` retire le
  paiement dont l'argent n'est pas au journal en reportant sa facture et ses
  primes acquises sur le paiement gardé — la facture reste payée, l'opération à
  la corbeille y reste, aucun argent ne bouge (WELLPHARM, n° 4 / n° 2). Le
  contrôle 3 donne la commande exacte.
- **Prolonger un contrat.** `reprise:prolonger-contrat <référence>` et l'action
  « Prolonger » de l'onglet Contrats portent la fin à l'année payée sans toucher
  aux échéances (HC IMPORT, 2026-109-C1 → 11/08/2027).

---

## v1.10.2 — Une facture pour l'année, un avoir qui corrige une partie, et les derniers faux pas du contrôle

*[Rapport](docs/rapports/RAPPORT-V1.10.2.md) — 1 091 tests, 5 690 assertions ; aucune migration.*

- **Une facture qui couvre plusieurs échéances.** `reprise:facture-plusieurs-echeances`
  (et « Couvrir plusieurs échéances » à l'écran) rattache à une facture les
  échéances qu'elle couvre, restaure l'encaissement resté à la corbeille et le
  fait porter par le paiement de l'échéance — sans nouvelle entrée d'argent
  (HC IMPORT EXPORT, 50/2026). « Nouvelle facture » facture N périodes d'un coup.
- **La jumelle que la recherche ne voyait pas.** WELLPHARM : l'opération vivante
  porte un autre paiement ; le diagnostic dit « paiement en double » et ne
  propose plus jamais de restaurer quand l'argent est déjà au journal.
- **L'avoir partiel**, lignes modifiables, plafonné au TTC moins les avoirs émis.
- **Plus de 403** sur « Ouvrir la facture » d'une payée (un seul chemin vers les
  pièces), et un bandeau « Encaissé » qui compte l'argent réellement rattaché.
- **Une restauration qui parle** : restaurée, ou pourquoi pas et quel geste faire.

---

## v1.10.1 — Le contrôle ne crie qu'au vrai

*[Rapport](docs/rapports/RAPPORT-V1.10.1.md) — 1 075 tests, 5 560 assertions ; aucune migration.*

- **Un seul périmètre pour les dix contrôles.** Les 34 factures reprises d'avant
  la plateforme (46 900,00 DH) remplissaient « Payée sans argent » : elles sont
  désormais hors champ de tous les contrôles — sauf si un lien plateforme les
  rattache — et l'information est dite une fois, en tête de l'écran et de la
  commande.
- **Un paiement relié à sa jumelle.** Le contrôle 3 nomme l'opération jumelle
  vivante d'un paiement dont l'écriture est à la corbeille ;
  `reprise:relier-paiements` (simulation, puis `--appliquer`) ou le bouton de
  l'écran les relient quand le cas est sûr — rien créé, rien supprimé, aucun
  montant touché.
- **Le jumeau qui fabriquait le trou.** « Dupliquer » ne recopie plus l'écriture
  d'un encaissement (ni d'un versement de prime, ni d'une dépense payée de sa
  poche) : c'était une seconde entrée d'argent pour un seul paiement réel. Le bon
  geste s'affiche à la place.

---

## v1.10.0 — La saisie au geste du socle, l'argent qui passe d'un compte à l'autre, la facture qui part en un geste, et un contrôle qui voit ce qui ne colle pas

*[Rapport](docs/rapports/RAPPORT-V1.10.0.md) — 1 065 tests, 5 492 assertions. ⚠️ Migration : `transactions.account_id` devient facultatif — sauvegarde phpMyAdmin avant.*

- **La saisie comme au socle.** « ⚡ Saisie rapide » (⌘⇧O) et « + Opération
  complète » dans la barre du haut de tous les écrans ; la saisie complète
  devient une page (l'essentiel à gauche, « Détails avancés » replié, date du
  jour), « Payé avec quoi ? » en boutons, « Créer & ajouter un autre ». Le
  Journal tient dans l'écran : six colonnes, montant signé, totaux entrées /
  sorties / solde.
- **Payer de sa poche.** « Fonds <associé> » crée ensemble la charge (sans
  compte) et l'apport en compte courant lié ; la paire vit et meurt ensemble,
  l'apport ne se touche pas seul. Aucun compte de la société ne bouge.
- **Transferts inter-comptes.** Deux écritures jumelles liées (catégorie
  système, hors résultat), bouton « Transfert » au Journal et sur chaque compte,
  aperçu des soldes, ⇄ au Journal. Exclus du résultat, du CPC, de la TVA, des
  courbes et des charges observées ; les soldes, eux, bougent.
- **La facture en un geste.** Cause racine de la 55/2026 « Envoyée » et « Réglée » :
  l'envoi écrasait le statut. Il ne le fait plus avancer que vers l'avant ; un
  brouillon ne s'envoie pas. « Ensuite : Émettre et envoyer » ouvre l'e-mail
  pré-rempli (rien ne part sans clic) ; « Facturer en lot » émet et propose
  l'envoi groupé ; bandeau HT · TVA · TTC · Encaissé · Reste sur Factures (et
  Devis).
- **Encaissements par mois.** Onglet des Rapports comptables : espèces (caisse)
  et banque par compte, autres entrées à part, contrôle du mode ; chaque chiffre
  ouvre le Journal filtré ; export Excel ; répartition sur la carte « Encaissé
  ce mois-ci » ; fonction d'assistance qui cite la même source.
- **Contrôles factures ↔ opérations.** Dix contrôles en lecture seule, écran
  « Contrôles » avec pastille, `mobdie:controler-factures`, correction du seul
  statut écrasé par `reprise:statut-factures` (simulation d'abord) ou ligne par
  ligne à l'écran ; cloche du matin pour une anomalie bloquante nouvelle.

---

## v1.9.1 — L'assistance sait ce que savent les écrans, une prime ne se paie pas deux fois, et un document sort du téléphone

*[Rapport](docs/rapports/RAPPORT-V1.9.1.md) — 994 tests, 5 039 assertions.*

- **L'argent se dit compte par compte.** Deux fonctions d'assistance ouvrent le
  chemin qui manquait : `mouvements_par_compte` (entrées/sorties par compte et
  par catégorie, part des paiements clients isolée, soldes du tableau de bord)
  et `encaissements_clients` (paiements des domiciliés, désaccords compte/mode
  signalés jamais corrigés, hors trésorerie dit à part, même calcul que la
  carte « Encaissé ce mois-ci »). « En espèces » = compte de type Caisse
  (décision du gérant). Le mode et la référence d'un paiement sont recopiés
  sur son opération du journal à partir de maintenant, jamais déduits du
  compte, et `journal_mensuel` ne perd plus les opérations sans catégorie.
- **Les fonctions jumelles lisent les calculs des écrans.** `echeances` repose
  sur le recouvrement (J+1, les deux parts « À aller chercher » / « À
  solder ») ; `client` ne choisit plus en silence (« Fakhar » → elle demande
  lequel des trois) et sépare l'échu de l'à-venir ; `pret` devient
  `dettes_de_financement` (tous les financements, et les prêteurs sans
  échéancier — les 98 500 DH invisibles) ; `commissions` groupe par
  bénéficiaire, sous son nom. Chaque fonction s'exécute sous le garde-fou.
- **Une prime ne se saisit pas deux fois.** Le verrou vit dans l'entonnoir
  unique et se voit avant d'envoyer, sur le champ « Prime pour » — deux
  personnes sur un même encaissement restent permises. Le doublon existant
  (MM DRAGON LOG TRANS) se répare par `reprise:prime-en-double` : liste,
  simulation, puis `--appliquer` — le trop-perçu règle une prime acquise du
  même bénéficiaire, invariants vérifiés, aucun argent ne bouge.
- **Les liens filtrent à nouveau.** « Ouvrir le journal de la caisse » et
  « Voir ses clients » se construisent avec la clé `filters` de Filament 5 —
  l'ancien paramètre était ignoré sans erreur, et la liste s'ouvrait entière.
- **Un document sort du téléphone.** Un seul geste partout, « Partager ou
  enregistrer » : la feuille de partage native sur appareil tactile
  (Enregistrer dans Fichiers, Mail, WhatsApp, AirDrop…), le téléchargement
  classique sur ordinateur — plus jamais de navigation vers un « attachment »,
  qui n'aboutit à rien en PWA iOS. Et le lecteur rend **tout** le document sur
  téléphone (pdfjs-dist embarqué, sans CDN) : fini la première page seule des
  iframes iOS, et le bandeau d'aveu a disparu.

---

## v1.9.0 — L'argent se relie toujours, la pièce se lit toujours, le contrat se signe et se lit partout

*[Rapport](docs/rapports/RAPPORT-V1.9.0.md) — 952 tests, 4 824 assertions.*

- **La chaîne argent ne perd plus rien.** Une facture née d'un devis, une
  facture groupée, un encaissement hors trésorerie : toutes proposent
  désormais une prime, et la prime saisie se rattache toujours à son paiement
  et à son client — jamais orpheline. La main pour corriger arrive avec :
  affecter, ré-affecter ou détacher une facture d'une échéance **même une fois
  payée** (le règlement existant se propage, le numéro et les montants ne
  bougent pas), ajouter une prime après coup depuis la facture ou depuis
  l'opération du journal, corriger une prime acquise. Le filet
  « encaissements sans prime » voit enfin les encaissements sans échéance.
- **L'OCR lit ce qu'il sait lire, et le dit quand il ne sait pas.** Un nom qui
  diverge du contrat ne fait plus tout jeter : le nom de référence tient, mais
  le numéro et les dates s'appliquent, divergence signalée. Une réponse
  illisible devient un échec explicite au lieu d'un « terminé, 0 champ », et le
  JSON se lit avec tolérance. Sur échec ou lecture vide — et seulement là — le
  modèle le plus puissant prend le relais, dans la limite du plafond mensuel.
  Les images sont converties (HEIC des iPhone), redressées, allégées et
  contrastées avant l'envoi, côté navigateur comme côté serveur, dans
  l'assistant comme sur la fiche client. Recto et verso d'une même pièce
  partent en un seul appel. Quatre nouveaux types de pièce d'identité, et les
  statuts, le modèle J et les pièces « autre » sont lus eux aussi.
- **Le contrat se signe comme il doit.** Le nom et le titre du signataire
  figurent dans la case de signature, des deux côtés ; la fonction du gérant se
  lit dans les réglages. Une forme juridique s'ajoute au client et propose le
  titre — Gérant(e), Président(e) — que le titre saisi surpasse toujours. Le
  devis en parallèle devient actif par défaut dans les trois flux de création.
  Et un contrat peut être **non renouvelable** : la clause suit le mode choisi,
  et aucun renouvellement ne lui est préparé.
- **Le mobile est débloqué.** Relevé de compte courant, aperçu d'une pièce,
  aperçu avant enregistrement : les trois passent par le lecteur, avec
  « Télécharger » qui marche sur iPhone. Le relevé s'envoie par e-mail sans
  quitter l'écran. Et l'application ne gèle plus au milieu d'une saisie :
  l'assistant ne lance plus d'analyse synchrone, le mode direct est raccourci,
  et une requête anormalement longue laisse une trace au journal.

---

## v1.8.2 — L'atelier des comptes courants, et la création de financement évidente

*[Rapport](docs/rapports/RAPPORT-V1.8.2.md) — 902 tests, 4 552 assertions.*

- **Comptes courants d'associés : l'atelier du socle, au métier MOBDIE.** Une
  carte par associé — solde dû, rappel de l'ouverture « saisie, tenue hors
  journal », apporté/repris, historique récent avec solde cumulé,
  mini-courbe — avec les gestes sur place : « Apport » et « Récupération »
  ouvrent la saisie du journal pré-garnie (catégorie, tiers, libellé) et
  **n'écrivent rien tant que l'exploitant n'a pas validé** ; « Relevé PDF »
  par associé, dans la famille des documents de la maison. Le bandeau
  d'explication, le CSV global, le rattachement des orphelins et le relevé
  complet restent. Rien du métier salaires-primes du socle n'entre.
- **Dettes de financement : le bouton qu'on cherchait.** « Nouveau
  financement » en bouton primaire sur la liste, sur le tableau de bord des
  dettes et dans l'état vide en pleine page ; le prêteur se crée à la volée
  dans la fenêtre. Et la vraie cause réparée : `Roles::garantir()`, appelé
  par migration, ajoute `dettes.voir` et `tresorerie.gerer` aux rôles de
  gestion **sans écraser aucun réglage manuel** — la permission née après le
  seeding initial n'avait jamais atteint l'administrateur en production.

Une migration additive idempotente (permissions), aucune dépendance nouvelle,
aucun fichier déplacé ni supprimé. Forsa intact — avril 2026 non réglée reste
non réglée, le test le tient.

---

## v1.8.1 — La saisie des opérations fluide, et le tableau de bord des dettes

*[Rapport](docs/rapports/RAPPORT-V1.8.1.md) — 892 tests, 4 491 assertions.*

- **La saisie d'une opération à l'ergonomie du socle** : le TTC se saisit,
  HT et TVA calculés s'affichent, bascule « Sans TVA » (le taux à zéro — le
  modèle reste la seule source de calcul, la ventilation `reprise:ventiler-tva`
  n'est pas touchée). Tiers du répertoire, mode de règlement + référence,
  pièce jointe privée, sens en boutons. Filtre Tiers et colonnes
  règlement/PJ sur le journal. **Rien ne change aux écritures existantes** —
  un test recharge et sauvegarde : pas un centime ne bouge.
- **Le module « Dettes de financement »** : Forsa, premier pensionnaire —
  liste des financements (prêteur, capital, encours, prochaine échéance,
  état), création avec génération d'échéancier (dernière ajustable au
  reliquat, le modèle Forsa : 96 × 938, dernière 890), fiche-poste de
  travail (échéances, régler/détacher, arbitrage des versements — la règle
  gravée v1.6.2 inchangée, la page Forsa intacte).
- **Le tableau de bord des dettes**, page dédiée : encours par financement
  et global, 30 prochains jours, retard à J+1, versements à arbitrer, cumul
  remboursé / coût total — cache 60 s invalidé à l'écriture, requêtes
  bornées par test. Le tableau de bord principal n'est pas surchargé : sa
  carte « Dettes de financement » y renvoie désormais. L'écran des prêteurs
  s'appelle « Prêteurs ».

Deux migrations additives idempotentes, aucune dépendance nouvelle, aucun
fichier déplacé ni supprimé.

---

## v1.8.0 — La facture et le devis rejoignent la génération du socle

*[Rapport](docs/rapports/RAPPORT-V1.8.0.md) — 879 tests, 4 415 assertions.*

Le socle IRADA/RUWAD a refondu ses PDF de facture et de devis (v3.13 → v3.14) ;
MOBDIE reçoit la même expérience, en gardant intact tout son métier —
numérotation NN/AAAA, factures nées d'échéances, retenues. Aucun concept de
marché public n'entre.

- **Sections de lignes** (facultatives) : un « Sous-titre de section » sur les
  lignes ; les lignes consécutives de même titre forment un bandeau avec
  « Sous-total HT » masquable. **Numéros de lignes** masquables. Deux bascules
  par pièce, à OUI par défaut : sans action de l'exploitant, rien ne bouge.
- **PDF nouvelle génération**, facture ET devis : « FACTURE N° 36/2026 » sur
  une ligne, marges 1,0 cm, désignation 58-62 %, pied légal **2 lignes fixé au
  bas de chaque page**, cadre du cachet à taille de **tampon physique**
  (≥ 3,8 cm utiles, identique dans les deux densités), montant en lettres.
  Un avoir dit désormais « AVOIR ».
- **Densité adaptative** (`App\Support\DensitePdf`) : confort si la pièce
  tient sur une page, compact sinon, confort multi-pages au-delà — choisie en
  **mesurant le rendu réel**, jamais au nombre de lignes. Multi-pages propre :
  en-tête de tableau répété, pied partout, pas de bandeau orphelin.
- **Conversion devis → facture** : sections, sous-titres et préférences
  suivent ; la traçabilité ne bouge pas.
- **« Encaisser hors trésorerie »** : action explicite sur une facture émise,
  motif obligatoire — la facture passe encaissée **sans une seule ligne au
  journal** (ni transaction, ni échéance touchée), badge dédié, annulation qui
  restaure l'état. L'encaissement normal reste le chemin par défaut,
  strictement inchangé.

Deux migrations additives idempotentes, aucune dépendance nouvelle, aucun
fichier déplacé ni supprimé.

---

## v1.7.4 — Les défauts de la redevance, partout pareil

*[Rapport](docs/rapports/RAPPORT-V1.7.4.md) — 864 tests, 4 334 assertions.*

La v1.7.3 avait posé **600 HT / semestriel / 6 mois** sur *un* des trois
formulaires de création de contrat. L'assistant « Nouveau dossier » — le
chemin que l'exploitant emprunte le plus — et l'action « Ajouter un contrat »
d'un client existant ouvraient encore sur **Annuel / 12 / montant vide**.

- **Une seule source de vérité** : `REDEVANCE_PERIODICITE_DEFAUT`,
  `REDEVANCE_DUREE_MOIS_DEFAUT` et `REDEVANCE_MONTANT_HT_DEFAUT` sur
  `App\Support\Domiciliation`, le référentiel qui porte déjà les
  périodicités. Trois copies du même défaut ne peuvent plus diverger.
- **Les trois formulaires la lisent** — champ **et** valeur de repli, pour
  qu'aucun chemin ne reparte en douce sur l'ancien défaut. Le montant, qui
  n'était pré-rempli nulle part hors de la fiche client, l'est partout.
- **Rien d'autre ne bouge** : calcul TTC, TVA à 20 %, libellés, échéancier.
  Les trois valeurs restent modifiables — le logiciel propose, l'exploitant
  décide.

Aucune migration, aucune dépendance, aucun fichier déplacé ni supprimé.

---

## v1.7.3 — Le contrat épuré, deux pages, et la place pour le cachet Wraq

*[Rapport](docs/rapports/RAPPORT-V1.7.3.md) — 860 tests, 4 294 assertions.*

L'exploitant a signé et légalisé un vrai contrat via **Wraq**. Verdict à
l'usage : le contrat de la v1.7.1 en faisait trop et laissait mal la place —
Wraq appose elle-même son bandeau bas de page, son QR code et sa colonne de
référence verticale, et le bandeau recouvrait encore le pied de page.

- **Le bloc final épuré** : la rangée « Espace réservé à la signature
  électronique » disparaît (Wraq pose son propre cachet), les amorces
  « N° : …… » / « Date : …… » aussi, la mention « Signé électroniquement
  le … » aussi, et les paraphes avec. **Les deux cadres de légalisation
  restent** — c'est la commune qui y tamponne — mais vides.
- **La place pour le cachet Wraq** : marge basse 3,4 → **4,2 cm**, marge
  droite 2,2 → **2,4 cm**, pied de page et pagination remontés. Mesuré sur le
  rendu réel : l'encre de l'application s'arrête à **3,04 cm du bord**, la
  bande inférieure reste blanche sur toute la largeur.
- **Deux pages** (il en faisait trois) : cadres de signature 4,5 → 3,4 cm,
  de légalisation 5,5 → 3,6 cm, interligne du corps 1,6 → 1,45 et marges
  internes resserrées. Les règles de coupe ne changent pas — bloc final soudé
  à la chute du corps, clause financière insécable.
- **La génération ne demande plus** l'option « Bloc de signature
  électronique » : un contrat se génère toujours selon le même modèle.
  Restent le gabarit, les formats, le cachet et la date de signature.
- **Défauts de la redevance** : le formulaire de contrat s'ouvre à
  **600 DH HT, semestriel, 6 mois** — 720 DH TTC la période à 20 %. Simple
  pré-remplissage ; le calcul TTC ne change pas.

Aucune migration, aucune dépendance, aucun fichier déplacé ni supprimé ; le
corps des actes en base ne bouge pas.

---

## v1.7.2 — Le même ordre de lecture, des PDF qui se referment, une barre en moins

*[Rapport](docs/rapports/RAPPORT-V1.7.2.md) — 855 tests, 4 248 assertions.*

L'exploitant a arrêté une grille de lecture commune aux trois applications
(MOBDIE, IRADA, RUWAD) : l'argent compte par compte, l'argent en vue
d'ensemble, ce qui attend une décision, l'activité du mois, les courbes. Ce
lot aligne MOBDIE — et retire ce qui gênait.

- **Le tableau de bord dans l'ordre commun** : la vue d'ensemble de
  trésorerie remonte juste après la position du jour ; titres au patron
  « Thème — précision » (« Trésorerie — vue d'ensemble », « À traiter —
  relances, résiliations, conformité, dossiers », « Activité du mois —
  recouvrement ») ; la tuile « Trésorerie totale » se dit « Somme des
  comptes ci-dessus ». Aucun calcul ne bouge ; l'ordre complet des six
  widgets est verrouillé par test.
- **La barre d'accès rapides et les raccourcis clavier disparaissent**
  (demande explicite) : barre, script d'en-tête, `keyBindings`, aide, et les
  quatre actions qui ne servaient qu'elle — le mode relevé part avec.
  Restent `NouvelleFactureAction` (écrans factures) et
  `ContratClientExistantAction` (fiche client), sans raccourcis. Les
  catégories habituelles du trimestre servent désormais le formulaire du
  journal. Un test prouve l'absence.
- **Les PDF se referment** : lecteur de documents `GET /lecteur`
  (authentifié, `src` sur liste blanche de préfixes internes, 403 sinon) —
  barre « ← Retour / titre / Télécharger », bannière d'avertissement sur
  iPhone ; `?telecharger=1` sur toutes les routes PDF (même binaire, en
  `attachment`) ; tous les liens d'interface passent par le lecteur, dans le
  même onglet ; les états PDF du CPC et du journal rejoignent les exports
  des rapports comptables. La PWA ne change pas.
- **Lissage** : les statuts parlent la même couleur partout (brouillon gris,
  émise/envoyée bleu, payée vert, en retard orange, annulée/expirée rouge —
  une seule source pour les échéances et pour le statut de dossier, qui
  vivait en six copies) ; les tableaux vides proposent le geste de création
  (devis, factures, clients, contrats) ; verrou anti-défilement horizontal à
  390 px, descriptions longues coupées au mot, graphiques bornés à leur
  carte.

⚠️ Déploiement : huit fichiers à **supprimer** du serveur — la liste exacte
est dans le rapport.

## v1.7.1 — Le contrat laisse la place aux cachets

*[Rapport](docs/rapports/RAPPORT-V1.7.1.md) — 857 tests, 4 321 assertions.*

Un contrat revenu légalisé (13/08/2026) montrait les cachets de la commune
posés sur l'article 3 et sur le pied de page : rien ne leur était réservé, et
la signature électronique (Wraq, lois n° 43-20 et 53-05) ajoute d'office
bandeau, colonne de référence et QR code par-dessus le pied. L'enveloppe des
quatre actes donne désormais un cadre à chaque chose.

- **Les marges portent les servitudes** : droite à 2,2 cm (colonne de
  référence), basse à 3,4 cm en deux étages — paraphe et pied remontés, 12 mm
  vides pour le bandeau électronique ; numéro de page à gauche ; coin bas-droit
  de la dernière page (~4 × 4 cm) net pour le QR.
- **Le bloc final en trois rangées** : signatures (4,5 cm), cadres de
  légalisation par partie avec amorces N°/Date (5,5 cm), espace de la
  signature électronique (2,8 cm). Deux colonnes partout ; l'attestation, que
  le domicilié ne signe pas, n'en porte qu'une. Le contrat de référence passe
  à trois pages, plafonné par test.
- **Un bogue latent depuis la v1.3.7 réparé** : `detacherLaChute()` capturait
  le corps entier au lieu du dernier bloc — invisible tant que le bloc final
  se coupait librement, révélé par son insécabilité, corrigé par une regex
  gardée. La clause financière reste entière, la chute reste soudée aux
  cadres.
- **Verrous nouveaux** : les intitulés des cadres prouvés au rendu sur les
  quatre actes (deux légalisations, une pour l'attestation) ; devis et
  facture n'en portent aucun.

## v1.7.0 — Les pièces de la chaîne se parlent

*[Rapport](docs/rapports/RAPPORT-V1.7.0.md) — 855 tests, 4 300 assertions.*

Le verdict des premières semaines d'usage réel : échéanciers, devis,
factures, primes et opérations ne se parlaient pas assez. Le lot les fait se
répondre — le logiciel propose, pré-remplit, mais ne tranche jamais en
silence.

- **L'écran dit vrai tout de suite.** Toute écriture qui change l'argent
  oublie les caches du tableau de bord à l'instant (journal, encaissements —
  donc aussi comptes courants et remboursements Forsa) ; la clé par
  utilisateur des dossiers incomplets devient invalidable par un sel de
  version ; le TTL de 60 s reste en filet ; action d'en-tête « Actualiser ».
- **Le devis accepté propose la suite.** Notification d'acceptation à deux
  boutons (« Transformer en contrat », « Établir la facture »), boutons
  visibles sur la ligne d'un devis accepté, devis refusé ré-acceptable,
  devis transformé intouchable, « Dupliquer », et les devis envoyés échus
  passent à « Expiré » chaque matin par le planificateur.
- **La facture et l'échéancier ne se contredisent plus.** L'annulation d'une
  facture groupée détache toutes ses échéances, qui redeviennent
  facturables ; la contrainte de base sur le lien échéance → facture
  (posée en v1.6.1) est désormais prouvée par tests ; l'écriture d'un
  encaissement ou d'un versement de prime refuse la suppression directe du
  journal, avec le bon geste en face du refus.
- **La prime ne s'oublie plus — et ne se décide jamais seule.** Rappel
  immédiat (écran + cloche) quand un encaissement part sans prime alors que
  le barème en suggère une, bouton « Ajouter la prime » pré-rempli ;
  cinquième carte « Encaissements sans prime » dans « À traiter » ;
  `mobdie:generer-commissions` reste manuel.
- **Modifier, annuler, supprimer — le cadre qui rend la liberté tenable.**
  Une facture émise se modifie directement (décision du 15 août 2026) ;
  numéro et série verrouillés pour tous — la renumérotation
  super-administrateur de la v1.6.x disparaît, jamais de réattribution ;
  historique des modifications lisible sur la pièce (journal d'audit
  existant) ; facture payée modifiable et annulable par le flux guidé —
  annuler le règlement, modifier, ré-encaisser ; suppression inchangée
  (brouillons et devis seulement) ; le PDF se régénère avec les nouvelles
  valeurs.

## v1.6.2 — Avril n'était pas payé

*[Rapport](docs/rapports/RAPPORT-V1.6.2.md) — 829 tests, 4 159 assertions.*

Le prêt Forsa remis d'équerre, sur trois corrections énoncées par
l'exploitant — et la leçon gravée : l'affectation d'un versement à une
échéance est une décision de l'exploitant, pas une déduction du logiciel.

- **La logique des 950 DH disparaît.** L'échéance du prêt est 938 DH, point ;
  les frais bancaires varient et se saisissent à part, pour leur montant
  réel. Plus de mensualité ni de part de frais dans le modèle, en base ou à
  l'écran ; l'échéancier affiche 96 × 938 (dernière à 890, le reliquat) ; un
  montant différent s'enregistre tel quel et la ligne affiche l'écart sans le
  corriger d'office. Un test garantit qu'aucun code ne référence plus 950.
- **L'affectation se choisit à la saisie.** Partout où un remboursement
  Forsa s'enregistre, le sélecteur « Échéance réglée » — « n° 15 — avril
  2026, en retard de 4 mois » — se révèle, obligatoire. Pré-choix intelligent
  (le mois de l'opération, sinon la plus ancienne impayée), jamais
  silencieux, toujours révocable. Une opération ne règle qu'une échéance
  (contrainte en base), et supprimer ou requalifier l'opération rouvre
  l'échéance.
- **La page du prêt devient un poste de travail.** « Enregistrer un
  remboursement » en tête — l'opération au journal et l'échéance soldée en
  un geste —, « Régler cette échéance » et « Détacher » sur chaque ligne,
  date de règlement cliquable vers le journal, indicateurs recalculés sur
  les seules échéances réellement réglées.
- **L'existant remis en face de la réalité.**
  `reprise:reapparier-forsa-par-mois` ré-affecte chaque versement à
  l'échéance de son propre mois et rouvre ce qui ne tombe pas juste. Sur les
  données réelles : avril 2026 et septembre 2025 ressortent impayées,
  16 réglées au lieu de 18, capital restant 74 992 DH, neuf versements
  laissés à l'arbitrage. La carte du tableau de bord montre la plus ancienne
  impayée, avec son retard — plus jamais un trou lissé.

## v1.6.1 — Le courrier entre, le quotidien aboutit, les données disent vrai

*[Rapport](docs/rapports/RAPPORT-V1.6.1.md) — 823 tests, 4 117 assertions.*

Le plus gros lot du projet, en trois parties. Aucune dépendance composer
ajoutée.

- **La messagerie devient un outil complet.** Tout envoi passe par la file
  d'attente — trois essais à attente croissante, échec franc posé au premier
  essai avec sa raison en français, « Renvoyer » au registre — et le registre
  du courrier devient l'historique complet : HTML conservé tel que parti,
  signature, pièces, fil de conversation, tous les canaux (relances,
  documents, formulaire public, alertes). Joindre depuis le dossier (pièces,
  factures et devis avec ou sans cachet, poids annoncé), brouillons
  explicites, envoi programmé annulable, envoi groupé à un message par
  destinataire — variables propres, aperçu par exemplaire, sans-adresse
  nommés avant l'envoi, débit maîtrisé, compte rendu nominatif.
- **Et la réception entre dans l'application** : un client IMAP maison sur
  l'extension PHP imap (absence expliquée à l'écran, tout le reste
  fonctionne), relève incrémentale par UID toutes les cinq minutes sans
  jamais toucher à la boîte, rattachement par fil (In-Reply-To) puis par
  adresse, « À classer » avec mémorisation, boîte de réception avec badge de
  non-lus, HTML nettoyé et images distantes bloquées, pièces jointes par
  route authentifiée, réponse pré-remplie dans le fil, et rebonds qui
  marquent l'adresse morte et re-routent la relance en « contact à
  corriger ».
- **Le quotidien aboutit** : « Saisir le contact » débloque la relance sur
  place et l'écran écrit ce que c'est au lieu d'un tiret ; plus jamais de
  ligne anonyme (raison sociale → représentant → code) ; les badges comptent
  la liste qui s'ouvre ; le retard commence à J+1 partout (Forsa, factures,
  widgets) ; l'ancienneté s'écrit d'une seule main ; « À sortir » regroupe
  par client ; la cloche annonce le matin et sonne les incidents (sauvegarde,
  caisse négative, analyse IA) ; le mode relevé verrouille le compte,
  enchaîne les dates et tient le compteur de session ; l'application
  s'épingle sur l'écran d'accueil du téléphone.
- **Les données disent vrai** : un client actif n'a plus de date de sortie au
  registre légal (la fin de contrat d'un dossier vivant n'est pas une
  sortie) ; reprise:expliquer-la-caisse montre le premier passage sous zéro
  (op. n° 1769 du 05/06/2026) et la garde forçable protège la suite ; les
  séries de charges se rapprochent par tiers + catégorie et le loyer coupé
  par un changement de libellé se recoud ; reprise:normaliser-les-tiers
  fusionne les doublons et pose une casse lisible ; ICE à quinze chiffres
  (refusé à la saisie, complété à l'import), pointillés de gabarit nettoyés,
  civilité en liste fermée, dates de pièce invraisemblables alertées ; une
  facture réglée dit « Réglée le X », une facture née après son échéance
  prend sa date d'émission comme limite ; l'archive distingue PDF et Word,
  reprise:dedoublonner-archive résorbe les doubles stricts et nomme les
  pièces sans client.

## v1.6.0 — Les dix premières secondes

*[Rapport](docs/rapports/RAPPORT-V1.6.0.md) — 788 tests, 3 893 assertions.*

Premier lot de la refonte UX : la langue, la vitesse, la recherche, le menu,
les écrans qui débordent. Les gestes d'encaissement et de saisie ne bougent pas.

- **Le français est complet.** Les 118 clés absentes du paquet français de
  Filament sont complétées sous `lang/vendor` : plus de
  `filament-tables::table.result_count` sur les listes ni de clés d'icônes sur
  les Résiliations. Un test anti-clés-brutes rend les écrans touchés et échoue
  à la première clé — la garantie que la prochaine mise à jour de Filament ne
  ramènera pas le problème. Au même passage : « Total général » remplace
  « Tous Factures » et « Tous domiciliation installments », le journal d'audit
  dit « Devis » et « Modèle de message » au lieu de « Quote » et
  « EmailTemplate », la pagination écrit « 1 845 » à la française, et les
  comptes s'affichent « Caisse » / « Banque ».
- **Le tableau de bord ouvre plein.** Position du jour et Recouvrement se
  rendent avec la page au lieu d'arriver en squelettes ; les calculs partagés
  — soldes, trésorerie, restes dus, compteur de complétude — passent par un
  cache d'une minute (`TableauDeBord`) : les widgets se servent au même plat au
  lieu de recuisiner chacun. Le triple `resteDu()` par prêteur disparaît. Les
  requêtes de l'ouverture sont bornées par un test.
- **La recherche globale trouve** : clients (raison sociale, code, ICE, RC,
  représentant, téléphone), factures et devis (numéro, client — « Facture
  21/2026 — LOVEGROVE », montant et date), opérations du journal (tiers, note),
  tiers (nom, ICE). Le périmètre du commercial tient aussi au ⌘K : l'ICE exact
  du client d'un collègue ne renvoie rien.
- **Le menu revient à l'essentiel** : « Changer mon mot de passe » vit sous
  l'avatar ; un groupe **Paramétrage** replié accueille ce qu'on ne règle
  qu'une fois (catégories, barèmes, gabarits, modèles, signatures, adresses,
  charges récurrentes, analyses IA, utilisateurs, permissions, audit) — 26
  entrées visibles au lieu de 37 ; les collisions de tri sont toutes
  dédupliquées, et un test interdit d'en réintroduire.
- **Les écrans qui débordaient** : la liste des Clients tombe à six colonnes
  par défaut (les autres s'activent d'un clic) et gagne un vrai tri par défaut
  — les plus récents d'abord — qui rend les en-têtes de colonnes de nouveau
  opérants ; la fiche client n'a plus qu'une barre d'onglets (le Résumé se lit
  de haut en bas, courrier et historique repliés) ; les quatorze onglets des
  Réglages passent en colonne verticale.
- **Le wizard compte quatre étapes** : « L'IA lit les pièces » n'était pas une
  décision, c'était une attente — « Vérifier » l'absorbe, la barre de
  progression remplit les champs à mesure sans jamais écraser une saisie.
- **Micro-conforts** : le mode de paiement se mémorise en session comme le
  compte, sur les quatre formulaires de paiement ; « Encaisser une échéance »
  ne charge plus qu'une fois son lot de trois cents lignes ; la colonne
  « Prochaine échéance » colore en rouge les dates passées et dit en infobulle
  que c'est la plus ancienne échéance impayée.

## v1.5.5 — Qui signe, de quelle plume, et ce qui arrive intact

*[Rapport](docs/rapports/RAPPORT-V1.5.5.md) — 774 tests, 3 853 assertions.*

- **La mention « dans le cadre de votre dossier de domiciliation » disparaît**
  des deux gabarits qui la portaient : fausse dès que le destinataire n'est pas
  un domicilié, inutile quand il l'est. Le pied garde les mentions de la
  société, qui suffisent.
- **Des signatures enregistrées.** Une liste « Signatures » dans le groupe
  Messagerie : un nom, un contenu écrit avec le même éditeur que le corps —
  variables `{{expediteur}}`, `{{fonction}}`, `{{telephone}}` comprises, image
  en pièce intégrée et non en lien externe —, une signature par défaut, et une
  seule. Trois sont livrées : complète, courte, neutre. À l'envoi, un sélecteur
  pré-rempli, « aucune » comme choix possible, l'aperçu qui la montre en place ;
  chaque modèle de message peut désigner la sienne, proposée au chargement sans
  jamais écraser un choix déjà fait. Le registre du courrier retient quelle
  signature accompagnait chaque envoi.
- **L'éditeur s'enrichit sans devenir une usine** : souligné, barré, alignement,
  couleur parmi cinq teintes de la marque — le sélecteur libre est fermé —,
  image intégrée, annulation. Un seul éditeur (`EditeurDeCourrier`) pour la zone
  d'envoi, les modèles et les signatures ; un seul contrat de balises
  (`CorpsHtml::BALISES`) et de couleurs (`Palette`) entre la barre, le nettoyage
  et l'habillage : ce qu'on voit dans l'éditeur est ce qui arrive dans la boîte.
- **Le collage depuis Word ressort propre** : chaque balise conservée est
  réécrite, seuls les attributs déclarés survivent — les classes « Mso », les
  polices et les commentaires conditionnels meurent, le centrage et le gras
  survivent. Et **l'arabe se lit de droite à gauche**, à la saisie comme chez le
  destinataire (`dir="auto"` sur chaque bloc).
- **Neuf modèles au lieu de cinq**, structurés — montants en évidence, listes
  pour les pièces — et complétés des situations réelles : accusé de réception
  d'une demande, échéance à venir, confirmation d'encaissement, renouvellement,
  résiliation en courrier formel. Chacun avec sa mise en page et sa signature
  attitrées. Un modèle retouché par l'exploitant n'est jamais réécrasé.

## v1.5.4 — Un écran, une décision

*[Rapport](docs/rapports/RAPPORT-V1.5.4.md) — 750 tests, 3 697 assertions.*

- **Le recouvrement devient un poste de travail.** Six étapes en onglets, nommées
  par le geste qu'elles appellent et non par leur ancienneté : à venir, à
  relancer, à rappeler fermement, à mettre en demeure, à trancher, à sortir.
  Chacune porte une action dominante — « relancer les 21 », « mettre en demeure
  les 13 » —, des colonnes choisies pour sa décision, et un en-tête qui dit
  l'enjeu en une phrase et deux chiffres. « À sortir » est gris et non rouge :
  une créance de quatorze mois appelle une décision, pas un réflexe.
- **Les impayés se lisent en deux parts, partout** — tableau de bord compris :
  ce qui est raisonnablement recouvrable, et ce qui est à solder. Un chiffre
  unique décourage et n'appelle aucun geste.
- **Les quatre bornes — 30 jours, 3, 6 et 12 mois — sont des réglages**, lus par
  un seul endroit qui fait autorité. Le retard commence le lendemain de
  l'échéance : le jour même, le client a jusqu'au soir.
- **Un dossier clos cesse de réclamer de l'argent.** Un dossier annulé n'a jamais
  pris effet : ses échéances non réglées sont annulées. Un dossier résilié a
  existé : ce qui était dû avant la date d'effet reste dû, seule la suite est
  annulée. Les encaissements antérieurs ne sont jamais touchés, et une échéance
  annulée porte sa date et son motif. `php artisan reprise:assainir-les-echeances`
  rattrape l'existant, avec `--simulation`, et nomme les dossiers résiliés sans
  date d'effet plutôt que de les taire. Le statut du dossier figure désormais sur
  chaque ligne d'échéance.
- **La fiche client ne déborde plus de l'écran** : quatre gestes du quotidien en
  évidence, le reste derrière un menu « Autres actions » — un intitulé, jamais
  trois points muets. La page « Modifier » suit.
- **Le logo et le pied de page survivent au thème sombre** : bascule vers un logo
  à texte blanc par `prefers-color-scheme`, déclarations `color-scheme` et
  `supported-color-schemes`, et un fond clair posé en attribut pour les clients
  qui forcent l'inversion et ignorent la requête de média.

## v1.5.3 — Ce qui se déduit, ce qui s'écarte, et ce qui s'annonce

*[Rapport](docs/rapports/RAPPORT-V1.5.3.md) — 723 tests, 3 535 assertions.*

- **Le mois, le groupe et le poste CPC d'une opération sont déduits par le
  modèle**, à l'enregistrement, quel que soit le chemin de création. Ils étaient
  posés par un effet de bord du formulaire, qui ne se déclenchait que si l'on
  touchait au champ : quatre opérations de juillet sont nées sans mois, et le
  tableau de bord est tombé dessus. Aucune opération ne peut plus être
  enregistrée avec un poste CPC vide. `php artisan reprise:reparer-les-mois`
  rattrape l'existant, avec `--simulation`.
- **Le « Résultat du mois » et le « Résultat 2026 » passent par le même calcul**,
  borné sur la date des deux côtés. Ils divergeaient de 4 585,16 DH — l'un lisait
  la colonne stockée, l'autre la date. La somme des douze mois d'un exercice égale
  désormais son résultat par construction, et un test le vérifie.
- **Un graphique ne meurt plus sur une donnée aberrante.** Les mois illisibles
  sont écartés de la courbe, comptés, et le graphique dit sous lui combien
  d'opérations il a laissées de côté et pourquoi. L'échec est local et visible,
  jamais total et muet.
- **Six indicateurs en tête du tableau de bord** : la caisse, la BP et l'Attijari
  chacune pour elle-même avec sa variation depuis le 1er du mois, les comptes
  courants d'associés détaillés par associé, les dettes de financement par
  prêteur, et la prochaine échéance du prêt Forsa. Le recouvrement reste, après.
- **Les charges à venir, calculées puis expliquées.** Les trente-six derniers mois
  du journal sont relus, les charges qui se répètent identifiées par catégorie et
  par tiers, et leurs prochaines échéances déduites — chacune ouvrable sur les
  opérations qui la fondent. L'IA n'intervient qu'après, pour mettre en mots ce
  que le calcul a trouvé : elle ne produit aucun chiffre, et sa réponse est
  rejetée si elle en avance un que le calcul ne portait pas. Une série
  manifestement régulière peut être inscrite en charge récurrente déclarée — c'est
  une proposition, aucune écriture n'est créée.

## v1.5.2 — Ce qui se lit, ce qui se règle, et ce qui s'affiche

*[Rapport](docs/rapports/RAPPORT-V1.5.2.md) — 692 tests, 3 384 assertions.*

- **Le libellé des opérations au journal.** Le champ portait l'essentiel de
  l'information — « from domiciliation », « pour cnss » — et ne s'affichait
  nulle part. Colonne ajoutée, tronquée avec infobulle, cherchable ; les autres
  listes d'opérations sont alignées.
- **Une facture émise pour une échéance déjà encaissée naît payée**, avec la
  date et le mode de règlement du paiement, et sans écriture de trésorerie
  supplémentaire : l'argent est déjà au journal. Aucune facture réglée ne porte
  plus le badge « En retard », quel que soit son chemin de création.
- **Les pièces d'identité photographiées** sont acceptées, converties en PDF à
  l'enregistrement — la photo d'origine conservée à côté —, redressées d'après
  l'orientation EXIF, et refusées avec un motif quand elles sont trop petites ou
  trop floues pour être lues.
- **Un groupe Messagerie**, entre Domiciliation et Facturation : écrire n'est pas
  un geste de domiciliation. Les adresses d'expédition restent en Administration.
- **Le sélecteur d'adresse d'expédition reste visible** même sans aucune adresse
  enregistrée : il annonce l'expéditeur du fichier de configuration et mène à
  l'écran de création. Un réglage qu'on ne peut pas trouver n'existe pas.
- **L'en-tête des e-mails** passe au fond blanc, logo couleur à fond transparent
  et filet violet — fini le carré blanc du logo opaque sur le bandeau.
- **Le jeu complet d'icônes d'onglet**, celui du site officiel : `.ico`, PNG par
  taille, icône iOS et manifeste web.
- **L'avatar est dessiné localement** — les initiales sur une couleur de la
  marque — au lieu d'être demandé à un service extérieur qui ne répond pas.

## v1.5.1 — Le courrier devient un outil, et le code se range par sujet

*[Rapport](docs/rapports/RAPPORT-V1.5.1.md) — 676 tests, 3 273 assertions.*

- **Plusieurs adresses d'expédition.** L'exploitant choisit à l'envoi depuis
  quelle adresse le message part, et en ajoute une sans redéploiement. Le mot de
  passe du serveur sortant est chiffré en base, jamais réaffiché, jamais
  journalisé, jamais exporté. Un bouton « Tester » tente la connexion réelle et
  rapporte l'erreur du serveur en clair.
- **Trois mises en page de message** — sobre, en-tête de marque, courrier formel
  —, réglables (logo, signature, mentions légales, bouton d'action). Éditeur
  limité au gras, à l'italique, aux listes, aux liens et aux titres. Aperçu du
  rendu final, basculable entre écran large et téléphone.
- **Mise en forme assistée par l'IA.** Elle structure ce qui est écrit et
  n'invente rien : tout chiffre ou toute date absents du texte d'origine font
  rejeter la proposition. Le résultat remplit l'éditeur, il ne s'envoie pas.
- **Rangement du code par domaine.** Courrier, Facturation et Comptabilité
  portent désormais leurs modèles, leurs services, leurs écrans et leurs tests.
  Voir [ARCHITECTURE.md](ARCHITECTURE.md).
- **Règles ramenées à un seul endroit** : les pièces exigées d'un dossier, et le
  reste dû d'un compte courant.

## v1.5.0 — Ce qui expose, ce qui ment, et ce qui ne se rejoue pas

*[Rapport](docs/rapports/RAPPORT-V1.5.0.md) — 630 tests. Aucune fonction nouvelle.*

- Les pièces d'identité ne s'énumèrent plus : policy avec périmètre du
  commercial, clé publique aléatoire dans les adresses.
- Corbeille sur le journal comptable et sur les pièces ; effacement définitif
  réservé à une permission dédiée.
- Autorisation stricte de Filament et trente-six policies, là où il y en avait
  deux.
- `mobdie:restaurer` relit une archive de sauvegarde ; chaque exécution écrit son
  résultat en base, et l'absence de sauvegarde depuis 36 h devient une alerte.
- Trois essais sur les seules erreurs transitoires de l'IA, balayage des analyses
  figées, plafond mensuel de dépense.
- Un e-mail qui ne part pas ne fait plus échouer l'action qui l'a déclenché.
- Agrégats mémorisés, agrégations SQL, index manquants posés.
- Douze commandes de reprise passent sous le préfixe `reprise:`.

## v1.4.9 — La prime se décide, elle ne se calcule pas

*[Rapport](docs/rapports/RAPPORT-V1.4.9.md)*

La prime d'apport se saisit à l'encaissement plutôt que de se déduire d'un
barème : ce n'est pas ainsi que la maison travaille. Correction d'un widget qui
cassait le tableau de bord.

## v1.4.8 — Ce qui se signe, ce qui se compte, ce qui s'écrit, ce qui prend rang

*[Rapport](docs/rapports/RAPPORT-V1.4.8.md)*

La facture ne se signe plus. Commissions, zone d'envoi de messages, assistance
IA, et contrôle de l'intégrité de la série des factures.

## v1.4.7 — Le cachet se remplace, la référence redevient « 35/2026 »

*[Rapport](docs/rapports/RAPPORT-V1.4.7.md)*

Le cachet devient un réglage téléversable, servi derrière l'authentification.
La référence imprimée abandonne le préfixe de série. Reprise des factures
antérieures à la plateforme.

## v1.4.4 — Ce qu'on retire, et pourquoi

*[Rapport](docs/rapports/RAPPORT-V1.4.4.md)*

Inventaire des écrans et des textes retirés, avec pour chacun sa raison.

## v1.4 — L'ergonomie remise sur les gestes du métier

*[Rapport](docs/rapports/RAPPORT-V1.4.md) — 374 tests.*

Refonte des parcours autour des gestes réels : échéancier global, dossiers
incomplets, actions rapides, assistant de nouveau dossier.

## v1.3.8 — L'échéancier global ne tombe plus au tri

*[Rapport](docs/rapports/RAPPORT-V1.3.8.md)*

Sur 206 échéances, 167 portaient un `invoice_id` que ne suivait aucune facture.
Pas de relation, pas de lien : les quatorze endroits qui fabriquaient une adresse
depuis une relation passent par un point unique.

## v1.3.7 — Les signatures ne se retrouvent plus seules

*[Rapport](docs/rapports/RAPPORT-V1.3.7.md)*

Mise en page des contrats : un article se coupe librement, seuls le titre et les
orphelines sont protégés.

## v1.3.6 — Le devis ne compilait pas

*[Rapport](docs/rapports/RAPPORT-V1.3.6.md)*

## v1.3.5 — L'assistant échouait sur la moitié qui n'avait pas été regardée

*[Rapport](docs/rapports/RAPPORT-V1.3.5.md)*

## v1.3.4, v1.3.2, v1.3.1 — Le téléversement qui n'aboutissait pas

*[v1.3.4](docs/rapports/RAPPORT-V1.3.4.md) · [v1.3.2](docs/rapports/RAPPORT-V1.3.2.md) · [v1.3.1](docs/rapports/RAPPORT-V1.3.1.md)*

Trois versions pour une seule cause, démontrée par sonde : l'écriture *par flux*
n'aboutissait qu'une fois sur treize, sans lever la moindre exception. L'échec
passait inaperçu parce que l'interface lisait la taille dans la fiche `.json` et
jamais sur le fichier.

## v1.3.0 — Documents, IA et conformité

*[Rapport](docs/rapports/RAPPORT-V1.3.md)*

## v1.2.0 — Facturation, trésorerie et automatisation

*[Rapport](docs/rapports/RAPPORT-V1.2-2026-07.md)*

## v1.1.0 — Refonte ergonomique

*[Rapport](docs/rapports/RAPPORT-UX-2026-07.md)*

## v1.0.0 — Mise en service

*[Rapport](docs/rapports/RAPPORT-FINAL.md)*

Domiciliation, facturation, comptabilité, documents et conformité réunis dans un
seul outil à l'adresse `/admin`.
