# Avancement - Lot 6 (Communication générale, Module 6, §9 du cahier des charges v4.1)

*Même principe que `documentation/avancement-lot5.md`. Points hors
scope consolidés dans `documentation/backlog-v2.md` ; questions de
conception ouvertes dans `documentation/decisions-a-prendre.md`.*

## §9.2 Fonctionnalités

| Fonctionnalité | État | Détail |
| --- | --- | --- |
| Annonces générales | ✅ | Diffusion Direction/équipe → tous les parents, append-only - 2026-08-05 |
| Calendrier des événements | ✅ | Liste chronologique, append-only - 2026-08-05 |
| Sondages simples | ✅ | Question + options, un vote par parent, résultats agrégés - 2026-08-05 |

## Détail (livré le 2026-08-05, incrément unique)

Module 5 clos. Module 6 est la suite logique dans l'ordre du cahier
des charges (§3).

Acteurs (§9.1) : "Direction / équipe → tous les parents" - diffusion à
sens unique, à distinguer de `Message` (§5.2.f, toujours rattaché à un
`Enfant` précis) et de `TransmissionEquipe` (§5.2.e, note interne non
visible des parents).

Décisions de scope :
- **Écrans "principaux" interprétés comme non-exhaustifs** : §9.3 ne
  nomme que "Liste des annonces" et "Calendrier des événements", mais
  §9.2 liste 3 fonctionnalités dont "sondages simples" - un vote/des
  résultats agrégés ne s'intègrent pas proprement dans un flux de
  lecture passive, un écran dédié `/equipe/sondages` +
  `/parents/sondages` a donc été ajouté.
- **Trois entités append-only** (`Annonce`, `Evenement`, `Sondage` +
  `SondageOption`/`SondageVote`), même pattern que `TransmissionEquipe`
  (§5.2.e) : pas d'édition ni de suppression en V1. Pas de
  `JournalAuditService` non plus, comme `MessageService`/
  `TransmissionEquipeService` - communication opérationnelle, pas
  financière/administrative sensible.
- **Aucune nouvelle règle `security.yaml`** : les routes staff vivent
  sous `/equipe` (déjà `ROLE_EDUCATEUR`, hérité par `ROLE_DIRECTION` -
  couvre exactement l'acteur "Direction / équipe") et les routes
  parent sous `/parents` (déjà `ROLE_PARENT`).
- **"Calendrier" = liste chronologique triée**, pas un widget JS de
  calendrier mensuel - cohérent avec l'absence de framework CSS/JS
  (§2) et le style du reste de l'app.
- **Portée établissement, pas groupe** : contrairement à `Message`/
  `TransmissionEquipe`, une annonce/un événement/un sondage cible tous
  les parents de l'établissement - un seul enregistrement visible par
  tous, pas de fan-out par enfant.
- **Résolution de l'établissement du parent** via
  `EnfantRepository::findPourResponsable()` (déjà existant, §5.2) :
  `User.etablissement` est `null` pour un compte Parent, résolu par
  son premier enfant rattaché (mono-site). 403 si aucun enfant.
- **Sondage "simple"** : question + options texte (une par ligne),
  ≥ 2 non vides, pas de date de clôture (toujours ouvert), un vote par
  parent et par sondage (index unique `(sondage_id, votant_id)` en
  base + vérifié en Service). Vote réservé aux parents - le staff
  consulte les résultats mais ne vote pas.
- **3 contrôleurs (un par entité), pas 6** :
  `AnnonceController`/`EvenementController`/`SondageController`
  regroupent chacun leurs routes `/equipe/...` et `/parents/...` sans
  préfixe de classe unique - léger écart au principe "un contrôleur =
  un préfixe" déjà en place, pour éviter 3 paires de contrôleurs
  quasi-vides. La sécurité reste garantie par `security.yaml`
  (basée sur le chemin, pas sur la classe).

**Nouvelles entités** (+ repositories) : `Annonce`, `Evenement`,
`Sondage`/`SondageOption`/`SondageVote`. **Nouveaux services** :
`AnnonceService` (`publier()`/`listerPourEtablissement()`),
`EvenementService` (`planifier()`, rejette une date de fin antérieure
à la date de début), `SondageService` (`creer()`/`voter()`/`aVote()`/
`resultats()`/`listerPourEtablissement()`). **Nouveaux contrôleurs** :
`AnnonceController`, `EvenementController`, `SondageController`.
**Nouveaux templates** : `equipe/annonces.html.twig`,
`parents/annonces.html.twig`, `equipe/calendrier.html.twig`,
`parents/calendrier.html.twig`, `equipe/sondages.html.twig`,
`parents/sondages.html.twig`. **Navigation** : liens ajoutés dans
`equipe/tableau_de_bord_groupe.html.twig` et `parents/mes_enfants.html.twig`.

Vérifié manuellement (serveur PHP local + curl, comptes Direction/
Éducateur/Comptabilité/Parent) :
- Annonce publiée par un Éducateur, visible immédiatement côté parent
  (titre, contenu, date, exact).
- Événement avec date de fin antérieure à la date de début →
  rejeté avec message clair, aucune ligne créée ; événement valide
  planifié par Direction, visible côté parent avec tous les champs
  (titre/dates/lieu/description) exacts.
- Sondage à 2 options créé par un Éducateur ; parent voit le
  formulaire de vote, vote "Samedi" → résultats **Samedi : 1 voix,
  Dimanche : 0 voix** identiques côté parent et côté équipe ;
  formulaire de vote disparaît après le vote (résultats affichés à la
  place) ; **second vote du même parent rejeté** ("Vous avez déjà voté
  à ce sondage."), décompte inchangé, une seule ligne en base
  (`sondage_vote`, contrainte unique confirmée).
- **403 pour Comptabilité sur `/equipe/annonces`** (pas dans la
  hiérarchie de rôles vers `ROLE_EDUCATEUR`) ; **403 croisés** : parent
  sur `/equipe/annonces`, éducateur sur `/parents/annonces`.

`php bin/phpunit` : 232 tests, 549 assertions, tous verts (3 nouveaux
fichiers de tests, 18 cas). `doctrine:schema:validate` : mapping et
base synchronisés après migration (5 nouvelles tables : `annonce`,
`evenement`, `sondage`, `sondage_option`, `sondage_vote`).
`lint:twig`/`lint:container` : OK.

## Prochaine étape

Module 6 clos - tous les modules fonctionnels du cahier des charges
(§4 à §9) sont désormais couverts. Reste **Module 7 (§10, Exigences
d'exploitation, transverse)** : objectifs mesurables de performance,
disponibilité, sécurité - à évaluer pour savoir ce qui relève de
code applicatif (ex. limites de débit, journalisation) versus
d'infrastructure/exploitation hors scope de ce dépôt.
