---
suivi: 1311
date: 2026-08-13
sujet: programme_dates_cles_travaux
chantier: marches_compta
type: feature
statut: poussé
hash: b4dc6729
fichiers:
  - database/migrations/2026_08_13_120000_add_dates_cles_travaux_to_programmes_table.php
  - app/Models/Programme.php
  - app/Http/Controllers/ProgrammeController.php
  - resources/js/Pages/Programmes/Edit.vue
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1311_dates_cles_travaux.md
---

## PROMPT ENVOYÉ

Première brique libération RG : dates clés programme (démarrage + réception travaux),
onglet Dates clés après Infos, validation nullable|date, échéance informative +1 an.
HEAD attendu #1317 (b44d5edf). Pas de logique de libération.

## SYNTHÈSE

### Fiches lues
- `#1309` LEÇON : `date_livraison_prevue` = livraison commerciale — **non détournée** ;
  `programme_etapes` = jalons chronologie (autre sémantique) ; onglet dans Edit.vue.

### Colonnes vs `programme_etapes` (choix retenu)
`programme_etapes` = N jalons liés à `etapes_modeles`, avec `date_prevue` / `date_reelle`,
statut, justificatif SharePoint, déclencheurs de situation. Ce n’est **pas** le couple fixe
« démarrage + réception unique du programme » décidé par Robin. Mapper deux jalons modèles
serait fragile (enseignes / modèles différents) et mélangerait sémantiques. → **colonnes
dédiées** sur `programmes`, comme recommandé au #1309.

| Colonne | Signification | Nullable |
|---------|---------------|----------|
| `date_demarrage_travaux` | Démarrage des travaux du programme | oui |
| `date_reception_travaux` | Réception des travaux (une seule / programme) | oui |

Distinct de `date_livraison_prevue` (livraison commerciale).

### Persistance
Règles `nullable|date` dans `ProgrammeController::update` + `array_key_exists` + `?: null`
pour remonter à NULL si champ vidé. Payload Inertia edit enrichi. Fillable + casts modèle.

### Vérification écran
À documenter après tests migrate/DB (MariaDB local port 3307).

## DÉPLOIEMENT-TEST

```bash
git pull origin main
php artisan migrate --force
php artisan optimize:clear
php artisan view:clear
php artisan journal:sync
```

## LEÇON

Ne pas réutiliser `date_livraison_prevue` ni forcer un couple métier dans `programme_etapes`
(jalons multi-étapes). Colonnes dédiées explicites. Un champ date vidé doit être posté
(chaîne vide) sinon Laravel ne le voit pas et le NULL n’est jamais écrit (#1279 / #1315).
