docs: design statistiques mensuelles dans la page rapports
This commit is contained in:
66
docs/plans/2026-03-13-monthly-stats-design.md
Normal file
66
docs/plans/2026-03-13-monthly-stats-design.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Design : statistiques mensuelles dans la page Rapports
|
||||
|
||||
Date : 2026-03-13
|
||||
|
||||
## Objectif
|
||||
|
||||
Ajouter une section "Détail mensuel" sous les cartes annuelles existantes dans `/reports`. 12 cartes (une par mois) donnant en un coup d'œil : distance parcourue par mode de transport + durée de travail typique.
|
||||
|
||||
## Décisions clés
|
||||
|
||||
- **Types de jours inclus** : tous les jours enregistrés (y compris absences = 0 min).
|
||||
- **Statistique temporelle** : médiane (plus robuste que la moyenne face aux GARDE à 10h et aux absences).
|
||||
- **"Par semaine"** : médiane de la durée totale hebdomadaire (somme des minutes par semaine ISO, puis médiane).
|
||||
- **Layout** : 12 cartes empilées sous un titre "Détail mensuel".
|
||||
- **Couleurs transport** : évocatrices (vert vélo, indigo électrique, ambre diesel).
|
||||
|
||||
## Architecture
|
||||
|
||||
### Données calculées par mois
|
||||
|
||||
```python
|
||||
monthly_data[month_int] = {
|
||||
"km_by_vehicle": {vehicle_id: km},
|
||||
"km_total": int,
|
||||
"median_daily_min": int, # médiane de entry.total_minutes() sur toutes les entries du mois
|
||||
"median_weekly_min": int, # médiane des sommes hebdomadaires (semaines ISO)
|
||||
"entry_count": int,
|
||||
}
|
||||
```
|
||||
|
||||
### Répartition du code
|
||||
|
||||
- **`app/business/time_calc.py`** : nouvelle fonction `monthly_stats(entries)` → calcule les médianes journalière et hebdomadaire. Pas de dépendance Flask.
|
||||
- **`app/routes/reports.py`** : groupement des entries par mois + calcul des km par véhicule (déjà dans ce fichier), appel de `monthly_stats`, transmission du tout au template.
|
||||
- **`app/templates/reports.html`** : section "Détail mensuel" avec les 12 cartes.
|
||||
|
||||
## Visuel des cartes
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ JANVIER 21 jours │
|
||||
│ │
|
||||
│ 312 km │
|
||||
│ [████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░] │
|
||||
│ ■ Vélo (132 km) ■ Électrique (108 km) │
|
||||
│ ■ Diesel (72 km) │
|
||||
│ │
|
||||
│ Médiane/jour 7h52 Médiane/sem. 38h45 │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Barre transport** : `div` flex, sections `width: X%` en `style=` inline (contrainte Tailwind CDN).
|
||||
- **Couleurs** :
|
||||
- Vélo → `#4ade80` (vert vif)
|
||||
- Électrique (fuel = "electric") → `#818cf8` (indigo)
|
||||
- Diesel → `#d4a574` (ambre chaud)
|
||||
- **Légende** : carré coloré + nom du véhicule + km, sous la barre.
|
||||
- **Mois vide** (0 entrées) : carte discrète, texte "Aucune entrée", sans barre.
|
||||
|
||||
## Tests
|
||||
|
||||
- Nouvelle fonction `monthly_stats()` dans `tests/test_time_calc.py` :
|
||||
- cas nominal (entries avec time_slots)
|
||||
- absences (total_minutes = 0) incluses dans la médiane
|
||||
- mois avec une seule semaine
|
||||
- Route `reports` : vérifier que `monthly_data` est bien transmis au template (test existant à étendre si besoin).
|
||||
Reference in New Issue
Block a user