# ADR-0011 — Les comptes sont supprimés au bout de trois ans

> Date : 2026-08-21
> Statut : `accepted`

## Contexte

L'application enregistre les **nom, prénom et adresse e-mail** de membres d'associations scolaires — donc, pour l'essentiel, **d'élèves mineurs**. Elle est auto-hébergée par l'établissement.

Jusqu'ici, rien ne disait combien de temps ces données restaient. En pratique, cela voulait dire : **pour toujours**. Un élève qui tient le stand en seconde retrouverait son nom, son prénom et son adresse dans la base dix ans après avoir quitté le lycée, sans que personne n'ait jamais décidé que ce soit le cas.

Une conservation sans durée n'est pas un oubli de rédaction. C'est une décision par défaut, prise par personne, et impossible à justifier devant qui que ce soit.

Trois questions se posaient donc ensemble : **combien de temps**, **à partir de quand**, et **ce que « supprimer » veut dire** ici — parce que c'est là que la réponse évidente ne marche pas.

## Décision

**Un compte est supprimé trois ans après sa dernière utilisation.**

### Trois ans après quoi

Après la **dernière activité du compte**, c'est-à-dire la plus récente de ces dates :

- sa dernière connexion ;
- sa dernière vente, son dernier mouvement de stock, sa dernière session de caisse, son dernier comptage d'inventaire, sa dernière commande préparée, validée ou réceptionnée ;
- à défaut de tout cela, **sa date de création**.

Un compte créé pour la rentrée et jamais utilisé s'éteint donc trois ans après sa création, pas immédiatement, et pas jamais.

Trois nouvelles colonnes portent ce calcul : `createdAt`, `lastLoginAt` et `anonymiseLe`. Les comptes antérieurs à la migration prennent la date de migration comme date de création — on ne sait pas quand ils ont été créés, et inventer une date antérieure reviendrait à raccourcir leur délai sans le savoir.

### Ce que « supprimer » veut dire

**Le compte est anonymisé, il n'est pas effacé de la base.** C'est le point qui n'est pas évident, et il n'y avait pas d'autre issue.

Dix clés étrangères pointent vers `app_user` : le vendeur d'une vente, l'auteur d'un mouvement de stock, celui qui a ouvert et celui qui a clôturé une session, celui qui a compté et celui qui a validé un inventaire, celui qui a préparé, validé et réceptionné une commande.

Effacer la ligne laissait deux issues, et les deux étaient mauvaises :

- **supprimer en cascade** — et détruire avec le compte les ventes, les clôtures et le journal du stock. La comptabilité de l'association disparaîtrait parce qu'un élève a eu vingt ans ;
- **détacher les références** — et obtenir un journal où plus personne n'a rien fait. Le journal des mouvements existe précisément pour dire **qui** a ajusté un stock ; un journal sans auteur ne vaut pas la peine d'être conservé.

L'anonymisation tranche : **la personne disparaît, l'activité reste.**

Concrètement, sur le compte :

| Champ | Après |
|---|---|
| Prénom / nom | `Membre` / `#12` — soit « Membre #12 » partout où le nom s'affichait |
| E-mail | `supprime-12@compte-supprime.invalid` — non routable, et l'unicité reste satisfaite |
| Mot de passe | une empreinte de secret aléatoire que personne ne connaît |
| Rôles | vidés : le compte ne peut plus rien atteindre |
| `anonymiseLe` | horodaté |

Le numéro conservé dans le libellé permet de continuer à distinguer deux vendeurs dans une statistique ancienne, sans dire qui ils étaient. Le nom et l'adresse sont écrasés en base : **il n'existe aucune table de correspondance**, donc aucun chemin de retour.

Les **demandes d'accès** suivent la même durée, mais elles, sont réellement supprimées : rien ne les référence.

### Une exception : les super-admins

**Les comptes `ROLE_SUPER_ADMIN` ne sont jamais purgés automatiquement.** C'est le compte qui administre l'instance : l'anonymiser fermerait la porte de l'intérieur, un matin, sans que personne ne l'ait demandé — et il faudrait un accès à la base pour rentrer. Ce sont par ailleurs des comptes d'adultes, responsables de l'instance, pas ceux que cette décision vise.

L'exception est dans le code et dans ce qu'affiche la commande. Elle n'est pas un oubli.

### Ce qui déclenche la suppression

Une commande, `app:purger-comptes`, **qui ne fait rien par défaut** : elle liste ce qu'elle supprimerait. Il faut `--executer` pour qu'elle agisse.

Pas de tâche planifiée dans l'application. Elle se lance à la main à la rentrée, ou depuis le `cron` de la machine — c'est à l'établissement qui héberge de le décider, pas à l'application.

## Conséquences

- **+** La question a une réponse, et cette réponse est **exécutable**. Une durée de conservation écrite dans les mentions légales mais qu'aucun code n'applique est exactement le genre de texte qui donne l'illusion que le sujet est réglé.
- **+** Les statistiques, la comptabilité et le journal du stock restent intacts et intègres après une purge. Un exercice clos ne change pas rétroactivement parce qu'un élève est parti.
- **+** Une seule durée pour tout. Deux durées, ce serait deux règles à retenir, et deux occasions de se tromper.
- **+** La commande à blanc par défaut permet de regarder avant d'agir — c'est la même règle que l'import des membres, pour la même raison.
- **−** Une purge est **irréversible et sans confirmation ligne à ligne**. Un `--executer` lancé sur la mauvaise instance ne se rattrape que par une sauvegarde. C'est le prix d'une commande, et c'est pourquoi elle ne fait rien sans le drapeau.
- **−** « Membre #12 » est une pseudonymisation dont la table de correspondance a été détruite. C'est solide en pratique, mais quelqu'un qui aurait conservé un export antérieur pourrait recroiser. Rien ne protège d'une copie prise avant la purge.
- **−** Trois ans est une durée **choisie**, pas une durée imposée par un texte. Elle est cohérente avec ce qu'on retient couramment pour des comptes inactifs, elle est défendable, mais ce n'est pas un avis juridique et elle n'a pas été validée par le délégué à la protection des données de l'académie.

## Ce que cette décision ne règle pas

- **La base légale** du traitement et l'**information des personnes** et de leurs représentants légaux. Savoir combien de temps on garde ne dit pas de quel droit on garde.
- **L'inscription au registre des traitements** de l'établissement.
- **Le droit d'accès et de suppression exercé par une personne**, avant l'échéance des trois ans. La commande passe par une durée ; elle ne répond pas à quelqu'un qui demande son effacement aujourd'hui. Techniquement, l'anonymisation existe déjà et peut servir à cela — il manque le chemin dans le back-office et la trace de la demande.
- **Les sauvegardes.** Purger la base ne purge pas les copies. Une politique de sauvegarde qui garde tout indéfiniment annule cette décision en silence.
