---
suivi: 1814
date: 2026-10-07
sujet: Tableau de bord campagne et purge RGPD monprojet
chantier: monprojet
type: feature
statut: poussé
hash: 94083ee9b
fichiers:
  - docs/suivi/SUIVI_1814_monprojet_tableau_de_bord_purge.md
  - database/migrations/2026_10_07_150000_add_anonymisee_le_to_monprojet_fiches.php
  - app/Support/Monprojet/MonprojetDepartement.php
  - app/Services/Monprojet/MonprojetTableauBordService.php
  - app/Services/Monprojet/MonprojetPurgeService.php
  - app/Console/Commands/MonprojetPurgerCommand.php
  - app/Http/Controllers/MonprojetFicheController.php
  - app/Models/MonprojetFiche.php
  - routes/web.php
  - routes/console.php
  - resources/js/Pages/Monprojet/TableauBord.vue
  - resources/js/Pages/Monprojet/Index.vue
  - resources/js/Pages/Monprojet/Show.vue
  - resources/js/Pages/Monprojet/Quarantaine.vue
  - ops/cron/monprojet_purger.php
  - tests/Unit/MonprojetDepartementTest.php
  - tests/Unit/MonprojetTableauBordPeriodeTest.php
  - tests/Unit/MonprojetPurgerCommandTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
---

# SUIVI #1814 — Tableau de bord et purge RGPD

## PROMPT ENVOYÉ

Lot 2 après #1809 : tableau de bord campagne (apexchart + DataTable Meta) et
commande `monprojet:purger` avec `--dry-run`, cron OVH quotidien via lanceur PHP.

## Fiches lues

- #1809 — réception, schéma, droits bruts, menu Groupe, hors tableau de bord / purge.
- #1806 — caler le dashboard sur Meta ; purge type `api-logs:purger` ;
  anonymisation contacts inadaptée ; transcription en base.

## Mapping filtres tableau de bord

| Libellé affiché | Valeur postée | Colonne / effet | Relu |
|---|---|---|---|
| Période (semaine / mois / trimestre / année / personnalisé) | `periode`, `date_debut`, `date_fin` | filtre `recu_le` | mêmes libellés PeriodSelector |
| Campagne | `campagne` (texte) | `suivi_campagne` LIKE | texte |
| Accroche | `accroche` (texte) | `suivi_accroche` LIKE | texte |
| Format | codes `FORMAT_SUIVI` | `suivi_format` | Bannière, E-mail, … |
| (indicateur) Demandent l’exemple chiffré | — | `ouvert_propositions = true` | Oui / Non sur la fiche |

Simulations (`simulation = 1`) exclues de tous les agrégats.

## Purge

| Étape | Condition | Action |
|---|---|---|
| Prénom | sans e-mail ni téléphone, `recu_le` ≤ J-30, pas encore anonymisée, prénom présent | `prenom = null` |
| Anonymisation | `conserver_jusqu_au` ≤ aujourd’hui, `anonymisee_le` null | null sur prénom, e-mail, téléphone, description, note ; suppression transcription + historiques ; `anonymisee_le` posé ; stats conservées |
| Quarantaine | `recu_le` ≤ J-30 | suppression ligne |
| Journal | — | compteurs seulement |

Commande : `monprojet:purger` (applique) ; `monprojet:purger --dry-run` (liste, rien écrit).

## Migration

`2026_10_07_150000_add_anonymisee_le_to_monprojet_fiches.php` — colonne
`anonymisee_le` nullable + index `mp_fiches_anonym_idx` et `mp_fiches_conserver_idx`.

## Cron OVH

Fichier à déployer : `/home/hectare-envol/cron/monprojet_purger.php` (copie de
`ops/cron/monprojet_purger.php`).

Ligne : `45 4 * * * /usr/local/bin/php /home/hectare-envol/cron/monprojet_purger.php`

(Le lanceur `monprojet_relever.php` est obsolète : la relève part du site. Cette purge garde son propre lanceur.)

## LEÇON

« Exemple chiffré » n’a pas de colonne dédiée dans le contrat v1 : l’indicateur
utilise `ouvert_propositions`. Département dérivé de l’INSEE, pas de colonne.
Ne pas toucher AppShell (lien tableau de bord dans les pages Monprojet seulement).

## DÉPLOIEMENT-TEST

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

Déposer le lanceur cron et la tâche planifiée quotidienne.

1. Tableau de bord : fiches simulation absentes ; une fiche réelle comptée.
2. `php artisan monprojet:purger --dry-run` puis sans option.
