IT-Stock/CLAUDE.md
maxsoch 7ce6540924 Refonte des listings et arborescence de catégories à profondeur illimitée
Catégorie/SousCategorie fusionnées en un seul modèle auto-référencé
(parent_id), pour permettre une imbrication sans limite de niveaux. Les
listings matériels/catégories/destinataires passent en lignes repliées
(<details>) avec recherche côté serveur, ce qui corrige le débordement
horizontal du tableau tout-en-input et reste utilisable sur de longues
listes. Style de l'écran de scan également retravaillé (frontend-design).
2026-07-14 19:06:37 +02:00

101 lines
5.1 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 (arborescence de 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.
- **Catégories à profondeur illimitée.** `Categorie` est auto-référencée
(`parent_id`), pas un modèle Catégorie/Sous-catégorie à deux niveaux fixes :
une catégorie peut avoir des sous-catégories qui en ont elles-mêmes, sans
limite (ex: Réseau > Câbles > RJ45 > 2m). Voir `Categorie.chemin()`.
- **Listes potentiellement longues.** Les pages Matériels/Catégories/
Destinataires sont conçues pour rester utilisables avec beaucoup
d'éléments : recherche texte côté serveur (`?q=`), lignes repliées par
défaut (`<details>`), jamais de tableau avec un `<input>` par colonne
affiché sur toutes les lignes à la fois (ça déborde horizontalement).
## 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 (arborescence auto-référencée), Materiel, DestinataireAlerte
categories_arbre.py parcours de l'arborescence (racines, aplatissement pour un <select> indenté)
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.
Les listings (`materiels.html`, `categories.html`) utilisent `<details>`/
`<summary>` pour replier les lignes/branches par défaut plutôt qu'un
tableau tout-en-input : c'est ce qui évite le débordement horizontal et
garde la page utilisable avec beaucoup d'éléments. Le formulaire d'édition
complet d'un matériel ne s'affiche que dans la ligne dépliée (voir
`.formulaire-edition` dans `style.css`), pas sur toutes les lignes en
permanence.
## 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.