Gestion de stock IT pour le département IT d'une clinique privée (catégories, matériels, scan code-barres, alertes email).
Find a file
maxsoch 5792b453e7 Prépare la dockerization : Dockerfile, docker-compose, .dockerignore
Image Python 3.14-slim (même version qu'en dev local), utilisateur
non-root, healthcheck sans dépendance externe, un seul worker Uvicorn
(SQLite gère mal les écritures concurrentes multi-process). data/ monté
en volume dans docker-compose.yml pour garder la base SQLite visible et
sauvegardable directement dans le dossier du projet, comme en dev local.

Non testé avec un vrai build : Docker indisponible dans cet environnement
de dev, à vérifier avant un premier déploiement.
2026-07-14 19:44:35 +02:00
.claude Initial scaffold: gestion de stock IT pour le département IT 2026-07-14 18:38:59 +02:00
app Planification du résumé de stock modifiable depuis l'interface 2026-07-14 19:37:36 +02:00
data Initial scaffold: gestion de stock IT pour le département IT 2026-07-14 18:38:59 +02:00
scripts Résumé de stock dans les alertes + email récapitulatif planifié 2026-07-14 19:28:39 +02:00
tests Planification du résumé de stock modifiable depuis l'interface 2026-07-14 19:37:36 +02:00
.dockerignore Prépare la dockerization : Dockerfile, docker-compose, .dockerignore 2026-07-14 19:44:35 +02:00
.env.example Planification du résumé de stock modifiable depuis l'interface 2026-07-14 19:37:36 +02:00
.gitignore Initial scaffold: gestion de stock IT pour le département IT 2026-07-14 18:38:59 +02:00
CLAUDE.md Prépare la dockerization : Dockerfile, docker-compose, .dockerignore 2026-07-14 19:44:35 +02:00
docker-compose.yml Prépare la dockerization : Dockerfile, docker-compose, .dockerignore 2026-07-14 19:44:35 +02:00
Dockerfile Prépare la dockerization : Dockerfile, docker-compose, .dockerignore 2026-07-14 19:44:35 +02:00
pyproject.toml Initial scaffold: gestion de stock IT pour le département IT 2026-07-14 18:38:59 +02:00
README.md Prépare la dockerization : Dockerfile, docker-compose, .dockerignore 2026-07-14 19:44:35 +02:00
requirements-dev.txt Initial scaffold: gestion de stock IT pour le département IT 2026-07-14 18:38:59 +02:00
requirements.txt Résumé de stock dans les alertes + email récapitulatif planifié 2026-07-14 19:28:39 +02:00

Gestion de stock IT

Application web pour le département IT d'une clinique, permettant de gérer le stock de matériel informatique (catégories / sous-catégories / matériels), avec scan de codes-barres et alertes email de stock bas.

Pas de système d'authentification dans l'app : l'accès est censé être restreint par un mécanisme externe (réseau interne, proxy, etc.).

Stack

  • Python + FastAPI : serveur web, un seul processus.
  • SQLite : base de données fichier (data/stock.db), aucun serveur à installer.
  • Jinja2 : pages HTML rendues côté serveur, formulaires classiques (pas de JS de build).
  • SQLModel : ORM (combine SQLAlchemy + validation Pydantic).

Tout vit dans ce dossier : pas de service externe requis pour développer et tester en local (les emails d'alerte sont simulés dans la console tant qu'aucun SMTP n'est configuré, voir plus bas).

Démarrer en local

python3 -m venv .venv
source .venv/bin/activate          # Windows : .venv\Scripts\activate
pip install -r requirements-dev.txt
cp .env.example .env               # optionnel en local, voir ci-dessous
uvicorn app.main:app --reload

L'app est accessible sur http://127.0.0.1:8000. La base SQLite est créée automatiquement au premier démarrage dans data/stock.db.

Lancer avec Docker

cp .env.example .env               # requis, voir Configuration des emails ci-dessous
docker compose up --build

L'app est accessible sur http://localhost:8000. data/ est monté depuis l'hôte : la base SQLite (data/stock.db) reste au même endroit qu'en dev local sans Docker, visible et sauvegardable directement dans ce dossier.

Un seul worker Uvicorn dans le conteneur (voir commentaire dans le Dockerfile) : SQLite gère mal les écritures concurrentes depuis plusieurs process, et un seul worker est largement suffisant pour l'usage interne visé.

Pour du développement actif, la boucle venv + --reload ci-dessus reste plus rapide (pas de rebuild d'image à chaque changement) ; Docker sert surtout à tester ou reproduire l'environnement de déploiement.

Lancer les tests

source .venv/bin/activate
pytest

Lancer le linter

source .venv/bin/activate
ruff check .

Configuration des emails

Les emails de stock (alerte immédiate + résumé périodique) sont envoyés via le relais SMTP interne de la clinique, configuré par variables d'environnement (voir .env.example) :

SMTP_HOST=...
SMTP_PORT=25
SMTP_USER=...
SMTP_PASSWORD=...
SMTP_FROM=stock-it@clinique.local

Si SMTP_HOST n'est pas renseigné (cas du dev local), rien n'est réellement envoyé : les emails sont affichés dans la console du serveur (--- [EMAIL SIMULÉ] ---). Ça permet de développer et tester tout le flux sans avoir de vrai serveur mail sous la main.

Deux emails distincts :

  • Alerte immédiate : envoyée dès qu'un matériel passe sous son seuil d'alerte (Materiel.seuil_alerte). Contient ce matériel, puis un résumé de tous les articles actuellement en stock bas.
  • Résumé périodique : stock bas en premier, puis le reste du stock groupé par catégorie. L'horaire se configure depuis l'interface, sur /destinataires (raccourcis courants + expression cron personnalisée) — pas de fichier à éditer, le changement s'applique immédiatement sans redémarrer le serveur. Défaut : tous les lundis à 9h. Le planificateur (APScheduler) tourne dans le process de l'app, rien à configurer côté système d'exploitation. Pour déclencher l'envoi manuellement (test, ou pour le brancher sur un cron système / Planificateur de tâches Windows à la place) : python scripts/envoyer_resume_stock.py.

Les destinataires (plusieurs possibles) se gèrent aussi sur /destinataires.

Douchette code-barres

Aucune intégration logicielle particulière : une douchette USB (ou Bluetooth) émule un clavier, elle "tape" le code puis Entrée. La page /scan a un simple champ de texte auto-focus dans un formulaire ; Entrée soumet automatiquement le formulaire.

Structure du projet

app/
  main.py              point d'entrée FastAPI, démarrage du planificateur
  config.py            lecture des variables d'environnement
  database.py           connexion SQLite
  models.py             modèles SQLModel (Categorie en arborescence, Materiel, DestinataireAlerte)
  categories_arbre.py    parcours de l'arborescence de catégories
  email_alerts.py        alerte immédiate + résumé périodique de stock
  scheduler.py            planification (APScheduler) du résumé périodique
  templates_engine.py    instance Jinja2Templates partagée
  routers/               une route FastAPI par ressource (categories, materiels, scan, destinataires)
  templates/              pages HTML (Jinja2)
  static/                 CSS
scripts/
  seed.py                 peuple la base avec des données de démo
  envoyer_resume_stock.py déclenche manuellement l'email récapitulatif
tests/                   tests pytest (client de test FastAPI + base SQLite en mémoire)
data/                    base SQLite locale (ignorée par git)
Dockerfile               image de l'app (Python 3.14-slim, utilisateur non-root, 1 worker Uvicorn)
docker-compose.yml       lancement local avec data/ monté en volume