- Ajout Cahier des Charges v1.3 - Ajout Workflow technique création de compte (v1.0) - Réorganisation docs avec préfixes numériques (00_, 01_, etc.) - Ajout données de test CSV - Modifications principales : * Champ téléphone unique (suppression mobile/fixe) * Inscription sans mot de passe (Parents + AM) * Création MDP par email après validation (7j) * Genre enfant obligatoire (H/F) * Date agrément obligatoire pour AM
422 lines
14 KiB
Markdown
422 lines
14 KiB
Markdown
# 🗄️ Documentation Base de Données
|
|
|
|
## Vue d'ensemble
|
|
|
|
L'application PtitsPas utilise **PostgreSQL 14** avec l'extension **pgcrypto** pour la gestion des UUID.
|
|
|
|
**Nom de la base** : `ptitpas_db`
|
|
**Port** : `5432`
|
|
**Conteneur Docker** : `ptitspas-postgres`
|
|
|
|
## Schéma de la base de données
|
|
|
|
### Types ENUM
|
|
|
|
La base de données utilise plusieurs types énumérés PostgreSQL :
|
|
|
|
| Type ENUM | Valeurs possibles | Usage |
|
|
|-----------|------------------|-------|
|
|
| `role_type` | `parent`, `gestionnaire`, `super_admin`, `assistante_maternelle`, `administrateur` | Rôles des utilisateurs |
|
|
| `genre_type` | `H`, `F`, `Autre` | Genre des utilisateurs et enfants |
|
|
| `statut_utilisateur_type` | `en_attente`, `actif`, `suspendu` | Statut du compte utilisateur |
|
|
| `statut_enfant_type` | `a_naitre`, `actif`, `scolarise` | Statut de l'enfant |
|
|
| `statut_dossier_type` | `envoye`, `accepte`, `refuse` | Statut de la candidature |
|
|
| `statut_contrat_type` | `brouillon`, `en_attente_signature`, `valide`, `resilie` | Statut du contrat |
|
|
| `statut_avenant_type` | `propose`, `accepte`, `refuse` | Statut des avenants au contrat |
|
|
| `type_evenement_type` | `absence_enfant`, `conge_am`, `conge_parent`, `arret_maladie_am`, `evenement_rpe` | Type d'événement |
|
|
| `statut_evenement_type` | `propose`, `valide`, `refuse` | Statut de l'événement |
|
|
| `statut_validation_type` | `en_attente`, `valide`, `refuse` | Statut de validation générique |
|
|
|
|
---
|
|
|
|
## Tables
|
|
|
|
### 1. `utilisateurs`
|
|
|
|
Table centrale pour tous les types d'utilisateurs.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `email` | VARCHAR(255) | NOT NULL, UNIQUE | Email (avec validation regex) |
|
|
| `password` | TEXT | NOT NULL | Mot de passe hashé (bcrypt) |
|
|
| `prenom` | VARCHAR(100) | | Prénom |
|
|
| `nom` | VARCHAR(100) | | Nom de famille |
|
|
| `genre` | genre_type | | Genre de l'utilisateur |
|
|
| `role` | role_type | NOT NULL | Rôle de l'utilisateur |
|
|
| `statut` | statut_utilisateur_type | DEFAULT 'en_attente' | Statut du compte |
|
|
| `telephone` | VARCHAR(20) | | Téléphone principal |
|
|
| `adresse` | TEXT | | Adresse complète |
|
|
| `photo_url` | TEXT | | URL de la photo de profil |
|
|
| `consentement_photo` | BOOLEAN | DEFAULT false | Consentement photo |
|
|
| `date_consentement_photo` | TIMESTAMPTZ | | Date du consentement |
|
|
| `changement_mdp_obligatoire` | BOOLEAN | DEFAULT false | Force changement de MDP |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
| `ville` | VARCHAR(150) | | Ville |
|
|
| `code_postal` | VARCHAR(10) | | Code postal |
|
|
| `mobile` | VARCHAR(20) | | Téléphone mobile |
|
|
| `telephone_fixe` | VARCHAR(20) | | Téléphone fixe |
|
|
| `profession` | VARCHAR(150) | | Profession |
|
|
| `situation_familiale` | VARCHAR(50) | | Situation familiale |
|
|
| `date_naissance` | DATE | | Date de naissance |
|
|
|
|
**Contraintes** :
|
|
- Email validé par regex : `^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$`
|
|
|
|
---
|
|
|
|
### 2. `assistantes_maternelles`
|
|
|
|
Extension de la table `utilisateurs` pour les assistantes maternelles.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id_utilisateur` | UUID | PRIMARY KEY, FK → utilisateurs(id) | Référence à l'utilisateur |
|
|
| `numero_agrement` | VARCHAR(50) | | Numéro d'agrément |
|
|
| `nir_chiffre` | CHAR(15) | | NIR (Sécurité sociale) |
|
|
| `nb_max_enfants` | INT | | Capacité maximale d'accueil |
|
|
| `biographie` | TEXT | | Présentation |
|
|
| `disponible` | BOOLEAN | DEFAULT true | Disponibilité |
|
|
| `ville_residence` | VARCHAR(100) | | Ville de résidence |
|
|
| `date_agrement` | DATE | | Date d'obtention de l'agrément |
|
|
| `annee_experience` | SMALLINT | | Années d'expérience |
|
|
| `specialite` | VARCHAR(100) | | Spécialités |
|
|
| `place_disponible` | INT | | Nombre de places disponibles |
|
|
|
|
**Cascade** : `ON DELETE CASCADE` (suppression si utilisateur supprimé)
|
|
|
|
---
|
|
|
|
### 3. `parents`
|
|
|
|
Extension de la table `utilisateurs` pour les parents.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id_utilisateur` | UUID | PRIMARY KEY, FK → utilisateurs(id) | Référence à l'utilisateur |
|
|
| `id_co_parent` | UUID | FK → utilisateurs(id) | Référence au co-parent (optionnel) |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 4. `enfants`
|
|
|
|
Table des enfants pris en charge.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `statut` | statut_enfant_type | | Statut de l'enfant |
|
|
| `prenom` | VARCHAR(100) | | Prénom |
|
|
| `nom` | VARCHAR(100) | | Nom |
|
|
| `genre` | genre_type | | Genre |
|
|
| `date_naissance` | DATE | | Date de naissance |
|
|
| `date_prevue_naissance` | DATE | | Date prévue (si à naître) |
|
|
| `photo_url` | TEXT | | URL de la photo |
|
|
| `consentement_photo` | BOOLEAN | DEFAULT false | Consentement photo |
|
|
| `date_consentement_photo` | TIMESTAMPTZ | | Date du consentement |
|
|
| `est_multiple` | BOOLEAN | DEFAULT false | Indique si grossesse multiple |
|
|
|
|
---
|
|
|
|
### 5. `enfants_parents`
|
|
|
|
Table de liaison entre enfants et parents (relation N:N).
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id_parent` | UUID | FK → parents(id_utilisateur) | Référence au parent |
|
|
| `id_enfant` | UUID | FK → enfants(id) | Référence à l'enfant |
|
|
|
|
**Clé primaire composite** : `(id_parent, id_enfant)`
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 6. `dossiers`
|
|
|
|
Dossiers de candidature des parents pour une assistante maternelle.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_parent` | UUID | FK → parents(id_utilisateur) | Parent demandeur |
|
|
| `id_enfant` | UUID | FK → enfants(id) | Enfant concerné |
|
|
| `presentation` | TEXT | | Présentation de la demande |
|
|
| `type_contrat` | VARCHAR(50) | | Type de contrat souhaité |
|
|
| `repas` | BOOLEAN | DEFAULT false | Demande de repas |
|
|
| `budget` | NUMERIC(10,2) | | Budget disponible |
|
|
| `planning_souhaite` | JSONB | | Planning souhaité (format JSON) |
|
|
| `statut` | statut_dossier_type | DEFAULT 'envoye' | Statut du dossier |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 7. `messages`
|
|
|
|
Messages échangés dans le cadre d'un dossier.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_dossier` | UUID | FK → dossiers(id) | Dossier lié |
|
|
| `id_expediteur` | UUID | FK → utilisateurs(id) | Expéditeur |
|
|
| `contenu` | TEXT | | Contenu du message |
|
|
| `re_redige_par_ia` | BOOLEAN | DEFAULT false | Message réécrit par IA |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date d'envoi |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 8. `contrats`
|
|
|
|
Contrats conclus entre parents et assistantes maternelles.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_dossier` | UUID | UNIQUE, FK → dossiers(id) | Dossier source (1:1) |
|
|
| `planning` | JSONB | | Planning défini (format JSON) |
|
|
| `tarif_horaire` | NUMERIC(6,2) | | Tarif horaire |
|
|
| `indemnites_repas` | NUMERIC(6,2) | | Indemnités repas |
|
|
| `date_debut` | DATE | | Date de début du contrat |
|
|
| `statut` | statut_contrat_type | DEFAULT 'brouillon' | Statut du contrat |
|
|
| `signe_parent` | BOOLEAN | DEFAULT false | Signature parent |
|
|
| `signe_am` | BOOLEAN | DEFAULT false | Signature assistante maternelle |
|
|
| `finalise_le` | TIMESTAMPTZ | | Date de finalisation |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 9. `avenants_contrats`
|
|
|
|
Modifications apportées aux contrats existants.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_contrat` | UUID | FK → contrats(id) | Contrat modifié |
|
|
| `modifications` | JSONB | | Détails des modifications (JSON) |
|
|
| `initie_par` | UUID | FK → utilisateurs(id) | Utilisateur initiateur |
|
|
| `statut` | statut_avenant_type | DEFAULT 'propose' | Statut de l'avenant |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 10. `evenements`
|
|
|
|
Événements liés au planning (absences, congés, etc.).
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `type` | type_evenement_type | | Type d'événement |
|
|
| `id_enfant` | UUID | FK → enfants(id) | Enfant concerné |
|
|
| `id_am` | UUID | FK → utilisateurs(id) | Assistante maternelle |
|
|
| `id_parent` | UUID | FK → parents(id_utilisateur) | Parent |
|
|
| `cree_par` | UUID | FK → utilisateurs(id) | Créateur de l'événement |
|
|
| `date_debut` | TIMESTAMPTZ | | Date de début |
|
|
| `date_fin` | TIMESTAMPTZ | | Date de fin |
|
|
| `commentaires` | TEXT | | Commentaires |
|
|
| `statut` | statut_evenement_type | DEFAULT 'propose' | Statut de l'événement |
|
|
| `delai_grace` | TIMESTAMPTZ | | Délai de grâce |
|
|
| `urgent` | BOOLEAN | DEFAULT false | Événement urgent |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 11. `signalements_bugs`
|
|
|
|
Signalements de bugs par les utilisateurs.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_utilisateur` | UUID | FK → utilisateurs(id) | Utilisateur signalant |
|
|
| `description` | TEXT | | Description du bug |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date du signalement |
|
|
|
|
---
|
|
|
|
### 12. `uploads`
|
|
|
|
Fichiers téléversés par les utilisateurs.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_utilisateur` | UUID | FK → utilisateurs(id), ON DELETE SET NULL | Utilisateur |
|
|
| `fichier_url` | TEXT | NOT NULL | URL du fichier |
|
|
| `type` | VARCHAR(50) | | Type de fichier |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date d'upload |
|
|
|
|
---
|
|
|
|
### 13. `notifications`
|
|
|
|
Notifications envoyées aux utilisateurs.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_utilisateur` | UUID | FK → utilisateurs(id) | Destinataire |
|
|
| `contenu` | TEXT | | Contenu de la notification |
|
|
| `lu` | BOOLEAN | DEFAULT false | Statut de lecture |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de création |
|
|
|
|
**Cascade** : `ON DELETE CASCADE`
|
|
|
|
---
|
|
|
|
### 14. `validations`
|
|
|
|
Validations génériques de données utilisateur.
|
|
|
|
| Colonne | Type | Contraintes | Description |
|
|
|---------|------|-------------|-------------|
|
|
| `id` | UUID | PRIMARY KEY | Identifiant unique |
|
|
| `id_utilisateur` | UUID | FK → utilisateurs(id) | Utilisateur à valider |
|
|
| `type` | VARCHAR(50) | | Type de validation |
|
|
| `statut` | statut_validation_type | DEFAULT 'en_attente' | Statut |
|
|
| `cree_le` | TIMESTAMPTZ | DEFAULT now() | Date de demande |
|
|
| `modifie_le` | TIMESTAMPTZ | DEFAULT now() | Dernière modification |
|
|
| `valide_par` | UUID | FK → utilisateurs(id) | Validateur |
|
|
| `commentaire` | TEXT | | Commentaire du validateur |
|
|
|
|
---
|
|
|
|
## Relations principales
|
|
|
|
```
|
|
utilisateurs (1) ──┬──> (1) assistantes_maternelles
|
|
├──> (1) parents
|
|
└──> (N) messages
|
|
|
|
parents (1) ───> (N) enfants_parents <─── (N) enfants
|
|
|
|
parents (1) ───> (N) dossiers <─── (1) enfants
|
|
dossiers (1) ───> (N) messages
|
|
dossiers (1) ───> (1) contrats
|
|
contrats (1) ───> (N) avenants_contrats
|
|
|
|
enfants (1) ───> (N) evenements
|
|
```
|
|
|
|
---
|
|
|
|
## Données initiales (SEED)
|
|
|
|
### Super Administrateur par défaut
|
|
|
|
**Email** : `admin@ptits-pas.fr`
|
|
**Mot de passe** : `4dm1n1strateur`
|
|
**Rôle** : `super_admin`
|
|
**Statut** : `actif`
|
|
|
|
> ⚠️ **Sécurité** : Le mot de passe est hashé avec bcrypt (`$2b$12$...`).
|
|
> Il est **impératif** de changer ce mot de passe en production.
|
|
|
|
---
|
|
|
|
## Migrations
|
|
|
|
Les migrations sont gérées manuellement via le fichier SQL :
|
|
|
|
**Fichier** : `/database/migrations/01_init.sql`
|
|
|
|
### Appliquer les migrations
|
|
|
|
```bash
|
|
# Depuis le conteneur backend
|
|
npx prisma migrate deploy
|
|
|
|
# Ou manuellement depuis psql
|
|
psql -U admin -d ptitpas_db -f /database/migrations/01_init.sql
|
|
```
|
|
|
|
---
|
|
|
|
## Accès à la base de données
|
|
|
|
### Via PgAdmin
|
|
|
|
**URL** : `https://app.ptits-pas.fr/pgadmin`
|
|
**Email** : `admin@ptits-pas.fr`
|
|
**Mot de passe** : `admin123`
|
|
|
|
**Configuration serveur** :
|
|
- Host : `ptitspas-postgres`
|
|
- Port : `5432`
|
|
- Database : `ptitpas_db`
|
|
- Username : `admin`
|
|
- Password : `admin123`
|
|
|
|
### Via terminal (Docker)
|
|
|
|
```bash
|
|
# Connexion au conteneur PostgreSQL
|
|
docker exec -it ptitspas-postgres psql -U admin -d ptitpas_db
|
|
|
|
# Lister les tables
|
|
\dt
|
|
|
|
# Voir le schéma d'une table
|
|
\d utilisateurs
|
|
|
|
# Quitter
|
|
\q
|
|
```
|
|
|
|
---
|
|
|
|
## Recommandations de sécurité
|
|
|
|
1. ✅ **Mots de passe hashés** avec bcrypt
|
|
2. ✅ **Validation email** via regex
|
|
3. ⚠️ **Changer les credentials par défaut en production**
|
|
4. ⚠️ **Créer un utilisateur read-only pour les analytics**
|
|
5. ⚠️ **Activer SSL/TLS pour les connexions PostgreSQL**
|
|
6. ✅ **Utiliser des UUID** plutôt que des identifiants séquentiels
|
|
|
|
---
|
|
|
|
## Maintenance
|
|
|
|
### Backup de la base
|
|
|
|
```bash
|
|
docker exec ptitspas-postgres pg_dump -U admin ptitpas_db > backup.sql
|
|
```
|
|
|
|
### Restauration
|
|
|
|
```bash
|
|
docker exec -i ptitspas-postgres psql -U admin ptitpas_db < backup.sql
|
|
```
|
|
|
|
### Vérifier la taille de la base
|
|
|
|
```sql
|
|
SELECT pg_size_pretty(pg_database_size('ptitpas_db'));
|
|
```
|
|
|
|
---
|
|
|
|
**Dernière mise à jour** : Novembre 2025
|
|
|