---
suivi: 1513
date: 2026-09-10
sujet: Fix persistance dossier/poste Projet à Valider
chantier: factures / depot / destination-projet
type: bugfix
statut: poussé
hash: c2bd7c0f
fichiers:
  - app/Support/DepotFactureProjetAncrage.php
  - app/Http/Controllers/DepotFactureController.php
  - app/Services/DepotFactureEngagerWorkflowService.php
  - tests/Unit/DepotProjetPersistanceValider1513SourceTest.php
  - tests/Unit/DepotProjetPersistanceValider1513Test.php
  - docs/suivi/SUIVI_1513_fix_persistance_dossier_projet_valider.md
---

# SUIVI #1513 — PHASE 2 : persistance dossier/poste Projet à l’engagement

## PROMPT ENVOYÉ

Fix serveur. Cause #1511 : `valider` / `validerHistorique` / `EngagerWorkflowService`
n’écrivent pas `dossier_foncier_id` ni `poste_budgetaire_type_id` (colonne + JSON).
Helper unique partagé avec `applyDepotSaisieFromValidated`. Pas de reprise 1817/1821.
Pas de Vue. Push `origin/main`.

## BASE GIT

Rebasé sur `origin/main` = `ecd8b99d` (chore hash fiche #1512). HEAD de départ
du prompt (`91294570`, fiche #1511) périmé : #1512 diagnostic (aucun code
applicatif) est déjà sur main. `DepotProjetDossierService` et
`DepotProjetDossierFields.vue` non touchés.

## FICHES LUES

- **#1511 LEÇON** — Valider reconstruit `ocr_raw.saisie` par liste blanche et oublie
  les clés ; les gardes voient le request. Impact : helper unique sur les trois
  persists + le brouillon, pas de fix UI.
- **#1505 LEÇON** — branchement brouillon colonne + JSON. Conservé, délégué au helper.
- **#1492 LEÇON** — `required_if` / `prohibited_unless` / asserts. Non retouchés.
- **#1506 LEÇON** — sélection AutoComplete. Hors cause.
- **#1507 LEÇON** — onglet Projet = colonne FK. Le fix de colonne suffit à faire
  réapparaître une facture nouvellement validée (pas 1821, reprise manuelle).

## FIX

`App\Support\DepotFactureProjetAncrage` :

- `depuisValidated` : PROJET → ids positifs ; sinon les deux NULL.
- `appliquerSaisie` : pose `dossier_foncier_id` toujours ; `poste_budgetaire_type_id`
  seulement si PROJET (ne pas écraser un poste PROGRAMMES hors marché).
- `appliquerColonnes` : idem sur le tableau `$updates` — pas un rewrite de `ocr_raw`.

Appelants : `applyDepotSaisieFromValidated`, `valider`, `validerHistorique`,
`DepotFactureEngagerWorkflowService::engagerAvecWorkflow`.

Aucun `JSON_SET` / `JSON_QUOTE`. Cast `ocr_raw => array` inchangé.
`cloturerSiValidationEnAttente` (#1489) toujours en fin d’apply.
Gardes #1492 inchangées.

## PIÈGE `??` L5213

Toujours présent dans `assertDestinationProjetCoherence` : un `null` posté retombe
sur le dépôt. **Signalé, non corrigé** — hors périmètre persistance, et ce n’était
pas la cause de 1821. Un `array_key_exists` serait le filet ; lot ultérieur.

## REPRISE

Aucune. Robin corrige 1821 et 1817 à la main après déploiement.

## SIGNALEMENT AVAL (non traité)

1821 reste **comptabilisable** : `ComptabilisationController` sans `Rule::in`
destination, aucun contrôle dossier/poste pour PROJET, `comptabiliser()` L662
sans garde Projet. Étape 5 CLASSID.

## JOURNAL

Aucune entrée (correctif invisible une fois la saisie persistée).

## DÉPLOIEMENT-TEST

    git pull origin main
    php artisan optimize:clear
    php artisan view:clear

Pas de migrate. Pas de route:clear. Pas de journal:sync. Pas de npm.

Robin : rejouer (a) en prod — destination Projet, Valider **sans** Enregistrer,
relire colonne + `ocr_raw.saisie`. Ne pas modifier 1817/1821 via un script.

## LEÇON

Deux persists (brouillon vs engagement) : une liste blanche d’overlay doit
recevoir **chaque** clé métier au même endroit. Un helper unique évite de
n’en brancher qu’une. `required_if` ne prouve pas l’écriture.
