Les parents avaient accès au lien "Emploi du temps" dans la navigation,
mais le dashboard n'affichait aucune donnée réelle : la section EDT
restait un placeholder vide ("L'emploi du temps sera disponible...").
Cette implémentation connecte le dashboard parent aux vrais endpoints API
(GET /api/me/children/{childId}/schedule/day|week/{date} et le résumé
multi-enfants), affiche le ScheduleWidget avec le prochain cours mis en
évidence (AC1), permet de cliquer sur chaque enfant dans le résumé pour
voir son EDT détaillé (AC2), et met en cache les endpoints parent dans le
Service Worker pour le mode offline (AC5).
Le handler backend est optimisé pour ne résoudre que l'enfant demandé
(via childId optionnel dans la query) au lieu de tous les enfants à chaque
appel, et les fonctions utilitaires dupliquées (formatSyncDate, timezone)
sont factorisées.
Les élèves n'avaient aucun moyen de voir leur emploi du temps
depuis l'application. Cette fonctionnalité ajoute une page dédiée
avec deux modes de visualisation (jour et semaine), la navigation
temporelle, et le détail des cours au tap.
Le backend résout l'EDT de l'élève en chaînant : affectation classe →
créneaux récurrents + exceptions + calendrier scolaire → enrichissement
des noms (matières/enseignants). Le frontend utilise un cache offline
(Workbox NetworkFirst) pour rester consultable hors connexion.
Implémente la Story 1.4 du système d'authentification avec plusieurs
couches de protection contre les attaques par force brute.
Sécurité backend :
- Authentification JWT avec access token (15min) + refresh token (7j)
- Rotation automatique des refresh tokens avec détection de replay
- Rate limiting progressif par IP (délai Fibonacci après échecs)
- Intégration Cloudflare Turnstile CAPTCHA après 5 tentatives
- Alerte email à l'utilisateur après blocage temporaire
- Isolation multi-tenant (un utilisateur ne peut se connecter que sur
son établissement)
Frontend :
- Page de connexion avec feedback visuel des délais et erreurs
- Composant TurnstileCaptcha réutilisable
- Gestion d'état auth avec stockage sécurisé des tokens
- Tests E2E Playwright pour login, tenant isolation, et activation
Infrastructure :
- Configuration Symfony Security avec json_login + jwt
- Cache pools séparés (filesystem en test, Redis en prod)
- NullLoginRateLimiter pour environnement de test (évite blocage CI)
- Génération des clés JWT en CI après démarrage du backend
Une application SaaS éducative nécessite une séparation stricte des données
entre établissements scolaires. L'architecture multi-tenant par sous-domaine
(ecole-alpha.classeo.local) permet cette isolation tout en utilisant une
base de code unique.
Le choix d'une résolution basée sur les sous-domaines plutôt que sur des
headers ou tokens facilite le routage au niveau infrastructure (reverse proxy)
et offre une UX plus naturelle où chaque école accède à "son" URL dédiée.
Configure l'environnement de développement complet avec Docker Compose,
structure DDD 4 Bounded Contexts, et pipeline CI/CD GitHub Actions.
Corrections compatibilité CI:
- Symfony 8 nécessite monolog-bundle ^4.0 (la v3.x ne supporte que jusqu'à Symfony 7)
- ESLint v9 nécessite flat config (eslint.config.js) - le format .eslintrc.cjs est obsolète