8 Commits

Author SHA1 Message Date
b7dc27f2a5 feat: Calculer automatiquement les moyennes après chaque saisie de notes
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled
Les enseignants ont besoin de moyennes à jour immédiatement après la
publication ou modification des notes, sans attendre un batch nocturne.

Le système recalcule via Domain Events synchrones : statistiques
d'évaluation (min/max/moyenne/médiane), moyennes matières pondérées
(normalisation /20), et moyenne générale par élève. Les résultats sont
stockés dans des tables dénormalisées avec cache Redis (TTL 5 min).

Trois endpoints API exposent les données avec contrôle d'accès par rôle.
Une commande console permet le backfill des données historiques au
déploiement.
2026-04-04 02:25:00 +02:00
23dd7177f2 feat: Optimiser la pagination avec cache-aside et ports de lecture dédiés
Les listes paginées (utilisateurs, classes, matières, affectations,
invitations parents, droits à l'image) effectuaient des requêtes SQL
complètes à chaque chargement de page, sans aucun cache. Sur les
établissements avec plusieurs centaines d'enregistrements, cela causait
des temps de réponse perceptibles et une charge inutile sur PostgreSQL.

Cette refactorisation introduit un cache tag-aware (Redis en prod,
filesystem en dev) avec invalidation événementielle, et extrait les
requêtes de lecture dans des ports Application / implémentations DBAL
conformes à l'architecture hexagonale. Un middleware Messenger garantit
l'invalidation synchrone du cache même pour les événements routés en
asynchrone (envoi d'emails), évitant ainsi toute donnée périmée côté UI.
2026-03-01 14:33:56 +01:00
44ebe5e511 feat: Liaison parents-enfants avec gestion des tuteurs
Les parents doivent pouvoir suivre la scolarité de leurs enfants (notes,
emploi du temps, devoirs). Cela nécessite un lien formalisé entre le
compte parent et le compte élève, géré par les administrateurs.

Le lien est établi soit manuellement via l'interface d'administration,
soit automatiquement lors de l'activation du compte parent lorsque
l'invitation inclut un élève cible. Ce lien conditionne l'accès aux
données scolaires de l'enfant (autorisations vérifiées par un voter
dédié).
2026-02-12 08:38:19 +01:00
b823479658 feat: Gestion des sessions utilisateur
Permet aux utilisateurs de visualiser et gérer leurs sessions actives
sur différents appareils, avec la possibilité de révoquer des sessions
à distance en cas de suspicion d'activité non autorisée.

Fonctionnalités :
- Liste des sessions actives avec métadonnées (appareil, navigateur, localisation)
- Identification de la session courante
- Révocation individuelle d'une session
- Révocation de toutes les autres sessions
- Déconnexion avec nettoyage des cookies sur les deux chemins (legacy et actuel)

Sécurité :
- Cache frontend scopé par utilisateur pour éviter les fuites entre comptes
- Validation que le refresh token appartient à l'utilisateur JWT authentifié
- TTL des sessions Redis aligné sur l'expiration du refresh token
- Événements d'audit pour traçabilité (SessionInvalidee, ToutesSessionsInvalidees)

@see Story 1.6 - Gestion des sessions
2026-02-03 10:53:31 +01:00
affad287f9 feat: Réinitialisation de mot de passe avec tokens sécurisés
Implémentation complète du flux de réinitialisation de mot de passe (Story 1.5):

Backend:
- Aggregate PasswordResetToken avec TTL 1h, UUID v7, usage unique
- Endpoint POST /api/password/forgot avec rate limiting (3/h par email, 10/h par IP)
- Endpoint POST /api/password/reset avec validation token
- Templates email (demande + confirmation)
- Repository Redis avec TTL 2h pour distinguer expiré/invalide

Frontend:
- Page /mot-de-passe-oublie avec message générique (anti-énumération)
- Page /reset-password/[token] avec validation temps réel des critères
- Gestion erreurs: token invalide, expiré, déjà utilisé

Tests:
- 14 tests unitaires PasswordResetToken
- 7 tests unitaires RequestPasswordResetHandler
- 7 tests unitaires ResetPasswordHandler
- Tests E2E Playwright pour le flux complet
2026-02-02 09:45:15 +01:00
b9d9f48305 feat: Connexion utilisateur avec sécurité renforcée
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
2026-02-01 14:43:12 +01:00
c5e6c1d810 feat: Activation de compte utilisateur avec validation token
L'inscription Classeo se fait via invitation : un admin crée un compte,
l'utilisateur reçoit un lien d'activation par email pour définir son
mot de passe. Ce flow sécurisé évite les inscriptions non autorisées
et garantit que seuls les utilisateurs légitimes accèdent au système.

Points clés de l'implémentation :
- Tokens d'activation à usage unique stockés en cache (Redis/filesystem)
- Validation du consentement parental pour les mineurs < 15 ans (RGPD)
- L'échec d'activation ne consume pas le token (retry possible)
- Users dans un cache séparé sans TTL (pas d'expiration)
- Hot reload en dev (FrankenPHP sans mode worker)

Story: 1.3 - Inscription et activation de compte
2026-01-31 19:34:03 +01:00
6da5996340 feat: Setup projet Classeo avec infrastructure Docker et architecture DDD
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
2026-01-30 15:31:07 +01:00