Files
jardin/docs/plans/2026-03-08-intrants-fabrications-design.md
2026-03-08 10:04:14 +01:00

141 lines
5.6 KiB
Markdown

# Intrants & Fabrications — Design
> **Pour Claude :** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Gérer les achats d'intrants (terreau, engrais, traitements) et les fabrications maison (compost, décoctions, purins) dans une vue unique avec deux onglets, liés aux jardins/plantations/tâches existants.
**Architecture:** Option B — deux tables distinctes (`achat_intrant` + `fabrication`), une vue `IntratsView.vue` avec onglets, deux routers FastAPI. Les ingrédients d'une fabrication sont stockés en JSON.
**Tech Stack:** FastAPI + SQLModel + SQLite (backend), Vue 3 + Pinia + Tailwind Gruvbox (frontend)
---
## Modèle de données
### Table `achat_intrant`
| Champ | Type | Notes |
|---|---|---|
| id | INTEGER PK | |
| categorie | TEXT | `terreau` \| `engrais` \| `traitement` \| `autre` |
| nom | TEXT | Nom du produit |
| marque | TEXT | Fabricant / marque |
| boutique_nom | TEXT | Gamm Vert, Lidl, Amazon… |
| boutique_url | TEXT | URL fiche produit |
| prix | REAL | En € |
| poids | TEXT | Ex: "20L", "1kg", "500ml" |
| date_achat | TEXT | ISO date |
| dluo | TEXT | ISO date limite d'utilisation |
| notes | TEXT | Observations libres |
| jardin_id | INTEGER FK → garden | Optionnel |
| plantation_id | INTEGER FK → planting | Optionnel |
| tache_id | INTEGER FK → task | Optionnel |
| created_at | TEXT | ISO datetime |
### Table `fabrication`
| Champ | Type | Notes |
|---|---|---|
| id | INTEGER PK | |
| type | TEXT | `compost` \| `decoction` \| `purin` \| `autre` |
| nom | TEXT | Ex: "Purin d'ortie mai 2026" |
| ingredients | TEXT | JSON : `[{"nom": "ortie", "quantite": "1kg"}, ...]` |
| date_debut | TEXT | ISO date |
| date_fin_prevue | TEXT | ISO date |
| statut | TEXT | `en_cours` \| `pret` \| `utilise` \| `echec` |
| quantite_produite | TEXT | Ex: "8L", "50kg" |
| notes | TEXT | Recette libre, observations |
| jardin_id | INTEGER FK → garden | Optionnel |
| plantation_id | INTEGER FK → planting | Optionnel |
| tache_id | INTEGER FK → task | Optionnel |
| created_at | TEXT | ISO datetime |
---
## API REST
```
GET /api/achats → liste des achats (filtre: categorie, jardin_id)
POST /api/achats → créer un achat
GET /api/achats/{id} → détail
PUT /api/achats/{id} → modifier
DEL /api/achats/{id} → supprimer
GET /api/fabrications → liste (filtre: type, statut, jardin_id)
POST /api/fabrications → créer
GET /api/fabrications/{id} → détail
PUT /api/fabrications/{id} → modifier
DEL /api/fabrications/{id} → supprimer
PATCH /api/fabrications/{id}/statut → changer statut rapidement
```
---
## Frontend
### Nouveau fichier : `frontend/src/views/IntratsView.vue`
**Nouvel item sidebar :** 🧪 Intrants (entre Outils et Réglages)
**Structure :**
```
┌─────────────────────────────────────────────────────┐
│ 🧪 Intrants [🛒 Achats] [🌿 Fabrications] │
│ │
│ Onglet Achats : │
│ • Filtres : Catégorie (terreau/engrais/traitement) │
│ • Grille de cartes : nom, marque, prix, poids, │
│ enseigne, DLUO (rouge si expirée) │
│ • Bouton "+ Ajouter un achat" │
│ • Popup détail + formulaire ajout/édition │
│ │
│ Onglet Fabrications : │
│ • Filtres : Type + Statut │
│ • Cartes : nom, type, statut (badge coloré), │
│ date fin prévue, ingrédients résumés │
│ • Boutons rapides : ✓ Prêt / ✗ Échec │
│ • Popup détail avec liste ingrédients éditable │
└─────────────────────────────────────────────────────┘
```
**Couleurs statut fabrication :**
- `en_cours` → orange
- `pret` → vert
- `utilise` → gris text-muted
- `echec` → rouge
### Nouveaux fichiers API : `frontend/src/api/achats.ts` + `frontend/src/api/fabrications.ts`
### Nouveaux stores Pinia : `frontend/src/stores/achats.ts` + `frontend/src/stores/fabrications.ts`
### Mise à jour `App.vue` : ajouter route `/intrants` dans la sidebar
---
## Migration BDD
Ajouter dans `backend/app/migrate.py` :
- Section `"achat_intrant"` avec toutes ses colonnes
- Section `"fabrication"` avec toutes ses colonnes
Les tables seront créées au démarrage via SQLModel metadata si absentes, puis migrées par `run_migrations()`.
---
## Fichiers à créer / modifier
| Fichier | Action |
|---|---|
| `backend/app/models/intrant.py` | Créer : AchatIntrant + Fabrication SQLModel |
| `backend/app/routers/achats.py` | Créer : CRUD AchatIntrant |
| `backend/app/routers/fabrications.py` | Créer : CRUD Fabrication + PATCH statut |
| `backend/app/main.py` | Modifier : import + include routers |
| `backend/app/migrate.py` | Modifier : ajouter sections achat_intrant + fabrication |
| `frontend/src/api/achats.ts` | Créer |
| `frontend/src/api/fabrications.ts` | Créer |
| `frontend/src/stores/achats.ts` | Créer |
| `frontend/src/stores/fabrications.ts` | Créer |
| `frontend/src/views/IntratsView.vue` | Créer |
| `frontend/src/router/index.ts` | Modifier : route /intrants |
| `frontend/src/App.vue` | Modifier : sidebar item 🧪 Intrants |