diff --git a/docs/plans/2026-03-08-plantes-varietes-design.md b/docs/plans/2026-03-08-plantes-varietes-design.md new file mode 100644 index 0000000..1665c06 --- /dev/null +++ b/docs/plans/2026-03-08-plantes-varietes-design.md @@ -0,0 +1,163 @@ +# Plantes & Variétés — Design + +> **Pour Claude :** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Restructurer la gestion des plantes en séparant niveau espèce (`plant`) et niveau variété (`plant_variety`), importer les données JSON des sachets de graines et arbustes, et ajouter le bouton "Ajouter variété" dans l'UI. + +**Architecture:** Option B — deux tables distinctes (`plant` + `plant_variety`), migration des 21 plantes existantes, import one-shot des 14 graines + 4 arbustes, nouveaux endpoints CRUD variétés. + +**Tech Stack:** FastAPI + SQLModel + SQLite (backend), Vue 3 + Pinia + Tailwind Gruvbox (frontend) + +--- + +## Modèle de données + +### Table `plant` (niveau espèce / nom commun) + +Conserve toutes les colonnes actuelles **sauf** : `variete`, `boutique_nom`, `boutique_url`, `prix_achat`, `date_achat`, `poids`, `dluo`, `tags` + +Nouvelles colonnes ajoutées : +| Champ | Type | Notes | +|---|---|---| +| temp_germination | TEXT | Ex: "8-10°C" | +| temps_levee_j | TEXT | Ex: "15-20 jours" | + +### Table `plant_variety` (niveau variété) + +| Champ | Type | Notes | +|---|---|---| +| id | INTEGER PK | | +| plant_id | INTEGER FK → plant | | +| variete | TEXT | "Nain", "Grimpant", "Stockarda"… | +| tags | TEXT | Tags spécifiques à cette variété | +| notes_variete | TEXT | Observations propres à la variété | +| boutique_nom | TEXT | Enseigne d'achat | +| boutique_url | TEXT | URL fiche produit | +| prix_achat | REAL | En € | +| date_achat | TEXT | ISO date | +| poids | TEXT | Ex: "500 graines", "1g" | +| dluo | TEXT | ISO date limite d'utilisation | +| created_at | TEXT | ISO datetime | + +### Photos sachet de graines +→ Table `media` existante avec `entity_type='plant_variety'` et `entity_id=plant_variety.id` +→ Deux photos par variété max (recto + verso sachet), type `photo_sachet` + +--- + +## API REST + +### Endpoints `plant` modifiés + +``` +GET /api/plants → liste plant + varieties[] (jointure) +GET /api/plants/{id} → détail plant + varieties[] +POST /api/plants → créer une plante (sans variété) +PUT /api/plants/{id} → modifier les champs espèce +DEL /api/plants/{id} → supprimer (cascade varieties) +``` + +### Nouveaux endpoints `plant_variety` + +``` +GET /api/plants/{id}/varieties → liste des variétés d'une plante +POST /api/plants/{id}/varieties → créer une variété +PUT /api/plants/{id}/varieties/{vid} → modifier une variété +DELETE /api/plants/{id}/varieties/{vid} → supprimer une variété +``` + +### Import one-shot + +``` +POST /api/plants/import-graines → importe docs/graine/ + docs/arbustre/ +``` + +--- + +## Migration BDD (script Python one-shot) + +1. Créer table `plant_variety` avec toutes ses colonnes +2. Pour chaque ligne `plant` actuelle → créer une `plant_variety` (copier variete, boutique_*, tags) +3. Recréer `plant` sans les colonnes migrées + ajouter temp_germination + temps_levee_j +4. Fusionner `haricot grimpant` (id=21) sous `Haricot` (id=7) comme variété, supprimer id=21 + +--- + +## Import JSON + +### `docs/graine/caracteristiques_plantation.json` (14 entrées) + +Mapping automatique `nom → plant.nom_commun` : + +| JSON | nom_commun BDD | Action | +|---|---|---| +| Oignon Stockarda | Oignon (nouveau) | créer plant + variety | +| Laitue Attraction | Laitue (id=4) | nouvelle variety | +| Persil frise Moskrul 2 | Persil (id=13) | enrichir plant + nouvelle variety | +| Courgette de Nice | Courgette (id=2) | nouvelle variety | +| Pois à ecosser Merveille | Pois (id=8) | enrichir + nouvelle variety | +| Tomates Moneymaker | Tomate (id=1) | nouvelle variety | +| Poireau Bleu de Solaise | Poireau (id=9) | enrichir variety existante | +| Echalion Zebrune | Échalote (id=14) | nouvelle variety | +| Courge Musquée Sucrine | Courge (nouveau) | créer plant + variety | +| Laitue Grosse Blonde | Laitue (id=4) | nouvelle variety | +| Chou Pomme Brunswick | Chou (id=16) | enrichir + nouvelle variety | +| Chou-fleur Nautilus HF1 | Chou-fleur (id=15) | enrichir variety existante | +| Tomate Cornue Cornabel | Tomate (id=1) | nouvelle variety | +| Pois mangetout Carouby | Pois (id=8) | nouvelle variety | + +Champs JSON → colonnes `plant` : +- `periode_semis` (ex: "III-IV") → `semis_exterieur_mois` (converti en liste mois "3,4") +- `periode_recolte` → `recolte_mois` +- `temperature` → `temp_germination` +- `profondeur` → `profondeur_semis_cm` (extrait la valeur numérique) +- `espacement` → `espacement_cm` (premier chiffre) +- `exposition` → `besoin_soleil` +- texte `arriere` → `astuces_culture` + +Photos `IMG_*.jpg` → copiées dans `/data/uploads/` + entrées `media` (entity_type='plant_variety') + +### `docs/arbustre/caracteristiques_arbustre.json` (4 entrées) + +4 nouvelles plantes de catégorie `arbuste` avec leurs variétés. + +--- + +## Frontend + +### `PlantesView.vue` — modifications + +- **GET /api/plants** retourne `plant + varieties[]` → groupage déjà géré +- **Popup détail** : bouton **"+ Variété"** à gauche du bouton "Modifier" +- **Popup variété** : formulaire pré-rempli depuis `plant` (nom commun) + champs variété-spécifiques : + - Nom de variété (requis) + - Tags, notes variété + - Boutique (nom, URL, prix, date, poids, DLUO) + - Section photos sachet : 2 uploads (recto + verso) +- **Popup nom commun** : affiche `temp_germination` + `temps_levee_j` dans la section culture + +### `frontend/src/api/plants.ts` — modifications + +- Interface `Plant` : supprimer boutique/tags/variete, ajouter `temp_germination`, `temps_levee_j`, `varieties: PlantVariety[]` +- Nouvelle interface `PlantVariety` : tous les champs variété +- Nouveaux appels API : `createVariety`, `updateVariety`, `deleteVariety` + +### `frontend/src/stores/plants.ts` — modifications + +- Actions : `createVariety`, `updateVariety`, `deleteVariety` +- `fetchAll` charge désormais les varieties intégrées + +--- + +## Fichiers à créer / modifier + +| Fichier | Action | +|---|---| +| `backend/app/models/plant.py` | Modifier : supprimer champs migrés, ajouter temp_germination + temps_levee_j + PlantVariety | +| `backend/app/routers/plants.py` | Modifier : GET retourne varieties, + endpoints varieties CRUD | +| `backend/app/migrate.py` | Modifier : ajouter section plant_variety | +| `backend/scripts/migrate_plant_varieties.py` | Créer : script migration one-shot | +| `backend/scripts/import_graines.py` | Créer : script import JSON graines + arbustre | +| `frontend/src/api/plants.ts` | Modifier : Plant + PlantVariety interfaces | +| `frontend/src/stores/plants.ts` | Modifier : actions variety | +| `frontend/src/views/PlantesView.vue` | Modifier : bouton + variété + popup variété + champs nouveaux |