ptitspas-ynov-bdd/docs/FK_POLICIES.md

143 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# FK_POLICIES.md
**Politique des clés étrangères (ON DELETE / ON UPDATE)** Sprint 1
## 🎯 Objectif
Documenter, de façon unique et partagée, les règles de suppression/mise à jour appliquées aux **clés étrangères** de la base PtitsPas pour :
- préserver l**intégrité référentielle** ;
- conserver l**historique** utile (messages, événements…) ;
- respecter les exigences **RGPD** (suppression en cascade lorsque pertinent).
> Par défaut, **ON UPDATE = NO ACTION** (UUID immuables).
> Ce document couvre **ON DELETE** table par table.
---
## 🧭 Principes généraux
- **CASCADE** quand la donnée fille **na pas de sens sans le parent**
(ex. `dossiers` dun parent, `avenants` dun contrat).
- **SET NULL** quand on veut **préserver lhistorique** mais que le référent peut disparaître
(ex. auteur dun message supprimé, créateur dun événement).
- **RESTRICT/NO ACTION** non utilisé ici pour éviter des blocages au nettoyage.
---
## 📚 Récapitulatif rapide (matrice)
| Table (colonne FK) → Référence | ON DELETE | Raison |
|---|---:|---|
| **assistantes_maternelles(id_utilisateur)**`utilisateurs(id)` | **CASCADE** | Profil AM supprimé avec son compte |
| **parents(id_utilisateur)**`utilisateurs(id)` | **CASCADE** | Extension parent supprimée avec son compte |
| **parents(id_co_parent)**`utilisateurs(id)` | **SET NULL** | Conserver le parent principal si co-parent disparaît |
| **enfants_parents(id_parent)**`parents(id_utilisateur)` | **CASCADE** | Nettoyage liaisons N:N |
| **enfants_parents(id_enfant)**`enfants(id)` | **CASCADE** | Idem |
| **dossiers(id_parent)**`parents(id_utilisateur)` | **CASCADE** | Dossier na pas de sens sans parent |
| **dossiers(id_enfant)**`enfants(id)` | **CASCADE** | Dossier na pas de sens sans enfant |
| **messages(id_dossier)**`dossiers(id)` | **CASCADE** | Messages détruits avec le dossier |
| **messages(id_expediteur)**`utilisateurs(id)` | **SET NULL** | Garder lhistorique des échanges |
| **contrats(id_dossier)**`dossiers(id)` | **CASCADE** | 1:1, contrat détruit si dossier supprimé |
| **avenants_contrats(id_contrat)**`contrats(id)` | **CASCADE** | Avenants détruits avec le contrat |
| **avenants_contrats(initie_par)**`utilisateurs(id)` | **SET NULL** | Historiser lavenant sans bloquer |
| **evenements(id_enfant)**`enfants(id)` | **CASCADE** | Événements nont plus de sens |
| **evenements(id_am)**`utilisateurs(id)` | **SET NULL** | Garder la trace même si AM supprimée |
| **evenements(id_parent)**`parents(id_utilisateur)` | **SET NULL** | Garder la trace si parent supprimé |
| **evenements(cree_par)**`utilisateurs(id)` | **SET NULL** | Conserver lhistorique de création |
| **signalements_bugs(id_utilisateur)**`utilisateurs(id)` | **SET NULL** | Conserver le ticket même si compte supprimé |
| **uploads(id_utilisateur)**`utilisateurs(id)` | **SET NULL** | Fichier reste référencé sans lauteur |
| **notifications(id_utilisateur)**`utilisateurs(id)` | **CASCADE** | Notifications propres à lutilisateur |
| **validations(id_utilisateur)**`utilisateurs(id)` | **SET NULL** | Garder lhistorique de décision |
> **ON UPDATE** : **NO ACTION** partout (les UUID ne changent pas).
---
## 🔎 Détail par domaine
### Utilisateurs & extensions
- `assistantes_maternelles.id_utilisateur`**CASCADE**
- `parents.id_utilisateur`**CASCADE**
- `parents.id_co_parent`**SET NULL** (interdit dêtre co-parent de soi-même via CHECK déjà posé)
### Enfants & liaisons
- `enfants_parents.id_parent`**CASCADE**
- `enfants_parents.id_enfant`**CASCADE**
### Dossiers & échanges
- `dossiers.id_parent`**CASCADE**
- `dossiers.id_enfant`**CASCADE**
- `messages.id_dossier`**CASCADE**
- `messages.id_expediteur`**SET NULL**
### Contrats & avenants
- `contrats.id_dossier`**CASCADE** (unique 1:1)
- `avenants_contrats.id_contrat`**CASCADE**
- `avenants_contrats.initie_par`**SET NULL**
### Événements
- `evenements.id_enfant`**CASCADE**
- `evenements.id_am`**SET NULL**
- `evenements.id_parent`**SET NULL**
- `evenements.cree_par`**SET NULL**
### Divers
- `signalements_bugs.id_utilisateur`**SET NULL**
- `uploads.id_utilisateur`**SET NULL**
- `notifications.id_utilisateur`**CASCADE**
- `validations.id_utilisateur`**SET NULL**
---
## 🧪 Scénarios de test (exemples)
1. **Suppression dun parent**
- Supprimer `utilisateurs(id=parentX)`
- Attendu : `parents` (CASCADE), ses `dossiers` (CASCADE), `messages` liés aux `dossiers` (CASCADE) sont supprimés.
2. **Suppression dun co-parent**
- Supprimer `utilisateurs(id=coParentY)`
- Attendu : `parents.id_co_parent` passe à **NULL**, aucun dossier supprimé.
3. **Suppression dun utilisateur auteur de messages**
- Supprimer `utilisateurs(id=uZ)`
- Attendu : les lignes `messages` **restent**, `id_expediteur` devient **NULL**.
4. **Suppression dun enfant**
- Supprimer `enfants(id=childA)`
- Attendu : `enfants_parents` (CASCADE), `dossiers` du childA (CASCADE), `evenements` du childA (CASCADE).
5. **Suppression dun utilisateur AM**
- Supprimer `utilisateurs(id=amB)`
- Attendu : `evenements.id_am` devient **NULL** (historique conservé).
---
## 🛠 Migrations associées
Les ajustements sont implémentés dans :
- **`/bdd/migrations/04_fk_policies.sql`**
redéfinition des contraintes FK avec les bonnes politiques (**DROP puis ADD CONSTRAINT**), de façon idempotente.
---
## 📄 Notes & futures évolutions
- **RGPD (Sprint 2)** : si vous activez le **soft delete** (`deleted_at`) côté tables métier, ces politiques restent valides (les suppressions logiques se gèrent au niveau applicatif).
- **Audit** : si vous voulez tracer les suppressions, ajoutez des triggers daudit (voir ticket Sprint 2 Audit log).
- **Performance** : chaque FK doit être **indexée côté enfant** (cf. `02_indexes.sql`).
---
## ✅ Checklist de conformité
- [ ] Toutes les FK listées existent dans la base
- [ ] Politique **ON DELETE** conforme au tableau ci-dessus
- [ ] **ON UPDATE = NO ACTION** partout
- [ ] Tests de suppression réalisés sur une base seedée
- [ ] `04_fk_policies.sql` appliqué sans erreur
---
**Mainteneur** : Équipe BDD
**Dernière mise à jour** : Sprint 1 Politique FK consolidée