From a788bf4392b470b7e05a06e3c597676d47ac09ec Mon Sep 17 00:00:00 2001 From: maxsoch Date: Tue, 14 Jul 2026 19:28:39 +0200 Subject: [PATCH] =?UTF-8?q?R=C3=A9sum=C3=A9=20de=20stock=20dans=20les=20al?= =?UTF-8?q?ertes=20+=20email=20r=C3=A9capitulatif=20planifi=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'alerte immédiate de stock bas inclut maintenant un résumé de tous les articles actuellement sous leur seuil, pas seulement celui qui l'a déclenchée. Ajout d'un second email, planifié via une expression cron (RESUME_STOCK_CRON, APScheduler intégré à l'app — pas de cron système à configurer) : stock bas en tête, puis le reste du stock groupé par catégorie. scripts/envoyer_resume_stock.py permet de le déclencher manuellement, ou de brancher l'envoi sur un cron système à la place. --- .env.example | 6 +++ CLAUDE.md | 33 +++++++++---- README.md | 39 ++++++++++++---- app/config.py | 5 ++ app/email_alerts.py | 83 ++++++++++++++++++++++++++++++--- app/main.py | 7 ++- app/scheduler.py | 50 ++++++++++++++++++++ requirements.txt | 1 + scripts/envoyer_resume_stock.py | 25 ++++++++++ tests/test_email_alerts.py | 71 ++++++++++++++++++++++++++++ 10 files changed, 295 insertions(+), 25 deletions(-) create mode 100644 app/scheduler.py create mode 100644 scripts/envoyer_resume_stock.py create mode 100644 tests/test_email_alerts.py diff --git a/.env.example b/.env.example index 04154f1..255e79e 100644 --- a/.env.example +++ b/.env.example @@ -10,3 +10,9 @@ SMTP_PORT=25 SMTP_USER= SMTP_PASSWORD= SMTP_FROM=stock-it@clinique.local + +# Expression cron (minute heure jour mois jour_semaine) pour l'email +# récapitulatif périodique de l'état du stock. Par défaut : tous les +# jours à 8h. Le planificateur tourne dans le process de l'app (voir +# app/scheduler.py) — pas de cron système à configurer. +RESUME_STOCK_CRON=0 8 * * * diff --git a/CLAUDE.md b/CLAUDE.md index 9d49dc1..91f0945 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,12 +64,13 @@ l'absence de SMTP_HOST). Ne pas se limiter au commentaire minimal habituel. ``` app/ - main.py point d'entrée FastAPI, montage des routers - config.py lecture des variables d'environnement (SMTP...) + main.py point d'entrée FastAPI, montage des routers, démarrage du planificateur + config.py lecture des variables d'environnement (SMTP, cron du résumé...) database.py connexion SQLite + dependency get_session() models.py modèles SQLModel : Categorie (arborescence auto-référencée), Materiel, DestinataireAlerte categories_arbre.py parcours de l'arborescence (racines, aplatissement pour un