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.
39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
"""
|
|
Point d'entrée de l'application FastAPI.
|
|
|
|
Lancement en local : uvicorn app.main:app --reload
|
|
"""
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
|
from app.database import init_db
|
|
from app.routers import categories, destinataires, materiels, scan
|
|
from app.scheduler import arreter_planification, demarrer_planification
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""Crée les tables SQLite au démarrage si elles n'existent pas encore,
|
|
puis démarre la planification de l'email récapitulatif de stock
|
|
(voir app/scheduler.py) — arrêtée proprement à l'extinction."""
|
|
init_db()
|
|
demarrer_planification()
|
|
yield
|
|
arreter_planification()
|
|
|
|
|
|
app = FastAPI(title="Gestion de stock IT", lifespan=lifespan)
|
|
|
|
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
|
|
|
app.include_router(categories.router)
|
|
# "/" est enregistrée directement sur le routeur materiels (voir
|
|
# lister_materiels) pour afficher la liste des matériels sans redirection
|
|
# HTTP : l'URL reste "/" plutôt que de rebondir vers "/materiels".
|
|
app.include_router(materiels.router)
|
|
app.include_router(scan.router)
|
|
app.include_router(destinataires.router)
|