feat: Calculer automatiquement les moyennes après chaque saisie de notes
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.
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
# Story 6.3 : Calcul Automatique des Moyennes
|
||||
|
||||
Status: in-progress
|
||||
|
||||
---
|
||||
|
||||
## Story
|
||||
|
||||
En tant que **système**,
|
||||
Je veux **calculer automatiquement les moyennes par matière et générales**,
|
||||
Afin de **fournir des données actualisées instantanément après chaque saisie (FR13)**.
|
||||
|
||||
---
|
||||
|
||||
## Critères d'Acceptation
|
||||
|
||||
### AC1 : Recalcul après publication
|
||||
- [x] Note publiée → moyenne matière élève recalculée
|
||||
- [x] Moyenne générale élève recalculée
|
||||
- [x] Moyenne de classe pour l'évaluation recalculée
|
||||
- [ ] Calcul < 10ms (NFR-P9)
|
||||
|
||||
### AC2 : Calcul moyenne matière
|
||||
- [x] Formule : Σ(note × coef) / Σ(coef)
|
||||
- [x] Coefficients de chaque évaluation appliqués
|
||||
- [x] Notes "absent" et "dispensé" exclues
|
||||
|
||||
### AC3 : Calcul moyenne générale
|
||||
- [x] Coefficients matières appliqués (si configurés)
|
||||
- [x] Si pas de coef matière : moyenne arithmétique des moyennes matières
|
||||
- [x] Matières sans note exclues
|
||||
|
||||
### AC4 : Statistiques classe
|
||||
- [x] Moyenne de classe : min / max / moyenne / médiane
|
||||
- [x] Absents et dispensés exclus
|
||||
|
||||
### AC5 : Recalcul sur modification
|
||||
- [x] Note modifiée → moyennes impactées recalculées immédiatement
|
||||
- [x] Via Domain Events (eager calculation)
|
||||
|
||||
### AC6 : Mode compétences
|
||||
- [ ] Établissement avec mode compétences → seules notes chiffrées prises en compte
|
||||
- [ ] Compétences ont leur propre agrégation
|
||||
|
||||
---
|
||||
|
||||
## Tâches / Sous-tâches
|
||||
|
||||
### T1 : Service calcul moyennes (AC: #1-4)
|
||||
- [x] T1.1 : Service `AverageCalculator`
|
||||
- [x] T1.2 : Calcul moyenne matière avec coefficients
|
||||
- [x] T1.3 : Calcul moyenne générale
|
||||
- [x] T1.4 : Calcul statistiques classe
|
||||
- [x] T1.5 : Tests unitaires
|
||||
|
||||
### T2 : Domain Events triggers (AC: #5)
|
||||
- [x] T2.1 : Listener `OnNotePubliee` → recalcul
|
||||
- [x] T2.2 : Listener `OnNoteModifiee` → recalcul
|
||||
- [x] T2.3 : Tests intégration
|
||||
|
||||
### T3 : Cache Redis (AC: #1)
|
||||
- [x] T3.1 : Cache moyennes fréquemment consultées
|
||||
- [x] T3.2 : Invalidation sur modification
|
||||
- [x] T3.3 : TTL configurable
|
||||
- [x] T3.4 : Tests
|
||||
|
||||
### T4 : Stockage moyennes (AC: #1-4)
|
||||
- [x] T4.1 : Table `student_averages` dénormalisée
|
||||
- [x] T4.2 : Table `class_statistics` dénormalisée
|
||||
- [x] T4.3 : Mise à jour via events
|
||||
- [x] T4.4 : Tests intégration
|
||||
|
||||
### T5 : API Endpoints (AC: #1-4)
|
||||
- [x] T5.1 : `GET /api/students/{id}/averages` - Moyennes élève
|
||||
- [x] T5.2 : `GET /api/classes/{id}/statistics` - Stats classe
|
||||
- [x] T5.3 : `GET /api/evaluations/{id}/statistics` - Stats évaluation
|
||||
|
||||
---
|
||||
|
||||
## Notes Développeur
|
||||
|
||||
### Dépendances
|
||||
|
||||
- **Story 6.1** : Création d'évaluation
|
||||
- **Story 6.2** : Saisie notes
|
||||
|
||||
### Schema Base de Données
|
||||
|
||||
```sql
|
||||
-- Moyennes dénormalisées pour performance
|
||||
CREATE TABLE student_averages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
student_id UUID NOT NULL REFERENCES users(id),
|
||||
subject_id UUID NOT NULL REFERENCES subjects(id),
|
||||
period_id UUID NOT NULL REFERENCES academic_periods(id),
|
||||
average DECIMAL(4,2),
|
||||
grade_count INT DEFAULT 0,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (student_id, subject_id, period_id)
|
||||
);
|
||||
|
||||
CREATE TABLE student_general_averages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
student_id UUID NOT NULL REFERENCES users(id),
|
||||
period_id UUID NOT NULL REFERENCES academic_periods(id),
|
||||
average DECIMAL(4,2),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (student_id, period_id)
|
||||
);
|
||||
|
||||
CREATE TABLE evaluation_statistics (
|
||||
evaluation_id UUID PRIMARY KEY REFERENCES evaluations(id),
|
||||
average DECIMAL(4,2),
|
||||
min_grade DECIMAL(4,2),
|
||||
max_grade DECIMAL(4,2),
|
||||
median_grade DECIMAL(4,2),
|
||||
graded_count INT DEFAULT 0,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_student_averages_student ON student_averages(student_id);
|
||||
CREATE INDEX idx_student_averages_subject ON student_averages(subject_id);
|
||||
```
|
||||
|
||||
### Service Calcul Moyennes
|
||||
|
||||
```php
|
||||
final class AverageCalculator
|
||||
{
|
||||
public function calculateSubjectAverage(
|
||||
UserId $studentId,
|
||||
SubjectId $subjectId,
|
||||
PeriodId $periodId
|
||||
): ?float {
|
||||
$grades = $this->gradeRepository->findPublishedForStudentSubjectPeriod(
|
||||
$studentId,
|
||||
$subjectId,
|
||||
$periodId
|
||||
);
|
||||
|
||||
$validGrades = array_filter(
|
||||
$grades,
|
||||
fn(Grade $g) => $g->status === GradeStatus::GRADED
|
||||
);
|
||||
|
||||
if (empty($validGrades)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sumWeighted = 0;
|
||||
$sumCoef = 0;
|
||||
|
||||
foreach ($validGrades as $grade) {
|
||||
$normalizedValue = $grade->evaluation->gradeScale->convertTo20($grade->value);
|
||||
$sumWeighted += $normalizedValue * $grade->evaluation->coefficient->value;
|
||||
$sumCoef += $grade->evaluation->coefficient->value;
|
||||
}
|
||||
|
||||
return round($sumWeighted / $sumCoef, 2);
|
||||
}
|
||||
|
||||
public function calculateClassStatistics(EvaluationId $evaluationId): ClassStatistics
|
||||
{
|
||||
$grades = $this->gradeRepository->findGradedForEvaluation($evaluationId);
|
||||
$values = array_map(fn(Grade $g) => $g->value, $grades);
|
||||
|
||||
sort($values);
|
||||
|
||||
return new ClassStatistics(
|
||||
average: count($values) > 0 ? round(array_sum($values) / count($values), 2) : null,
|
||||
min: min($values) ?? null,
|
||||
max: max($values) ?? null,
|
||||
median: $this->calculateMedian($values),
|
||||
gradedCount: count($values)
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Contraintes Techniques
|
||||
|
||||
- Calculs via Domain Events (pas de batch nocturne)
|
||||
- Cache Redis pour moyennes fréquemment consultées
|
||||
- Précision : 2 décimales, arrondi au plus proche
|
||||
- Performance < 10ms (NFR-P9)
|
||||
|
||||
### FRs/NFRs Couverts
|
||||
|
||||
- **FR13** : Calcul automatique des moyennes
|
||||
- **NFR-P9** : Calculs < 10ms
|
||||
|
||||
### Structure Fichiers
|
||||
|
||||
```
|
||||
backend/src/Scolarite/
|
||||
├── Application/
|
||||
│ ├── Service/
|
||||
│ │ └── AverageCalculator.php
|
||||
│ └── Listener/
|
||||
│ ├── OnNotePubliee.php
|
||||
│ └── OnNoteModifiee.php
|
||||
└── Infrastructure/
|
||||
├── Cache/
|
||||
│ └── RedisAverageCache.php
|
||||
└── Api/
|
||||
└── AverageController.php
|
||||
```
|
||||
|
||||
### Références
|
||||
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md - Epic 6 Story 6.3]
|
||||
|
||||
---
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
|
||||
Claude Opus 4.6
|
||||
|
||||
### Debug Log References
|
||||
|
||||
### Completion Notes List
|
||||
|
||||
- **T1** : Service `AverageCalculator` dans `Domain/Service/` — calcul pondéré des moyennes matières (normalisation /20), moyenne générale (arithmétique), statistiques de classe (min/max/moyenne/médiane). Value Object `ClassStatistics` et DTO `GradeEntry`. 19 tests unitaires.
|
||||
- **T2** : Event handlers Symfony Messenger pour `NotesPubliees`, `NoteSaisie|NoteModifiee`, `EvaluationModifiee`, `EvaluationSupprimee`. Logique commune extraite dans `RecalculerMoyennesService`. Requêtes batch via `findByEvaluations()` (N+1 résolu). 8 tests unitaires.
|
||||
- **T3** : Cache Redis via Symfony Cache pools (TTL 5 min configurable). Decorators `CachingStudentAverageRepository` et `CachingEvaluationStatisticsRepository` avec invalidation sur écriture/suppression. 7 tests unitaires.
|
||||
- **T4** : Migration Doctrine pour 3 tables dénormalisées (student_averages, student_general_averages, evaluation_statistics). Repositories Doctrine avec UPSERT + DELETE. InMemory implémentations.
|
||||
- **T5** : 3 endpoints API Platform avec contrôle d'accès (ownership/role), validation UUID, tenant isolation. LEFT JOIN pour stats partielles.
|
||||
- **Backfill** : Commande `app:recalculer-moyennes` pour remplir les projections depuis les données historiques (--tenant optionnel). 4 tests unitaires.
|
||||
- **Code Review fixes** : N+1 queries résolu, NoteSaisie handler ajouté, null averages cleanup, EvaluationModifiee/Supprimee handlers, FQCN corrigé, equals() standardisé, UUID validation 400 vs 500, LEFT JOIN.
|
||||
|
||||
### File List
|
||||
|
||||
- `backend/src/Scolarite/Domain/Service/AverageCalculator.php` (new)
|
||||
- `backend/src/Scolarite/Domain/Service/GradeEntry.php` (new)
|
||||
- `backend/src/Scolarite/Domain/Model/Evaluation/ClassStatistics.php` (new)
|
||||
- `backend/src/Scolarite/Domain/Repository/EvaluationStatisticsRepository.php` (new)
|
||||
- `backend/src/Scolarite/Domain/Repository/StudentAverageRepository.php` (new)
|
||||
- `backend/src/Scolarite/Domain/Repository/EvaluationRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Domain/Repository/GradeRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Application/Port/PeriodFinder.php` (new)
|
||||
- `backend/src/Scolarite/Application/Port/PeriodInfo.php` (new)
|
||||
- `backend/src/Scolarite/Application/Service/RecalculerMoyennesService.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/Doctrine/DoctrineEvaluationRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/Doctrine/DoctrineGradeRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/Doctrine/DoctrineEvaluationStatisticsRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/Doctrine/DoctrineStudentAverageRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/InMemory/InMemoryEvaluationRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/InMemory/InMemoryGradeRepository.php` (modified)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/InMemory/InMemoryEvaluationStatisticsRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Persistence/InMemory/InMemoryStudentAverageRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Service/DoctrinePeriodFinder.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnNotesPublieesHandler.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnNoteModifieeHandler.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnEvaluationModifieeHandler.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnEvaluationSupprimeeHandler.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Cache/CachingStudentAverageRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Cache/CachingEvaluationStatisticsRepository.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Console/RecalculerToutesMoyennesCommand.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Resource/EvaluationStatisticsResource.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Resource/StudentAveragesResource.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Resource/ClassStatisticsResource.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Provider/EvaluationStatisticsProvider.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Provider/StudentAveragesProvider.php` (new)
|
||||
- `backend/src/Scolarite/Infrastructure/Api/Provider/ClassStatisticsProvider.php` (new)
|
||||
- `backend/migrations/Version20260329082334.php` (new)
|
||||
- `backend/config/packages/cache.yaml` (modified)
|
||||
- `backend/config/services.yaml` (modified)
|
||||
- `backend/tests/Unit/Scolarite/Domain/Service/AverageCalculatorTest.php` (new)
|
||||
- `backend/tests/Unit/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnNotesPublieesHandlerTest.php` (new)
|
||||
- `backend/tests/Unit/Scolarite/Infrastructure/EventHandler/RecalculerMoyennesOnNoteModifieeHandlerTest.php` (new)
|
||||
- `backend/tests/Unit/Scolarite/Infrastructure/Cache/CachingEvaluationStatisticsRepositoryTest.php` (new)
|
||||
- `backend/tests/Unit/Scolarite/Infrastructure/Cache/CachingStudentAverageRepositoryTest.php` (new)
|
||||
- `backend/tests/Unit/Scolarite/Infrastructure/Console/RecalculerToutesMoyennesCommandTest.php` (new)
|
||||
166
_bmad-output/implementation-artifacts/sprint-status.yaml
Normal file
166
_bmad-output/implementation-artifacts/sprint-status.yaml
Normal file
@@ -0,0 +1,166 @@
|
||||
# generated: 2026-01-29
|
||||
# project: classeo
|
||||
# project_key: classeo
|
||||
# tracking_system: file-system
|
||||
# story_location: _bmad-output/implementation-artifacts
|
||||
|
||||
# STATUS DEFINITIONS:
|
||||
# ==================
|
||||
# Epic Status:
|
||||
# - backlog: Epic not yet started
|
||||
# - in-progress: Epic actively being worked on
|
||||
# - done: All stories in epic completed
|
||||
#
|
||||
# Epic Status Transitions:
|
||||
# - backlog → in-progress: Automatically when first story is created (via create-story)
|
||||
# - in-progress → done: Manually when all stories reach 'done' status
|
||||
#
|
||||
# Story Status:
|
||||
# - backlog: Story only exists in epic file
|
||||
# - ready-for-dev: Story file created in stories folder
|
||||
# - in-progress: Developer actively working on implementation
|
||||
# - review: Ready for code review (via Dev's code-review workflow)
|
||||
# - done: Story completed
|
||||
#
|
||||
# Retrospective Status:
|
||||
# - optional: Can be completed but not required
|
||||
# - done: Retrospective has been completed
|
||||
#
|
||||
# WORKFLOW NOTES:
|
||||
# ===============
|
||||
# - Epic transitions to 'in-progress' automatically when first story is created
|
||||
# - Stories can be worked in parallel if team capacity allows
|
||||
# - SM typically creates next story after previous one is 'done' to incorporate learnings
|
||||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||||
|
||||
generated: 2026-01-29
|
||||
project: classeo
|
||||
project_key: classeo
|
||||
tracking_system: file-system
|
||||
story_location: _bmad-output/implementation-artifacts
|
||||
|
||||
development_status:
|
||||
# Epic 1: Fondations, Auth & Observabilité (9 stories)
|
||||
epic-1: done
|
||||
1-1-setup-projet-infrastructure: done
|
||||
1-2-foundation-multi-tenant: done
|
||||
1-3-inscription-et-activation-compte: done
|
||||
1-4-connexion-utilisateur: done
|
||||
1-5-reinitialisation-mot-de-passe: done
|
||||
1-6-gestion-sessions: done
|
||||
1-7-audit-trail-actions-sensibles: done
|
||||
1-8-observabilite-monitoring: done
|
||||
1-9-dashboard-placeholder-avec-preview-score-serenite: done
|
||||
epic-1-retrospective: optional
|
||||
|
||||
# Epic 2: Configuration Établissement (13 stories)
|
||||
epic-2: done
|
||||
2-1-creation-et-gestion-des-classes: done
|
||||
2-2-creation-et-gestion-des-matieres: done
|
||||
2-3-gestion-des-periodes-scolaires: done
|
||||
2-4-configuration-mode-de-notation: done
|
||||
2-5-creation-comptes-utilisateurs: done
|
||||
2-5b-messaging-asynchrone-fiable: done
|
||||
2-6-attribution-des-roles: done
|
||||
2-7-liaison-parents-enfants: done
|
||||
2-7b-conversion-mobile-first: done
|
||||
2-8-affectation-enseignants-aux-classes-et-matieres: done
|
||||
2-8b-pagination-et-recherche-sections-admin: done
|
||||
2-8c-migration-utilisateurs-postgresql: done
|
||||
2-9-designation-remplacants-temporaires: done
|
||||
2-10-gestion-multi-etablissements-super-admin: done
|
||||
2-11-configuration-calendrier-scolaire: done
|
||||
2-12-consultation-liste-droit-a-limage: done
|
||||
2-12b-optimistic-update-pages-admin: done
|
||||
2-13-personnalisation-visuelle-etablissement: done
|
||||
2-15-organisation-sections-dashboard-admin: done
|
||||
epic-2-retrospective: done
|
||||
|
||||
# Epic 3: Import & Onboarding (5 stories)
|
||||
epic-3: done
|
||||
3-0-creation-manuelle-eleves: done
|
||||
3-1-import-eleves-via-csv: done
|
||||
3-2-import-enseignants-via-csv: done
|
||||
3-3-generation-et-envoi-codes-invitation-parents: done
|
||||
3-4-optimisation-pagination-et-cache-requetes: done
|
||||
epic-3-retrospective: optional
|
||||
|
||||
# Epic 4: Emploi du Temps (5 stories)
|
||||
epic-4: done
|
||||
4-1-creation-et-modification-de-lemploi-du-temps: done
|
||||
4-2-recurrences-hebdomadaires: done
|
||||
4-3-consultation-edt-par-leleve: done
|
||||
4-4-consultation-edt-par-le-parent: done
|
||||
4-6-recherche-parent-liaison-eleve: done
|
||||
epic-4-retrospective: optional
|
||||
|
||||
# Epic 5: Devoirs & Règles (8 stories)
|
||||
epic-5: done
|
||||
5-1-creation-de-devoirs: done
|
||||
5-2-duplication-de-devoirs-multi-classes: done
|
||||
5-2b-optimisation-chargement-page-devoirs: done
|
||||
5-3-configuration-des-regles-de-devoirs: done
|
||||
5-4-application-des-regles-mode-soft-warning: done
|
||||
5-5-application-des-regles-mode-hard-blocage: done
|
||||
5-6-contournement-des-regles-avec-notification: done
|
||||
5-7-consultation-des-devoirs-par-leleve: done
|
||||
5-8-consultation-des-devoirs-par-le-parent: done
|
||||
5-9-description-enrichie-et-pieces-jointes-enseignant: done
|
||||
5-10-rendu-de-devoir-par-leleve: done
|
||||
epic-5-retrospective: optional
|
||||
|
||||
# Epic 6: Notes & Évaluations (8 stories)
|
||||
epic-6: in-progress
|
||||
6-1-creation-devaluation: done
|
||||
6-2-saisie-notes-grille-inline: done
|
||||
6-3-calcul-automatique-des-moyennes: in-progress
|
||||
6-4-saisie-des-appreciations: ready-for-dev
|
||||
6-5-mode-competences: ready-for-dev
|
||||
6-6-consultation-notes-par-leleve: ready-for-dev
|
||||
6-7-consultation-notes-par-le-parent: ready-for-dev
|
||||
6-8-statistiques-enseignant: ready-for-dev
|
||||
epic-6-retrospective: optional
|
||||
|
||||
# Epic 7: Vie Scolaire (8 stories)
|
||||
epic-7: in-progress
|
||||
7-1-appel-en-un-ecran: ready-for-dev
|
||||
7-2-signalement-absences: ready-for-dev
|
||||
7-3-signalement-retards: ready-for-dev
|
||||
7-4-justification-absence-par-le-parent: ready-for-dev
|
||||
7-5-historique-absences-et-retards: ready-for-dev
|
||||
7-6-gestion-dispenses-et-amenagements: ready-for-dev
|
||||
7-7-saisie-sanctions-et-recompenses: ready-for-dev
|
||||
7-8-consultation-vie-scolaire-par-le-parent: ready-for-dev
|
||||
epic-7-retrospective: optional
|
||||
|
||||
# Epic 8: Dashboard Sérénité & Recherche (5 stories)
|
||||
epic-8: in-progress
|
||||
8-1-dashboard-parent-avec-score-serenite: ready-for-dev
|
||||
8-2-configuration-et-opt-out-score-serenite: ready-for-dev
|
||||
8-3-dashboard-enseignant: ready-for-dev
|
||||
8-4-dashboard-direction: ready-for-dev
|
||||
8-5-recherche-globale: ready-for-dev
|
||||
epic-8-retrospective: optional
|
||||
|
||||
# Epic 9: Communication & Notifications (7 stories)
|
||||
epic-9: in-progress
|
||||
9-1-messagerie-enseignant-parents-eleves: ready-for-dev
|
||||
9-2-messagerie-direction-etablissement: ready-for-dev
|
||||
9-3-accuses-de-lecture-et-statistiques: ready-for-dev
|
||||
9-4-notifications-push-pwa: ready-for-dev
|
||||
9-5-notifications-email: ready-for-dev
|
||||
9-6-preferences-de-notification: ready-for-dev
|
||||
4-5-notifications-de-modification-edt: ready-for-dev # Déplacée : dépend de 9.4 et 9.6
|
||||
9-7-digest-hebdomadaire-serenite: ready-for-dev
|
||||
epic-9-retrospective: optional
|
||||
|
||||
# Epic 10: Documents & Conformité (7 stories)
|
||||
epic-10: in-progress
|
||||
10-1-generation-bulletins-pdf: ready-for-dev
|
||||
10-2-telechargement-bulletins: ready-for-dev
|
||||
10-3-verrouillage-et-deverrouillage-des-notes: ready-for-dev
|
||||
10-4-certificat-de-scolarite: ready-for-dev
|
||||
10-5-gestion-cycle-de-vie-des-donnees: ready-for-dev
|
||||
10-6-droits-rgpd-utilisateurs: ready-for-dev
|
||||
10-7-passage-de-classe-et-cloture-annee: ready-for-dev
|
||||
epic-10-retrospective: optional
|
||||
Reference in New Issue
Block a user