# Suivi PR-A1 — Train A (R1, R2, R12)

Objectif: Unifier les mutations via /api/commands (chemin de compat), standardiser le contrat JSON (helpers Response::ok/error), activer le signal de normalisation sous flag.

Décisions de l’itération:
- Compat REST→bus activé via `REST_MUTATIONS_FALLBACK=true` (voir `.env.audit-v4`).
- Normalisation enveloppe JSON signalée uniquement si `ENVELOPE_SMOKE=true` (dev).
- MySQL only confirmé (bootstrap empêche SQLite).
- Non-Board Bus adopté: bus dédié pour `Board.* (CRUD)`, `Account.*`, `File.*`, `PackDataset.*` avec handlers par intention. `CommandController` aminci (parse/valide/dispatch).

Portée et actions:

R1 — Mutations uniquement via /api/commands (compat)
- [x] Non‑Board Bus + handlers par intention pour Board./Account./PackDataset./File.
- [x] `CommandController` aminci: délègue au Non‑Board Bus (plus de glue interne).
- [x] Routes REST mutantes renvoient 410 (suppression de la compat): passage strict par `/api/commands`.

R2 — Contrat JSON canonique
- [x] Helpers `Response::ok(...)` et `Response::error(code, message, details?, status)`.
- [x] Contrôleurs mis à jour (succès/erreurs) :
  - `BoardController.php`
  - `BoardRulesController.php`
  - `UserFilesController.php`
  - `AccountController.php`
  - `AuthController.php`
  - `PacksController.php`
  - `NotificationController.php`
  - `ActivationController.php`
  - `RulesExplainController.php`
- [ ] Contrôleurs Admin (reste à traiter en R2-b) : `Admin/*`.

R12 — Signal de normalisation
- [x] Retrait du header `X-Envelope-Normalized` et de la normalisation automatique dans `Response::json` (pas de parachute; réponses canoniques via `Response::ok/error`).

Outils / CI
- [x] `tools/ci/guards.sh` (WARN) — greps legacy et erreurs non canoniques.
- [x] `tools/smoke/audit-v4-smoke.sh` — appels basiques de smoke.
- [x] `.env.audit-v4` — flags: `REST_MUTATIONS_FALLBACK=true`, `ENVELOPE_SMOKE=true`.

Notes & prochains pas
- Poursuivre la migration des contrôleurs Admin vers le contrat canonique.
- Purge finale: une fois le front migré à 100% sur `/api/commands`, mettre `REST_MUTATIONS_FALLBACK=false` puis supprimer les routes REST mutantes.

Décision documentée — Non‑Board Bus

Pourquoi: éliminer le double flux (REST mutateur) côté fichiers/comptes/packs et garder un contrôleur maigre. Aligner la pile hors-board sur le même pattern que Board (commande → handler) sans toucher aux invariants du moteur.

Comment: création d’un `NonBoardBus` avec enregistrement de handlers:
- Board.Create/Rename/Delete → BoardCatalog
- Account.Logout/UpdateProfile/RequestVerification/Verify/RedeemLicense → Auth/Account/EmailVerification
- File.Compose/Upload/UpdateContent/Rename/Delete → UserFileService
- PackDataset.Upsert/Delete → DatasetStore (avec ETag)

Transition: pendant la migration, les anciennes routes REST mutantes peuvent forwarder vers `/api/commands` (flag `REST_MUTATIONS_FALLBACK=true`) pour éviter les régressions. Une fois le front migré, on désactive le flag et on supprime les routes REST.
