88 lines
4.2 KiB
Markdown
88 lines
4.2 KiB
Markdown
|
|
# CLAUDE.md
|
||
|
|
|
||
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
|
|
||
|
|
## Projet
|
||
|
|
|
||
|
|
Application web interne pour le département IT d'une clinique privée : gestion
|
||
|
|
du stock de matériel informatique (catégories / sous-catégories / matériels),
|
||
|
|
avec recherche de matériel par scan de code-barres et alertes email quand le
|
||
|
|
stock passe sous un seuil défini.
|
||
|
|
|
||
|
|
Contraintes du domaine, volontairement strictes :
|
||
|
|
- **Pas d'authentification dans l'app** : l'accès est restreint par un
|
||
|
|
mécanisme externe (réseau interne, proxy...). Ne pas ajouter de login/session.
|
||
|
|
- **Pas de suivi d'exemplaires individuels.** Un `Materiel` est un *type*
|
||
|
|
d'objet (ex: "PC Dell XPS 13 modèle 9310", "Câble RJ45 2m") avec juste une
|
||
|
|
quantité en stock. Pas de numéro de série, pas d'historique par unité.
|
||
|
|
- **Douchette code-barres = clavier.** Les douchettes USB/Bluetooth émulent un
|
||
|
|
clavier (elles tapent le code + Entrée). Aucune intégration matérielle
|
||
|
|
n'est nécessaire côté app : un simple `<input>` seul dans un `<form>`
|
||
|
|
suffit, le navigateur soumet au Entrée.
|
||
|
|
|
||
|
|
## Stack
|
||
|
|
|
||
|
|
Python + FastAPI + SQLModel (ORM) + SQLite (fichier `data/stock.db`) +
|
||
|
|
Jinja2 (rendu HTML côté serveur, formulaires classiques, pas de bundler JS).
|
||
|
|
|
||
|
|
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 `app/email_alerts.py` et `.env.example`).
|
||
|
|
|
||
|
|
## Commandes
|
||
|
|
|
||
|
|
```bash
|
||
|
|
source .venv/bin/activate # créer avec: python3 -m venv .venv
|
||
|
|
pip install -r requirements-dev.txt
|
||
|
|
uvicorn app.main:app --reload # lancer le serveur de dev (http://127.0.0.1:8000)
|
||
|
|
pytest # lancer les tests
|
||
|
|
ruff check . # linter
|
||
|
|
```
|
||
|
|
|
||
|
|
Les tests utilisent une base SQLite **en mémoire** (voir `tests/conftest.py`),
|
||
|
|
jamais le fichier `data/stock.db` du développement.
|
||
|
|
|
||
|
|
## Convention : commentaires détaillés
|
||
|
|
|
||
|
|
Contrairement à la préférence par défaut (commentaires minimaux), ce projet
|
||
|
|
doit rester compréhensible par d'autres membres du département IT qui n'ont
|
||
|
|
pas suivi son développement. **Commenter en français, de façon détaillée**,
|
||
|
|
en particulier le "pourquoi" des décisions non évidentes (ex: pourquoi la
|
||
|
|
douchette ne nécessite pas d'intégration, pourquoi les emails sont simulés en
|
||
|
|
l'absence de SMTP_HOST). Ne pas se limiter au commentaire minimal habituel.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
app/
|
||
|
|
main.py point d'entrée FastAPI, montage des routers
|
||
|
|
config.py lecture des variables d'environnement (SMTP...)
|
||
|
|
database.py connexion SQLite + dependency get_session()
|
||
|
|
models.py modèles SQLModel : Categorie, SousCategorie, Materiel, DestinataireAlerte
|
||
|
|
email_alerts.py vérifie le seuil d'alerte et envoie/simule l'email
|
||
|
|
templates_engine.py instance Jinja2Templates partagée par tous les routers
|
||
|
|
routers/ une route FastAPI par ressource (categories, materiels, scan, destinataires)
|
||
|
|
templates/ pages HTML (Jinja2, formulaires HTML classiques)
|
||
|
|
static/ CSS
|
||
|
|
tests/ pytest + TestClient FastAPI + base SQLite en mémoire
|
||
|
|
data/ base SQLite locale, ignorée par git
|
||
|
|
```
|
||
|
|
|
||
|
|
Point d'attention Starlette : `Jinja2Templates.TemplateResponse()` prend
|
||
|
|
`request` en premier argument positionnel (`templates.TemplateResponse(request,
|
||
|
|
"page.html", {...})`), **pas** `{"request": request, ...}` dans le contexte —
|
||
|
|
c'est l'API de la version de Starlette installée ici.
|
||
|
|
|
||
|
|
Un `<form>` ne peut pas entourer plusieurs `<td>` en HTML valide : pour les
|
||
|
|
lignes de tableau éditables (`app/templates/materiels.html`), les champs
|
||
|
|
utilisent l'attribut `form="materiel-{id}"` pour se rattacher à un `<form>`
|
||
|
|
déclaré séparément après le tableau.
|
||
|
|
|
||
|
|
## Emails d'alerte
|
||
|
|
|
||
|
|
Seuil configurable par matériel (`Materiel.seuil_alerte`), liste globale de
|
||
|
|
destinataires (`DestinataireAlerte`, gérée sur `/destinataires`). La logique
|
||
|
|
d'envoi est dans `app/email_alerts.py` : si `SMTP_HOST` n'est pas défini, rien
|
||
|
|
n'est envoyé, l'email est juste affiché dans la console du serveur — pratique
|
||
|
|
pour tester le déclenchement des alertes sans serveur mail réel.
|