docs: Workflow création de compte + refonte documentation
- 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
This commit is contained in:
@@ -0,0 +1,421 @@
|
||||
# 🗄️ 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
|
||||
|
||||
Reference in New Issue
Block a user