From 2a0b8ac04b9ca423fbab86c872ed132d3ecca790 Mon Sep 17 00:00:00 2001 From: vdorge Date: Tue, 2 Sep 2025 10:30:52 +0000 Subject: [PATCH] Actualiser migrations/01_init.sql --- migrations/01_init.sql | 446 ++++++++++++++++++----------------------- 1 file changed, 199 insertions(+), 247 deletions(-) diff --git a/migrations/01_init.sql b/migrations/01_init.sql index 982b4c2..ea4fe18 100644 --- a/migrations/01_init.sql +++ b/migrations/01_init.sql @@ -1,263 +1,215 @@ -CREATE EXTENSION IF NOT EXISTS "pgcrypto"; +-- ============================================================ +-- 02_seed.sql : Données de test réalistes (conformes à 01_init.sql) +-- - Idempotent : ON CONFLICT DO NOTHING +-- - Utilise des UUID fixes pour faciliter les tests +-- ============================================================ --- ========================================================== --- ENUMS --- ========================================================== -DO $$ BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'role_type') THEN - CREATE TYPE role_type AS ENUM ('parent', 'gestionnaire', 'super_admin', 'assistante_maternelle'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'genre_type') THEN - CREATE TYPE genre_type AS ENUM ('H', 'F', 'Autre'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_utilisateur_type') THEN - CREATE TYPE statut_utilisateur_type AS ENUM ('en_attente','actif','suspendu'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_enfant_type') THEN - CREATE TYPE statut_enfant_type AS ENUM ('a_naitre','actif','scolarise'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_dossier_type') THEN - CREATE TYPE statut_dossier_type AS ENUM ('envoye','accepte','refuse'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_contrat_type') THEN - CREATE TYPE statut_contrat_type AS ENUM ('brouillon','en_attente_signature','valide','resilie'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_avenant_type') THEN - CREATE TYPE statut_avenant_type AS ENUM ('propose','accepte','refuse'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'type_evenement_type') THEN - CREATE TYPE type_evenement_type AS ENUM ('absence_enfant','conge_am','conge_parent','arret_maladie_am','evenement_rpe'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_evenement_type') THEN - CREATE TYPE statut_evenement_type AS ENUM ('propose','valide','refuse'); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_validation_type') THEN - CREATE TYPE statut_validation_type AS ENUM ('en_attente','valide','refuse'); - END IF; -END $$; +BEGIN; --- ========================================================== --- Table : utilisateurs --- ========================================================== -CREATE TABLE utilisateurs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - courriel VARCHAR(255) NOT NULL UNIQUE, - CHECK (courriel ~* '^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$'), - mot_de_passe_hash TEXT NOT NULL, - prenom VARCHAR(100), - nom VARCHAR(100), - genre genre_type, - role role_type NOT NULL, - statut statut_utilisateur_type DEFAULT 'en_attente', - telephone VARCHAR(20), - adresse TEXT, - photo_url TEXT, - consentement_photo BOOLEAN DEFAULT false, - date_consentement_photo TIMESTAMPTZ, - changement_mdp_obligatoire BOOLEAN DEFAULT false, - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); +-- ============================== +-- Utilisateurs (rôles & statuts) +-- ============================== +-- super_admin +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('11111111-1111-1111-1111-111111111111', 'admin@ptits-pas.fr', '$2y$10$hashAdminIci', 'Super', 'Admin', 'super_admin', 'accepte') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : assistantes_maternelles --- ========================================================== -CREATE TABLE assistantes_maternelles ( - id_utilisateur UUID PRIMARY KEY REFERENCES utilisateurs(id) ON DELETE CASCADE, - numero_agrement VARCHAR(50), - date_naissance DATE, - ville_naissance VARCHAR(100), - pays_naissance CHAR(2), - nir_chiffre CHAR(15), - nb_max_enfants INT, - biographie TEXT, - disponible BOOLEAN DEFAULT true, - ville_residence VARCHAR(100) -); +-- gestionnaire +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('22222222-2222-2222-2222-222222222222', 'gestion@ptits-pas.fr', '$2y$10$hashGestionIci', 'Gina', 'Gestion', 'gestionnaire', 'accepte') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : parents --- ========================================================== -CREATE TABLE parents ( - id_utilisateur UUID PRIMARY KEY REFERENCES utilisateurs(id) ON DELETE CASCADE, - id_co_parent UUID REFERENCES utilisateurs(id) -); +-- parent #1 +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('33333333-3333-3333-3333-333333333333', 'parent1@example.com', '$2y$10$hashParent1', 'Paul', 'Parent', 'parent', 'accepte') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : enfants --- ========================================================== -CREATE TABLE enfants ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - statut statut_enfant_type, - prenom VARCHAR(100), - nom VARCHAR(100), - genre genre_type, - date_naissance DATE, - date_prevue_naissance DATE, - photo_url TEXT, - consentement_photo BOOLEAN DEFAULT false, - date_consentement_photo TIMESTAMPTZ, - est_multiple BOOLEAN DEFAULT false -); +-- co-parent du parent #1 +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('44444444-4444-4444-4444-444444444444', 'coparent1@example.com', '$2y$10$hashCoParent1', 'Clara', 'CoParent', 'parent', 'accepte') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : enfants_parents --- ========================================================== -CREATE TABLE enfants_parents ( - id_parent UUID REFERENCES parents(id_utilisateur) ON DELETE CASCADE, - id_enfant UUID REFERENCES enfants(id) ON DELETE CASCADE, - PRIMARY KEY (id_parent, id_enfant) -); +-- parent #2 +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('55555555-5555-5555-5555-555555555555', 'parent2@example.com', '$2y$10$hashParent2', 'Nora', 'Parent', 'parent', 'en_attente') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : dossiers --- ========================================================== -CREATE TABLE dossiers ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_parent UUID REFERENCES parents(id_utilisateur) ON DELETE CASCADE, - id_enfant UUID REFERENCES enfants(id) ON DELETE CASCADE, - presentation TEXT, - type_contrat VARCHAR(50), - repas BOOLEAN DEFAULT false, - budget NUMERIC(10,2), - planning_souhaite JSONB, - statut statut_dossier_type DEFAULT 'envoye', - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); +-- assistante maternelle +INSERT INTO utilisateurs (id, courriel, mot_de_passe_hash, prenom, nom, role, statut) +VALUES ('66666666-6666-6666-6666-666666666666', 'am1@example.com', '$2y$10$hashAM1', 'Alice', 'AM', 'am', 'accepte') +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : messages --- ========================================================== -CREATE TABLE messages ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_dossier UUID REFERENCES dossiers(id) ON DELETE CASCADE, - id_expediteur UUID REFERENCES utilisateurs(id) ON DELETE CASCADE, - contenu TEXT, - re_redige_par_ia BOOLEAN DEFAULT false, - cree_le TIMESTAMPTZ DEFAULT now() -); +-- ============================== +-- Parents & co-parents (extensions) +-- ============================== +INSERT INTO parents (id_utilisateur, id_co_parent) +VALUES + ('33333333-3333-3333-3333-333333333333', '44444444-4444-4444-4444-444444444444'), -- parent1 avec co-parent + ('55555555-5555-5555-5555-555555555555', NULL) -- parent2 seul +ON CONFLICT (id_utilisateur) DO NOTHING; --- ========================================================== --- Table : contrats --- ========================================================== -CREATE TABLE contrats ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_dossier UUID UNIQUE REFERENCES dossiers(id) ON DELETE CASCADE, - planning JSONB, - tarif_horaire NUMERIC(6,2), - indemnites_repas NUMERIC(6,2), - date_debut DATE, - statut statut_contrat_type DEFAULT 'brouillon', - signe_parent BOOLEAN DEFAULT false, - signe_am BOOLEAN DEFAULT false, - finalise_le TIMESTAMPTZ, - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); +-- ============================== +-- Assistantes maternelles (extension) +-- ============================== +INSERT INTO assistantes_maternelles (id_utilisateur, numero_agrement, nb_max_enfants, disponible, ville_residence, nir_chiffre) +VALUES ('66666666-6666-6666-6666-666666666666', 'AGR-2025-0001', 3, true, 'Lille', '000000000000000') +ON CONFLICT (id_utilisateur) DO NOTHING; --- ========================================================== --- Table : avenants_contrats --- ========================================================== -CREATE TABLE avenants_contrats ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_contrat UUID REFERENCES contrats(id) ON DELETE CASCADE, - modifications JSONB, - initie_par UUID REFERENCES utilisateurs(id), - statut statut_avenant_type DEFAULT 'propose', - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); +-- ============================== +-- Enfants +-- ============================== +-- Enfant A : déjà né (statut actif) +INSERT INTO enfants (id, prenom, nom, statut, date_naissance, jumeau_multiple) +VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'Léo', 'Parent', 'actif', '2022-04-12', false) +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : evenements --- ========================================================== -CREATE TABLE evenements ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - type type_evenement_type, - id_enfant UUID REFERENCES enfants(id) ON DELETE CASCADE, - id_am UUID REFERENCES utilisateurs(id), - id_parent UUID REFERENCES parents(id_utilisateur), - cree_par UUID REFERENCES utilisateurs(id), - date_debut TIMESTAMPTZ, - date_fin TIMESTAMPTZ, - commentaires TEXT, - statut statut_evenement_type DEFAULT 'propose', - delai_grace TIMESTAMPTZ, - urgent BOOLEAN DEFAULT false, - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); +-- Enfant B : à naître (statut a_naitre) +INSERT INTO enfants (id, prenom, nom, statut, date_prevue_naissance, jumeau_multiple) +VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'Mila', 'Parent', 'a_naitre', '2026-02-15', false) +ON CONFLICT (id) DO NOTHING; --- ========================================================== --- Table : signalements_bugs --- ========================================================== -CREATE TABLE signalements_bugs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_utilisateur UUID REFERENCES utilisateurs(id), - description TEXT, - cree_le TIMESTAMPTZ DEFAULT now() -); +-- ============================== +-- Liaison N:N parents ↔ enfants +-- ============================== +-- parent1 & co-parent ↔ enfant A +INSERT INTO enfants_parents (id_parent, id_enfant) +VALUES + ('33333333-3333-3333-3333-333333333333', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'), + ('44444444-4444-4444-4444-444444444444', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa') +ON CONFLICT DO NOTHING; --- ========================================================== --- Table : uploads --- ========================================================== -CREATE TABLE uploads ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_utilisateur UUID REFERENCES utilisateurs(id) ON DELETE SET NULL, - fichier_url TEXT NOT NULL, - type VARCHAR(50), - cree_le TIMESTAMPTZ DEFAULT now() -); +-- parent1 & parent2 ↔ enfant B +INSERT INTO enfants_parents (id_parent, id_enfant) +VALUES + ('33333333-3333-3333-3333-333333333333', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'), + ('55555555-5555-5555-5555-555555555555', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb') +ON CONFLICT DO NOTHING; --- ========================================================== --- Table : notifications --- ========================================================== -CREATE TABLE notifications ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_utilisateur UUID REFERENCES utilisateurs(id) ON DELETE CASCADE, - contenu TEXT, - lu BOOLEAN DEFAULT false, - cree_le TIMESTAMPTZ DEFAULT now() -); - --- ========================================================== --- Table : validations --- ========================================================== -CREATE TABLE validations ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - id_utilisateur UUID REFERENCES utilisateurs(id), - type VARCHAR(50), - statut statut_validation_type DEFAULT 'en_attente', - cree_le TIMESTAMPTZ DEFAULT now(), - modifie_le TIMESTAMPTZ DEFAULT now() -); - - --- ========================================================== --- Initialisation d'un administrateur par défaut --- ========================================================== - -INSERT INTO utilisateurs ( - id, - courriel, - mot_de_passe_hash, - prenom, - nom, - role, - statut, - cree_le, - modifie_le -) +-- ============================== +-- Dossier (parent1 ↔ enfant A) +-- ============================== +INSERT INTO dossiers (id, id_parent, id_enfant, presentation, type_contrat, repas, budget, planning_souhaite, statut) VALUES ( - gen_random_uuid(), - 'admin@ptitspas.com', - 'motdepasse_hashé', -- ⚠️ à remplacer par le hash réel du mot de passe - 'Admin', - 'PtitsPas', - 'super_admin', - 'actif', - now(), - now() + 'dddddddd-dddd-dddd-dddd-dddddddddddd', + '33333333-3333-3333-3333-333333333333', + 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + 'Besoin garde périscolaire lundi/mardi/jeudi/vendredi.', + 'mensuel', + true, + 600.00, + '{"lun_ven":{"midi":true,"soir":true}}'::jsonb, + 'envoye' ) -ON CONFLICT (courriel) DO NOTHING; +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Messages (sur le dossier) +-- ============================== +INSERT INTO messages (id, id_dossier, id_expediteur, contenu) +VALUES + ('m0000000-0000-0000-0000-000000000001', 'dddddddd-dddd-dddd-dddd-dddddddddddd', '33333333-3333-3333-3333-333333333333', 'Bonjour, nous cherchons une garde périscolaire.'), + ('m0000000-0000-0000-0000-000000000002', 'dddddddd-dddd-dddd-dddd-dddddddddddd', '66666666-6666-6666-6666-666666666666', 'Bonjour, je suis disponible les soirs. Discutons du contrat.') +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Contrat (1:1 avec le dossier) +-- ============================== +INSERT INTO contrats (id, id_dossier, planning, tarif_horaire, indemnites_repas, date_debut, statut, signe_parent, signe_am) +VALUES ( + 'cccccccc-cccc-cccc-cccc-cccccccccccc', + 'dddddddd-dddd-dddd-dddd-dddddddddddd', + '{"lun_ven":{"17h-19h":true}}'::jsonb, + 12.50, + 3.50, + '2025-09-01', + 'brouillon', + false, + false +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Avenant de contrat +-- ============================== +INSERT INTO avenants_contrats (id, id_contrat, modifications, initie_par, statut) +VALUES ( + 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee', + 'cccccccc-cccc-cccc-cccc-cccccccccccc', + '{"changement_horaire":{"vendredi":{"17h-20h":true}}}'::jsonb, + '33333333-3333-3333-3333-333333333333', + 'propose' +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Événement (absence enfant) +-- ============================== +INSERT INTO evenements (id, type, id_enfant, id_am, id_parent, cree_par, date_debut, date_fin, commentaires, statut, delai_grace, urgence) +VALUES ( + 'e0000000-0000-0000-0000-000000000001', + 'absence_enfant', + 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + '66666666-6666-6666-6666-666666666666', + '33333333-3333-3333-3333-333333333333', + '33333333-3333-3333-3333-333333333333', + '2025-09-12', + '2025-09-12', + 'Enfant malade (rhume).', + 'propose', + '2025-09-15', + false +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Upload (justificatif lié au dossier) +-- ============================== +INSERT INTO uploads (id, id_utilisateur, id_dossier_lie, fichier_url, type_fichier) +VALUES ( + 'u0000000-0000-0000-0000-000000000001', + '33333333-3333-3333-3333-333333333333', + 'dddddddd-dddd-dddd-dddd-dddddddddddd', + '/uploads/justificatifs/dossier_dddddddd_attestation.pdf', + 'application/pdf' +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Notification (pour le parent1) +-- ============================== +INSERT INTO notifications (id, id_utilisateur, type, contenu, lu) +VALUES ( + 'n0000000-0000-0000-0000-000000000001', + '33333333-3333-3333-3333-333333333333', + 'nouveau_message', + 'Vous avez un nouveau message sur le dossier #dddd…', + false +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Validation (compte de l’AM validé) +-- ============================== +INSERT INTO validations (id, id_utilisateur, statut, commentaire, cree_le) +VALUES ( + 'v0000000-0000-0000-0000-000000000001', + '66666666-6666-6666-6666-666666666666', + 'accepte', + 'Dossier AM vérifié par gestionnaire.', + NOW() +) +ON CONFLICT (id) DO NOTHING; + +-- ============================== +-- Signalement de bug +-- ============================== +INSERT INTO signalements_bugs (id, id_utilisateur, description, cree_le) +VALUES ( + 'b0000000-0000-0000-0000-000000000001', + '33333333-3333-3333-3333-333333333333', + 'Impossible d’envoyer un message quand le fichier est trop lourd.', + NOW() +) +ON CONFLICT (id) DO NOTHING; + +COMMIT;