-- ============================================================================= -- 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 $$;