# 🗄️ 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