# Spec — Alertes

> Statut : `done`

## Intention

Faire remonter au prof responsable ce qui mérite son attention, sans qu'il ait à ouvrir chaque écran pour le chercher : les produits qui vont manquer, ceux dont le suivi décroche, et les sessions de caisse dont l'écart sort de l'ordinaire.

Depuis l'[ADR-0007](../decisions/0007-vente-jamais-bloquee-par-stock.md), le stock négatif n'est plus empêché. Sans un dispositif qui le signale, il passerait simplement inaperçu.

## Contraintes

- Réservé aux admins, scopé à l'association.
- **En application uniquement.** Une alerte est un état lu à l'écran, jamais une notification poussée. Depuis le lot 11 ([mail.md](mail.md)) l'application sait envoyer des e-mails, et elle ne s'en sert toujours pas ici : un stock bas n'est pas un événement, c'est une situation, et une boîte pleine d'alertes automatiques ne se lit plus.
- Pas de table d'alertes ni de tâche planifiée en v1 : une alerte est **calculée à la lecture** depuis les données existantes. Rien à stocker, rien à synchroniser, rien qui puisse devenir périmé.
- Les seuils sont réglables par association.

## Comportement attendu

### Alertes de stock

| Niveau | Condition | Sens |
|---|---|---|
| Attention | `0 < stock ≤ seuil bas` | Il faut recommander |
| Rupture | `stock = 0` | Il n'y en a plus, en principe |
| Décrochage | `stock < 0` | Le suivi ment, un inventaire s'impose |

Le seuil bas est défini par association, avec une valeur par défaut. Un seuil propre à un produit pourra s'ajouter plus tard.

Le niveau « décrochage » est le plus important des trois : il ne dit pas qu'il manque de la marchandise, il dit que **le chiffre affiché n'est plus fiable**. Il renvoie vers l'inventaire.

### Alertes d'écart de caisse

Une session clôturée est signalée si la **valeur absolue** de son écart dépasse le seuil de l'association — un surplus de 12 € interroge autant qu'un manque de 12 €.

Avec le rapprochement CB (voir `caisses-sessions.md`), l'écart espèces et l'écart carte sont évalués **séparément** : ils n'ont pas la même cause. Un écart espèces, c'est du comptage ou de la monnaie rendue. Un écart carte, c'est presque toujours un moyen de paiement mal saisi.

### Où elles apparaissent

1. **Tableau de bord** — aujourd'hui une simple redirection vers les produits. Il devient l'écran qui ouvre le back-office et résume l'état : produits sous le seuil, produits en décrochage, sessions à regarder. Chaque ligne mène à l'écran concerné.
2. **Pastille dans le menu** — un compteur sur « Produits » et sur « Sessions de caisse ».
3. **Sur les écrans concernés** — la liste des produits et la liste des sessions marquent les lignes en alerte, sans nécessiter le tableau de bord.

### Ce qui n'alerte pas

- Le front de vente n'affiche aucune alerte de gestion. Le vendeur voit le stock sur la carte produit, ça suffit ; le reste n'est pas son sujet et lui coûterait du temps.
- Un écart de caisse ne bloque jamais une clôture (voir `caisses-sessions.md`).
- Pas d'alerte sur une session simplement ouverte depuis longtemps : une session qui traîne n'est pas un problème en soi.


### Ce que le tableau de bord montre en plus

Au-delà des alertes, il ouvre sur le **chiffre de la semaine en cours** — CA, nombre de ventes, répartition espèces/SumUp — et sur les cinq produits qui se vendent le mieux. C'est la question qu'on se pose en ouvrant le back-office, avant même de savoir ce qui va mal.

Le classement 20/80 proprement dit relève du chantier statistiques : ici, cinq lignes suffisent.

### Le calcul est partagé, pas dupliqué

Le niveau d'alerte d'un stock et le dépassement d'un seuil d'écart sont exposés aux gabarits par une extension Twig (`ea_niveau_alerte`, `ea_ecart_hors_seuil`) qui appelle `AlerteService`. La liste des produits, celle des sessions et le tableau de bord passent donc par le **même** code.

Sans ça, un produit pourrait être signalé sur un écran et pas sur l'autre, et plus personne ne saurait lequel des deux dit vrai.

## Critères de « fait »

- [x] Seuils par association : seuil de stock bas (5), seuil d'écart de caisse (5,00 €), réglables depuis « Mon association ».
- [x] `AlerteService` calcule les alertes à la lecture, sans table dédiée.
- [x] Tableau de bord back-office listant les alertes, chaque ligne cliquable vers l'écran concerné.
- [x] Pastilles de comptage dans le menu, sur « Produits » et « Sessions de caisse ».
- [x] Lignes en alerte marquées dans la liste des produits et celle des sessions.
- [x] Écarts espèces et carte évalués séparément.
- [x] Aucune alerte sur le front de vente.
- [x] Tout est scopé à l'association.

## Notes

Si un mailer est branché plus tard, un récapitulatif hebdomadaire au prof responsable serait le premier usage à couvrir — pas une notification par événement, qui serait vite ignorée.
