Lorsqu'un super-admin crée un établissement via l'interface, le système doit automatiquement créer la base tenant, exécuter les migrations, créer le premier utilisateur admin et envoyer l'invitation — le tout de manière asynchrone pour ne pas bloquer la réponse HTTP. Ce mécanisme rend chaque établissement opérationnel dès sa création sans intervention manuelle sur l'infrastructure.
182 lines
12 KiB
SQL
182 lines
12 KiB
SQL
-- =============================================================================
|
|
-- Jeu de données local — Story 6.9 : GradeVoter & accès notes
|
|
-- =============================================================================
|
|
-- Prérequis : avoir lancé `make generate-demo` sur un tenant (ecole-beta par défaut)
|
|
-- Usage :
|
|
-- docker compose exec -T php php bin/console dbal:run-sql "$(cat backend/seed-story-6.9.sql)"
|
|
--
|
|
-- Mot de passe de tous les comptes démo : DemoPassword123!
|
|
-- URL : http://ecole-beta.classeo.local:5174/login
|
|
--
|
|
-- ┌──────────────────────────────────────────────────────────────────────────┐
|
|
-- │ Scénarios à tester │
|
|
-- │ │
|
|
-- │ AC1 — GradeVoter │
|
|
-- │ ✅ Amina Benali (prof maths, affectée 6A) → peut saisir notes │
|
|
-- │ ❌ Sophie Lambert (prof SVT, pas affectée 6A en maths) → bloquée │
|
|
-- │ ✅ David Nguyen (remplaçant actif maths 6A) → peut saisir notes │
|
|
-- │ │
|
|
-- │ AC2 — Retrait d'affectation │
|
|
-- │ ❌ Julie Caron (prof français, affectation retirée 6A) │
|
|
-- │ → peut voir les notes existantes, ne peut plus en saisir │
|
|
-- │ │
|
|
-- │ AC3 — Badge "Remplaçant" │
|
|
-- │ → Se connecter avec David Nguyen, saisir une note │
|
|
-- │ → Le badge violet "Remplaçant" apparaît sur la ligne │
|
|
-- │ │
|
|
-- │ AC4 — Parent StudentVoter │
|
|
-- │ ✅ Nadia Martin → voit les notes de Lina Martin (6A) │
|
|
-- │ ❌ Claire Bernard → ne voit PAS les notes de Lina Martin │
|
|
-- └──────────────────────────────────────────────────────────────────────────┘
|
|
|
|
DO $$
|
|
DECLARE
|
|
v_tenant_id UUID;
|
|
v_class_6a_id UUID;
|
|
v_subject_math_id UUID;
|
|
v_subject_fr_id UUID;
|
|
v_teacher_amina_id UUID; -- prof maths, affectée
|
|
v_teacher_julie_id UUID; -- prof français, affectation retirée
|
|
v_teacher_david_id UUID; -- prof anglais, utilisé comme remplaçant
|
|
v_student_lina_id UUID;
|
|
v_student_chloe_id UUID;
|
|
v_student_hugo_id UUID;
|
|
v_student_zoe_id UUID;
|
|
v_eval_math_id UUID;
|
|
v_eval_fr_id UUID;
|
|
v_subdomain TEXT := 'ecole-beta';
|
|
BEGIN
|
|
-- Résoudre le tenant via les utilisateurs démo
|
|
SELECT tenant_id INTO v_tenant_id
|
|
FROM users WHERE email = 'prof.amina.benali.' || v_subdomain || '@classeo.test' LIMIT 1;
|
|
|
|
IF v_tenant_id IS NULL THEN
|
|
RAISE EXCEPTION 'Aucun compte démo trouvé pour %. Lancez `make generate-demo` d''abord.', v_subdomain;
|
|
END IF;
|
|
|
|
-- Résoudre les entités de démo existantes
|
|
SELECT id INTO v_class_6a_id FROM school_classes WHERE tenant_id = v_tenant_id AND name = '6A';
|
|
SELECT id INTO v_subject_math_id FROM subjects WHERE tenant_id = v_tenant_id AND code = 'MATH';
|
|
SELECT id INTO v_subject_fr_id FROM subjects WHERE tenant_id = v_tenant_id AND code = 'FR';
|
|
|
|
SELECT id INTO v_teacher_amina_id FROM users WHERE tenant_id = v_tenant_id AND email = 'prof.amina.benali.' || v_subdomain || '@classeo.test';
|
|
SELECT id INTO v_teacher_julie_id FROM users WHERE tenant_id = v_tenant_id AND email = 'prof.julie.caron.' || v_subdomain || '@classeo.test';
|
|
SELECT id INTO v_teacher_david_id FROM users WHERE tenant_id = v_tenant_id AND email = 'prof.david.nguyen.' || v_subdomain || '@classeo.test';
|
|
|
|
SELECT id INTO v_student_lina_id FROM users WHERE tenant_id = v_tenant_id AND email = 'eleve.lina.martin.' || v_subdomain || '@classeo.test';
|
|
SELECT id INTO v_student_chloe_id FROM users WHERE tenant_id = v_tenant_id AND email = 'eleve.chloe.lopez.' || v_subdomain || '@classeo.test';
|
|
SELECT id INTO v_student_hugo_id FROM users WHERE tenant_id = v_tenant_id AND email = 'eleve.hugo.lopez.' || v_subdomain || '@classeo.test';
|
|
SELECT id INTO v_student_zoe_id FROM users WHERE tenant_id = v_tenant_id AND email = 'eleve.zoe.moreau.' || v_subdomain || '@classeo.test';
|
|
|
|
-- Vérifications
|
|
IF v_class_6a_id IS NULL THEN RAISE EXCEPTION 'Classe 6A introuvable.'; END IF;
|
|
IF v_subject_math_id IS NULL THEN RAISE EXCEPTION 'Matière MATH introuvable.'; END IF;
|
|
IF v_teacher_amina_id IS NULL THEN RAISE EXCEPTION 'Prof Amina introuvable.'; END IF;
|
|
IF v_teacher_david_id IS NULL THEN RAISE EXCEPTION 'Prof David introuvable.'; END IF;
|
|
IF v_student_lina_id IS NULL THEN RAISE EXCEPTION 'Élève Lina introuvable.'; END IF;
|
|
|
|
-- =========================================================================
|
|
-- 1. Évaluation de maths en 6A (propriétaire = Amina, affectée)
|
|
-- =========================================================================
|
|
v_eval_math_id := gen_random_uuid();
|
|
|
|
INSERT INTO evaluations (id, tenant_id, class_id, subject_id, teacher_id, title, description, evaluation_date, grade_scale, coefficient, status, created_at, updated_at, grades_published_at)
|
|
VALUES (v_eval_math_id, v_tenant_id, v_class_6a_id, v_subject_math_id, v_teacher_amina_id,
|
|
'Contrôle — Fractions', 'Chapitre 4 : fractions et décimaux',
|
|
CURRENT_DATE - INTERVAL '3 days', 20, 1.0, 'published', NOW(), NOW(),
|
|
NOW() - INTERVAL '2 days');
|
|
|
|
-- Notes pour les 4 élèves de 6A
|
|
-- Lina et Hugo : saisies par David (remplaçant) → badge "Remplaçant" visible
|
|
-- Chloe et Zoe : saisies par Amina (titulaire) → pas de badge
|
|
INSERT INTO grades (id, tenant_id, evaluation_id, student_id, value, status, created_by, created_at, updated_at)
|
|
VALUES
|
|
(gen_random_uuid(), v_tenant_id, v_eval_math_id, v_student_lina_id, 16.5, 'graded', v_teacher_david_id, NOW(), NOW()),
|
|
(gen_random_uuid(), v_tenant_id, v_eval_math_id, v_student_chloe_id, 12.0, 'graded', v_teacher_amina_id, NOW(), NOW()),
|
|
(gen_random_uuid(), v_tenant_id, v_eval_math_id, v_student_hugo_id, NULL, 'absent', v_teacher_david_id, NOW(), NOW()),
|
|
(gen_random_uuid(), v_tenant_id, v_eval_math_id, v_student_zoe_id, 18.0, 'graded', v_teacher_amina_id, NOW(), NOW());
|
|
|
|
-- Statistiques
|
|
INSERT INTO evaluation_statistics (evaluation_id, average, min_grade, max_grade, median_grade, graded_count, updated_at)
|
|
VALUES (v_eval_math_id, 15.5, 12.0, 18.0, 16.5, 3, NOW())
|
|
ON CONFLICT (evaluation_id) DO NOTHING;
|
|
|
|
-- =========================================================================
|
|
-- 2. Évaluation de français en 6A (propriétaire = Julie)
|
|
-- Julie aura son affectation RETIRÉE → AC2
|
|
-- =========================================================================
|
|
v_eval_fr_id := gen_random_uuid();
|
|
|
|
INSERT INTO evaluations (id, tenant_id, class_id, subject_id, teacher_id, title, description, evaluation_date, grade_scale, coefficient, status, created_at, updated_at, grades_published_at)
|
|
VALUES (v_eval_fr_id, v_tenant_id, v_class_6a_id, v_subject_fr_id, v_teacher_julie_id,
|
|
'Dictée — Les Misérables', NULL,
|
|
CURRENT_DATE - INTERVAL '5 days', 20, 1.0, 'published', NOW(), NOW(),
|
|
NOW() - INTERVAL '4 days');
|
|
|
|
INSERT INTO grades (id, tenant_id, evaluation_id, student_id, value, status, created_by, created_at, updated_at)
|
|
VALUES
|
|
(gen_random_uuid(), v_tenant_id, v_eval_fr_id, v_student_lina_id, 14.0, 'graded', v_teacher_julie_id, NOW(), NOW()),
|
|
(gen_random_uuid(), v_tenant_id, v_eval_fr_id, v_student_chloe_id, 17.5, 'graded', v_teacher_julie_id, NOW(), NOW());
|
|
|
|
INSERT INTO evaluation_statistics (evaluation_id, average, min_grade, max_grade, median_grade, graded_count, updated_at)
|
|
VALUES (v_eval_fr_id, 15.75, 14.0, 17.5, 15.75, 2, NOW())
|
|
ON CONFLICT (evaluation_id) DO NOTHING;
|
|
|
|
-- Retirer l'affectation français 6A de Julie → AC2
|
|
UPDATE teacher_assignments
|
|
SET status = 'removed', end_date = NOW(), updated_at = NOW()
|
|
WHERE tenant_id = v_tenant_id
|
|
AND teacher_id = v_teacher_julie_id
|
|
AND school_class_id = v_class_6a_id
|
|
AND subject_id = v_subject_fr_id;
|
|
|
|
-- =========================================================================
|
|
-- 3. Remplacement actif : David Nguyen remplace Amina en maths 6A → AC1/AC3
|
|
-- =========================================================================
|
|
INSERT INTO teacher_replacements (id, tenant_id, replaced_teacher_id, replacement_teacher_id, start_date, end_date, status, reason, created_by, created_at, updated_at)
|
|
VALUES (gen_random_uuid(), v_tenant_id, v_teacher_amina_id, v_teacher_david_id,
|
|
CURRENT_DATE - INTERVAL '1 day', CURRENT_DATE + INTERVAL '14 days',
|
|
'active', 'Formation continue — 2 semaines',
|
|
v_teacher_amina_id, NOW(), NOW());
|
|
|
|
-- Lier le remplacement à la classe/matière maths 6A
|
|
INSERT INTO replacement_classes (replacement_id, class_id, subject_id)
|
|
SELECT tr.id, v_class_6a_id, v_subject_math_id
|
|
FROM teacher_replacements tr
|
|
WHERE tr.tenant_id = v_tenant_id
|
|
AND tr.replacement_teacher_id = v_teacher_david_id
|
|
AND tr.replaced_teacher_id = v_teacher_amina_id
|
|
AND tr.status = 'active';
|
|
|
|
-- =========================================================================
|
|
-- Résumé
|
|
-- =========================================================================
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE '══════════════════════════════════════════════════════════════';
|
|
RAISE NOTICE ' Story 6.9 — Jeu de données créé !';
|
|
RAISE NOTICE '══════════════════════════════════════════════════════════════';
|
|
RAISE NOTICE ' URL : http://ecole-beta.classeo.local:5174/login';
|
|
RAISE NOTICE ' Mot de passe : DemoPassword123!';
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE ' AC1 — Enseignant affecté :';
|
|
RAISE NOTICE ' prof.amina.benali.ecole-beta@classeo.test → saisie maths 6A ✅';
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE ' AC1 — Enseignant non affecté :';
|
|
RAISE NOTICE ' prof.sophie.lambert.ecole-beta@classeo.test';
|
|
RAISE NOTICE ' → /dashboard/teacher/evaluations/%/grades → bloqué ❌', v_eval_math_id;
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE ' AC1/AC3 — Remplaçant actif + badge :';
|
|
RAISE NOTICE ' prof.david.nguyen.ecole-beta@classeo.test';
|
|
RAISE NOTICE ' → /dashboard/teacher/evaluations/%/grades → saisie ✅ + badge', v_eval_math_id;
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE ' AC2 — Affectation retirée (lecture seule) :';
|
|
RAISE NOTICE ' prof.julie.caron.ecole-beta@classeo.test';
|
|
RAISE NOTICE ' → /dashboard/teacher/evaluations/%/grades → lecture ✅ saisie ❌', v_eval_fr_id;
|
|
RAISE NOTICE '';
|
|
RAISE NOTICE ' AC4 — Parent lié / non lié :';
|
|
RAISE NOTICE ' parent.nadia.martin.ecole-beta@classeo.test → notes Lina ✅';
|
|
RAISE NOTICE ' parent.claire.bernard.ecole-beta@classeo.test → pas Lina ❌';
|
|
RAISE NOTICE '══════════════════════════════════════════════════════════════';
|
|
|
|
END $$;
|