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:
@@ -70,7 +70,7 @@ async function loginAsStudent(page: import('@playwright/test').Page) {
|
||||
await page.locator('#email').fill(STUDENT_EMAIL);
|
||||
await page.locator('#password').fill(STUDENT_PASSWORD);
|
||||
await Promise.all([
|
||||
page.waitForURL(/\/dashboard/, { timeout: 30000 }),
|
||||
page.waitForURL(/\/dashboard/, { timeout: 60000 }),
|
||||
page.getByRole('button', { name: /se connecter/i }).click()
|
||||
]);
|
||||
}
|
||||
@@ -357,7 +357,7 @@ test.describe('Student Homework Consultation (Story 5.7)', () => {
|
||||
await page.locator('.filter-chip', { hasText: /maths/i }).click();
|
||||
|
||||
const cards = page.locator('.homework-card');
|
||||
await expect(cards).toHaveCount(1, { timeout: 5000 });
|
||||
await expect(cards).toHaveCount(1);
|
||||
await expect(cards.first().locator('.card-title')).toContainText('Exercices chapitre 3');
|
||||
});
|
||||
|
||||
@@ -369,10 +369,10 @@ test.describe('Student Homework Consultation (Story 5.7)', () => {
|
||||
|
||||
// Filter then unfilter
|
||||
await page.locator('.filter-chip', { hasText: /maths/i }).click();
|
||||
await expect(page.locator('.homework-card')).toHaveCount(1, { timeout: 5000 });
|
||||
await expect(page.locator('.homework-card')).toHaveCount(1);
|
||||
|
||||
await page.locator('.filter-chip', { hasText: /tous/i }).click();
|
||||
await expect(page.locator('.homework-card')).toHaveCount(2, { timeout: 5000 });
|
||||
await expect(page.locator('.homework-card')).toHaveCount(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -413,7 +413,7 @@ test.describe('Student Homework Consultation (Story 5.7)', () => {
|
||||
|
||||
// Reload the page
|
||||
await page.reload();
|
||||
await expect(page.locator('.homework-card').first()).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.homework-card').first()).toBeVisible({ timeout: 15000 });
|
||||
|
||||
// Done state should persist (localStorage)
|
||||
await expect(page.locator('.homework-card.done')).toBeVisible({ timeout: 5000 });
|
||||
|
||||
Reference in New Issue
Block a user