---
suivi: 1556
date: 2026-09-15
sujet: Chaînage dossier foncier ↔ programme
chantier: foncier / programmes
type: feature
statut: poussé
hash: 943d78a1
fichiers:
  - database/migrations/2026_09_15_140000_add_programme_id_to_dossiers_fonciers.php
  - app/Support/Foncier/DossierProgrammeLink.php
  - app/Support/Foncier/DossierFoncierTabs.php
  - app/Models/Programme.php
  - app/Models/DossierFoncier.php
  - app/Http/Controllers/ProgrammeController.php
  - app/Http/Controllers/ProgrammeFoncierController.php
  - app/Http/Controllers/Foncier/DossierFoncierController.php
  - app/Http/Controllers/Foncier/DossierFoncierPosteBudgetaireController.php
  - app/Http/Middleware/HandleInertiaRequests.php
  - routes/web.php
  - resources/js/Layouts/AppShell.vue
  - resources/js/Pages/Foncier/Dossiers/Show.vue
  - resources/js/Pages/Programmes/Create.vue
  - resources/js/Pages/Programmes/Foncier.vue
  - resources/js/Composables/useTabAnchor.js
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - tests/Unit/DossierFoncier1448SourceTest.php
  - public/build/
---

# SUIVI #1556 — PHASE 2 chaînage dossier foncier ↔ programme

## PROMPT ENVOYÉ

Liaison `dossiers_fonciers.programme_id` UNIQUE. Boutons Associer / Créer /
Dissocier (admin). Hub FONCIER voie C. Corriger `prochainCode` (#1519).
Retirer l’onglet FACTURATION. Pas de rattachement auto, pas de destination
PROJET, pas de fusion ACL.

## FICHES LUES

- **#1555 LEÇON** — UNIQUE + SoftDeletes interdit la FK côté programmes.
  ObjectSubNavBar générique ; Show.vue n’est pas le hub. Barres AppShell
  mutuellement exclusives. Droits non recouvrants. Impact : FK côté dossier,
  page `Programmes/Foncier.vue` dédiée, `foncier_tab_visible` serveur.
- **#1519 LEÇON** — `prochainCode` sans `withTrashed` → 500. Impact : corrigé
  ici (générateur + preview + catch 1062).
- **#1448 LEÇON** — pas de droit par onglet. Postes XOR conservés. Impact :
  routes CRUD postes conservées ; onglet UI retiré.
- **#1351 / #1104** — patron CHANTIER Teleport + AppShell zone commune.
  Impact : rebase avant build ; hôte `#foncier-subnav-host`.
- **#1512** — RecordHabilitationScope vs ProgrammeAccessService. Impact :
  voir un programme ≠ voir le dossier.

## SYNTHÈSE

Voie C **tenue**. Hub mince : barre programme + `ObjectSubNavBar`
`tone=surface`, référence/libellé dans le corps, contenu des 7 onglets
(sans Accès ni Facturation). Mutations lourdes (nouvelle offre, etc.)
restent sur la fiche dossier / les deep links.

## DÉPLOIEMENT-TEST

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

## LEÇON

Ne jamais rendre `Foncier/Dossiers/Show` sous un programme : AppShell
échange alors la barre gold. `foncier_tab_visible` doit venir du serveur
(`userCanViewRecord` via `m365GroupNames()` brut). Soft-delete programme
= NULL la FK dans la même transaction, l’UNIQUE MySQL ignore `deleted_at`.
