diff --git a/amelioration.md b/amelioration.md index ad1913a..2540334 100644 --- a/amelioration.md +++ b/amelioration.md @@ -1,86 +1,85 @@ -- [ ] photo possibilité d'ajouter des photos, upload ( prevoir mecanisme : transformer en webp et redimensionner) +- [x] photo : upload + conversion WebP + thumbnail automatique - couleur predominante : plantes: vert; jardin : marron; arrosage : bleu; outils: jaune -- ajout icones representatives +- [ ] ajout icones representatives dimensionnables jardin : - - [ ] ajouter les caracteristiques pour un jardin: photo, geolocalisation, type de terre, ph, ensoleillement, exposition, dimension,surface, ... - - - -- [ ] dans l'edition du jardin definir si carré potager avec dimension x;y en cm + - [x] ajouter les caracteristiques pour un jardin: photo, geolocalisation, type de terre, ph, ensoleillement, exposition, dimension, surface, ... + - [x] dans l'edition du jardin definir si carré potager avec dimension x;y en cm plante : - - [ ] header : varietés => remplacer par plante ( pareil dans tous le programme) - - [ ] pour une plante, ajouter des caracteristiques : photo, nom, varités, famille, resistance au froid , maladie commune et astuces , methode de semis et de plantation, ... (brainstorming) - - [ ] plante du potager, fleur, arbre ou arbustre - - [ ] brainstorming pour ajouter une liste de plantes courante du jardin: carotte, tomate, ail, oignon, haricot, petis pois, poireaux, pomme de terre, salade, fraise, framboise, persil, echalote,courgette, choux fleur, choux boule, - - [ ] association des plantes et plantes ne devant pas etre planté a proximite + - [x] header : varietés => remplacé par plante (partout dans le programme) + - [x] pour une plante, ajouter des caracteristiques : photo, nom, variétés, famille, résistance au froid, maladie commune et astuces, méthode de semis et de plantation, ... + - [x] plante du potager, fleur, arbre ou arbuste + - [x] liste de plantes courantes seedée : carotte, tomate, ail, oignon, haricot, petits pois, poireaux, pomme de terre, salade, fraise, framboise, persil, échalote, courgette, chou-fleur, chou boule, ... + - [x] association des plantes (favorables / défavorables) : tags noms communs, validation croisée, édition depuis popup plante taches: - - [ ] brainstorming pour preremplir la liste des taches courantes au jardin - - [ ] un tache peut etre unique ou avoir une frequence - - [ ] une tache peut utiliser un outils et s'applique a une platantion ( plantation: plantes dans une zone d'un jardin) + - [x] liste des tâches courantes au jardin pré-remplie (seed) + - [x] une tâche peut être unique ou avoir une fréquence (frequence_jours + date_prochaine) + - [x] une tâche peut utiliser un outil et s'applique à une plantation outils: - - [ ] brainstorming pour ajouter des outils de jardinage - - [ ] liste dans le header - - [ ] créer une 1ere liste d'outils commun du jardin (grelinete, pelle, beche, pioche, sarcloir,....) + - [x] outils de jardinage : CRUD complet, catégories + - [x] liste dans le header (OutilsView) + - [x] 1ère liste d'outils communs seedée (grelinette, pelle, bêche, pioche, sarcloir, ...) planning: - - [ ] brainstorming - + - [x] PlanningView : calendrier 4 semaines, tâches et plantations par jour calendrier: -- [ ] renommer le header lunaire en calendrier ( lunaire, dictons, meteo, taches, ) -- [ ] brainstorming -- [ ] calendrier lunaire avec icones et texte -- [ ] calendrier ajouter dictons courant ( brainstorming region france, auvergne, haute-loire, yssingeaux) -- analyse le dossier calendrier_lunaire + - [x] renommer le header lunaire en calendrier (Météo + Lunaire + Dictons + navigation) + - [x] calendrier lunaire avec icônes et texte (phases + types jours : racine/feuille/fleur/fruit) + - [x] dictons courants (région France, Auvergne, Haute-Loire, Yssingeaux) + - [x] dossier calendrier_lunaire analysé et intégré meteo: - - [ ] brainstorming -- [ ] calendrier bi-hebdo ? avec prevision meteo -- recupere les infos sur ma station meteo locale ( donnéée de la veille une fois par jours et donnée actuelle 1 fois par heure)( brainstorming a partir des script d'essai) -- recupere les infos sur https://open-meteo.com/ une fois par heure pour les prevision ( brainstorming a partir des script d'essai) -- presentation meteo sous forme de tableau journalier synthetique ( passé, present, futur ( avec des colonnes pour station meteo locale et site open-meteo separé)) ( brainstorming -- analyse le dossier prevision meteo et station_meteo -astuces : - - [ ] possibilité d'ajouter des astuces pour les plantes, le jardin, les taches - - [ ] brainstorming + - [x] station météo locale (WeeWX) : données veille 1×/jour + actuelles 1×/heure + - [x] open-meteo.com : prévisions 1×/heure + - [x] tableau journalier synthétique (passé/présent/futur, colonne station + open-meteo) + - [x] dossiers prevision_meteo et station_meteo analysés et intégrés +astuces : + - [x] astuces pour les plantes, le jardin, les tâches : CRUD + filtres catégorie/mois/tag + - [ ] "Astuce du jour" dans le dashboard capteur: -- [ ] recuperation de capteur possible: ensoleillement, temperature ambiante, temperature du sol, humidite de l'air, humidite du sol, ph du sol, -- [ ] configuration via serveur mqtt ( topic et payload) - - [ ] brainstorming - - capteur exterieur et capteur serre + - [ ] récupération de capteurs : ensoleillement, température ambiante/sol, humidité air/sol, pH sol + - [ ] configuration via serveur MQTT (topic et payload) + - [ ] capteur extérieur et capteur serre -reglages : - - [ ] application en mode desktop et pour smartphone ( responsive ?) - - [ ] section pour chaque type: interface, jardin, plante, taches, calendrier, planning - - [ ] backup et restaure (toutes les données: bdd, photo, pdf, txt) - - [ ] ajout de detection de plante a partir de photos ( possibilite d'ajouter un service de detection de type de plantes a partir d'une photo) - - reglage url station meteo local et site distant +reglages : + - [x] application responsive desktop et smartphone + - [x] backup ZIP (DB + uploads) téléchargeable + - [ ] restauration depuis ZIP (upload + restore) + - [ ] sections réglages par type : interface, jardin, plante, tâches, calendrier, planning + - [x] détection de plante depuis photo (Pl@ntNet API + YOLO local) + - [x] réglage URL station météo locale et site distant -recolte: - - [ ] ajouter possibiliter de saisir des quantites recoltés et a quelles dates ( brainstorming) - - [ ] ajouter la possibiliter de suivre des maladies (mildioux ), des traitement, des ravageurs: limaces, taupe, chenille, ... +recolte: + - [x] saisie des quantités récoltées avec dates (unités : kg/g/unités/litres/bottes) + - [x] suivi maladies (mildiou), traitements, ravageurs (limaces, taupe, chenille) via Observations - frontend : - - [ ] icones pour objet dimensionnable ds setting : jardin, plantes, tache, calendrier, meteo, outils - - [ ] icones pour plantes dimensionnable ds setting : tomate, pomme de terre, salade, carotte, ... - - [ ] mode editions pour pouvoir modifier les different element, plantes, jardin, taches, calendrier, ... -- [ ] ajouter des images depuis iphones ( appareil photo) -- [ ] ajouter des pdf ou des annotation, des url dvalable pour tous types d'objet: jardin, plantes,outils, -- verifier que l'application s'affiche correctement sur smartphone -- utilise le dossier icons pour le calendrier lunaire et la meteo ( icone svg adapter taille d'affichage dans setting) +frontend : + - [ ] icônes pour objets dimensionnables dans setting : jardin, plantes, tâche, calendrier, météo, outils + - [ ] icônes pour plantes dimensionnables dans setting : tomate, pomme de terre, salade, carotte, ... + - [x] mode édition pour les différents éléments (plantes, jardin, tâches, calendrier) via modales + - [ ] ajouter des images depuis iPhone (appareil photo natif) + - [x] PDF, annotations, URL pour tous types d'objets : jardin, plantes, outils (Attachments) + - [ ] vérifier affichage correct sur smartphone (à tester) + - [ ] utiliser le dossier icons pour le calendrier lunaire et la météo (icônes SVG adaptatifs dans settings) -bibliotehque photo: -- ajoute une bibliotheque ( plante, legume, fleur, arbres et arbrisseau, adventices) avec un stockage de mes capture et le rsultat d'une identification des plante grace au web ( via api ou via ia : brainstorming) api key: 2b1088cHCJ4c7Cn2Vqq67xfve sur https://my.plantnet.org/dashboard ( https://my.plantnet.org/doc/api/openapi) -- brainstorming local ai detection style yolo ( fichier consigne_yolo.md) +bibliotheque photo: + - [x] bibliothèque (plante, légume, fleur, arbres et arbrisseaux, adventices) + galerie lightbox + - [x] identification via Pl@ntNet API (api key configurée) + - [x] détection locale style YOLO (consigne_yolo.md intégrée) - backend : - - [ ] methode simple pour mettre a jours la base de donnée ; brainstorming +backend : + - [x] migration automatique BDD (migrate.py : ALTER TABLE ADD COLUMN sans perte de données) + - [x] mise à jour BDD via API REST + - [ ] ajouter des étoiles 1 à 5 (satisfaction plante) - - [ ] mise a jours bdd via api puis je peut ajouter des script dans mon openclaw] - - - [ ] ajouter des etoiles 1 à 5 si j'ai été satisfait de la plante \ No newline at end of file +divers : + - [ ] page 404 catch-all (route Vue manquante) + - [ ] export/import JSON complet + - [ ] observations dans PlantationsView (backend prêt, UI manquante) + - [ ] tests backend : couverture ~60% → objectif 80% diff --git a/backend/app/migrate.py b/backend/app/migrate.py index a983d0a..6c85c17 100644 --- a/backend/app/migrate.py +++ b/backend/app/migrate.py @@ -13,6 +13,14 @@ EXPECTED_COLUMNS: dict[str, list[tuple[str, str, str | None]]] = { ("maladies_courantes", "TEXT", None), ("astuces_culture", "TEXT", None), ("url_reference", "TEXT", None), + ("associations_favorables", "TEXT", None), # JSON list[str] + ("associations_defavorables", "TEXT", None), # JSON list[str] + ("boutique_nom", "TEXT", None), + ("boutique_url", "TEXT", None), + ("prix_achat", "REAL", None), + ("date_achat", "TEXT", None), + ("poids", "TEXT", None), + ("dluo", "TEXT", None), ], "garden": [ ("latitude", "REAL", None), diff --git a/backend/app/models/plant.py b/backend/app/models/plant.py index 3ea477c..eccb224 100644 --- a/backend/app/models/plant.py +++ b/backend/app/models/plant.py @@ -1,5 +1,7 @@ from datetime import datetime, timezone -from typing import Optional +from typing import List, Optional +from sqlalchemy import Column +from sqlalchemy import JSON as SA_JSON from sqlmodel import Field, SQLModel @@ -31,6 +33,21 @@ class Plant(SQLModel, table=True): astuces_culture: Optional[str] = None url_reference: Optional[str] = None notes: Optional[str] = None + associations_favorables: Optional[List[str]] = Field( + default=None, + sa_column=Column("associations_favorables", SA_JSON, nullable=True), + ) + associations_defavorables: Optional[List[str]] = Field( + default=None, + sa_column=Column("associations_defavorables", SA_JSON, nullable=True), + ) + # Boutique / approvisionnement (par variété) + boutique_nom: Optional[str] = None # ex: "Gamm Vert", "Lidl", "Amazon" + boutique_url: Optional[str] = None # URL fiche produit + prix_achat: Optional[float] = None + date_achat: Optional[str] = None # ISO date + poids: Optional[str] = None # ex: "5g", "100g", "50 graines" + dluo: Optional[str] = None # date limite utilisation optimale created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) diff --git a/data/jardin.db b/data/jardin.db index 87c511b..a56884c 100755 Binary files a/data/jardin.db and b/data/jardin.db differ diff --git a/data/jardin.db-shm b/data/jardin.db-shm index aeab45e..457ff98 100755 Binary files a/data/jardin.db-shm and b/data/jardin.db-shm differ diff --git a/data/jardin.db-wal b/data/jardin.db-wal index 76e4310..bf8eb17 100755 Binary files a/data/jardin.db-wal and b/data/jardin.db-wal differ diff --git a/docs/arbustre/IMG_4808.jpg b/docs/arbustre/IMG_4808.jpg new file mode 100644 index 0000000..3f7bef8 Binary files /dev/null and b/docs/arbustre/IMG_4808.jpg differ diff --git a/docs/arbustre/IMG_4809.jpg b/docs/arbustre/IMG_4809.jpg new file mode 100644 index 0000000..0629041 Binary files /dev/null and b/docs/arbustre/IMG_4809.jpg differ diff --git a/docs/arbustre/IMG_4810.jpg b/docs/arbustre/IMG_4810.jpg new file mode 100644 index 0000000..ccb5427 Binary files /dev/null and b/docs/arbustre/IMG_4810.jpg differ diff --git a/docs/arbustre/IMG_4811.jpg b/docs/arbustre/IMG_4811.jpg new file mode 100644 index 0000000..6388d8b Binary files /dev/null and b/docs/arbustre/IMG_4811.jpg differ diff --git a/docs/arbustre/IMG_4813.jpg b/docs/arbustre/IMG_4813.jpg new file mode 100644 index 0000000..0392233 Binary files /dev/null and b/docs/arbustre/IMG_4813.jpg differ diff --git a/docs/arbustre/IMG_4814.jpg b/docs/arbustre/IMG_4814.jpg new file mode 100644 index 0000000..52acdf2 Binary files /dev/null and b/docs/arbustre/IMG_4814.jpg differ diff --git a/docs/arbustre/IMG_4815.jpg b/docs/arbustre/IMG_4815.jpg new file mode 100644 index 0000000..f6d770f Binary files /dev/null and b/docs/arbustre/IMG_4815.jpg differ diff --git a/docs/arbustre/IMG_4816.jpg b/docs/arbustre/IMG_4816.jpg new file mode 100644 index 0000000..119356d Binary files /dev/null and b/docs/arbustre/IMG_4816.jpg differ diff --git a/docs/arbustre/caracteristiques_arbustre.json b/docs/arbustre/caracteristiques_arbustre.json new file mode 100644 index 0000000..823bc2d --- /dev/null +++ b/docs/arbustre/caracteristiques_arbustre.json @@ -0,0 +1,219 @@ +{ + "source_dossier": "docs/arbustre", + "regle_groupement": "2 images consecutives = 1 plante", + "plantes": [ + { + "id": 1, + "plante": "Vitis vinifera 'Marechal Foch'", + "nom_latin": "Vitis vinifera", + "images": ["IMG_4808.jpg", "IMG_4809.jpg"], + "texte_extrait": { + "avant": "Vitis vinifera 'Marechal Foch' (code 191599).", + "arriere": "Pictogrammes de culture et informations plant passport/recyclage." + }, + "caracteristiques_plantation": { + "type": "Plant en pot (arbuste fruitier)", + "periode_plantation": null, + "periode_recolte": null, + "exposition": "Soleil / mi-ombre (selon pictogrammes)", + "arrosage": "Regulier (pictogramme arrosoir)", + "espacement": null, + "remarques": "Pictogramme maison (culture proche d'un support/mur, interpretation)." + }, + "icones_significatives": [ + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + }, + { + "icone": "demi-soleil", + "signification": "Exposition", + "valeur": "Mi-ombre" + }, + { + "icone": "arrosoir", + "signification": "Arrosage", + "valeur": "Regulier" + }, + { + "icone": "maison", + "signification": "Emplacement", + "valeur": "Zone abritee/proche habitation (a confirmer)" + }, + { + "icone": "couverts barres", + "signification": "Usage alimentaire", + "valeur": "Interpretation incertaine" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vitis\nvinifera 'Marechal Foch'\n191599", + "arriere": "Pictogrammes visibles: soleil, demi-soleil, maison, arrosoir, couverts barres.\nRaccolta differenziata - Etichetta: Carta - Verifica le disposizioni del tuo Comune.\nPlant Passport (bloc lisible partiellement): A Vitis vinifera; B CZ-...; C 02574/...; D 25.\nGGN: 4063061211323." + } + } + }, + { + "id": 2, + "plante": "Ribes nigrum 'Titania'", + "nom_latin": "Ribes nigrum", + "images": ["IMG_4810.jpg", "IMG_4811.jpg"], + "texte_extrait": { + "avant": "Ribes nigrum 'Titania' (code 58329).", + "arriere": "Pictogrammes: soleil, arrosage, 150 cm, recolte VI-VII." + }, + "caracteristiques_plantation": { + "type": "Plant en pot (arbuste fruitier)", + "periode_plantation": null, + "periode_recolte": "VI-VII", + "exposition": "Soleil", + "arrosage": "Regulier", + "espacement": "150 cm", + "taille_entretien": "Pictogrammes de taille/suppression du bois (interpretation)" + }, + "icones_significatives": [ + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + }, + { + "icone": "arrosoir", + "signification": "Arrosage", + "valeur": "Regulier" + }, + { + "icone": "fleche verticale 150 cm", + "signification": "Espacement/distance", + "valeur": "150 cm" + }, + { + "icone": "main + VI-VII", + "signification": "Periode de recolte", + "valeur": "Juin-Juillet" + }, + { + "icone": "branche/fruits + fleches", + "signification": "Taille/renouvellement", + "valeur": "Interpretation" + }, + { + "icone": "flocon barre + fleches", + "signification": "Gestion hivernale", + "valeur": "Interpretation" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Ribes nigrum\n'Titania'\n58329", + "arriere": "Ribes nigrum\nPictogrammes: soleil; arrosoir; 150 cm; main + VI-VII; deux pictogrammes de taille/entretien.\nPlant Passport: A Ribes nigrum; B NL-...; C 4421PP; D NL.\nCode-barres: 4014157115032." + } + } + }, + { + "id": 3, + "plante": "Rubus idaeus 'Schoenemann'", + "nom_latin": "Rubus idaeus", + "images": ["IMG_4813.jpg", "IMG_4814.jpg"], + "texte_extrait": { + "avant": "Rubus idaeus 'Schoenemann' (code 58329).", + "arriere": "Pictogrammes: soleil, arrosage, 150 cm, recolte VII-XI." + }, + "caracteristiques_plantation": { + "type": "Plant en pot (arbuste fruitier)", + "periode_plantation": null, + "periode_recolte": "VII-XI", + "exposition": "Soleil", + "arrosage": "Regulier", + "espacement": "150 cm", + "taille_entretien": "Pictogrammes de taille/suppression du bois (interpretation)" + }, + "icones_significatives": [ + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + }, + { + "icone": "arrosoir", + "signification": "Arrosage", + "valeur": "Regulier" + }, + { + "icone": "fleche verticale 150 cm", + "signification": "Espacement/distance", + "valeur": "150 cm" + }, + { + "icone": "main + VII-XI", + "signification": "Periode de recolte", + "valeur": "Juillet-Novembre" + }, + { + "icone": "branche/fruits + fleches", + "signification": "Taille/renouvellement", + "valeur": "Interpretation" + }, + { + "icone": "flocon barre + fleches", + "signification": "Gestion hivernale", + "valeur": "Interpretation" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Rubus idaeus\n'Schoenemann'\n58329", + "arriere": "Rubus idaeus\nPictogrammes: soleil; arrosoir; 150 cm; main + VII-XI; deux pictogrammes de taille/entretien.\nPlant Passport: A Rubus idaeus; B NL-...; C 4421PP; D NL.\nCode-barres: 4014157115087." + } + } + }, + { + "id": 4, + "plante": "Framboisier remontant 'Paris'", + "nom_latin": "Rubus idaeus", + "images": ["IMG_4815.jpg", "IMG_4816.jpg"], + "texte_extrait": { + "avant": "F.A.N Fruits Au Naturel - Framboisier remontant 'Paris'. Recolte: juin-juillet puis septembre-octobre.", + "arriere": "Conseils complets de plantation/entretien + recette 'Palets a la confiture de framboises'." + }, + "caracteristiques_plantation": { + "type": "Plant en pot 1,6 litre", + "periode_plantation": "Fevrier a juin et aout a novembre", + "periode_recolte": "Juin-juillet puis septembre-octobre", + "exposition": "Soleil a mi-ombre", + "arrosage": "Arroser a la plantation puis regulier", + "espacement": "0,50 m a 0,70 m entre chaque plant", + "sol": "Tout type de sol sauf humide", + "fertilisation": "Engrais organique a l'automne" + }, + "icones_significatives": [ + { + "icone": "suite etapes 1-5", + "signification": "Methode de plantation", + "valeur": "Ameublir, trou, retirer le pot, planter/tasser, arroser" + }, + { + "icone": "recolte en 2 periodes", + "signification": "Calendrier de production", + "valeur": "Juin-juillet puis septembre-octobre" + }, + { + "icone": "mes reperes usage/gout", + "signification": "Usages culinaires et profil gustatif", + "valeur": "Patisserie, confiture, fruits frais, smoothies" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "F.A.N Fruits Au Naturel\nFramboisier remontant\n'Paris'\nRecolte: juin-juillet puis septembre-octobre\nmes reperes: glaces/sorbets, patisserie/confiture, fruits frais/smoothies\nproduction locale\nPot 1,6 litre", + "arriere": "1 Travaillez le sol pour l'ameublir.\n2 Faites un trou a la taille de la motte.\n3 Retirez le pot.\n4 Plantez et tassez la terre autour de la motte.\n5 Arrosez.\ninfos et conseils: www.vivaplante.fr\n\nFRAMBOISIER REMONTANT 'Paris' (Rubus idaeus)\n\nFramboisier remontant 'Paris'\nSol: tout type de sol sauf humide.\nPlantation: planter toute la motte sous terre. Arroser.\nFertilisation: apporter un engrais organique a l'automne.\nTaille:\n- non remontant (de saison): chaque hiver, enlever les tiges dessechees. Palisser les cannes conservees pour l'annee suivante.\n- remontant: l'hiver, enlever les tiges dessechees et celles trop freles. Ne laisser que 4 ou 5 belles cannes qui produiront en juin. La deuxieme production des septembre aura lieu sur les pousses de l'annee.\n\nPalets a la confiture de framboises\n250 g de farine - 125 g de beurre - 150 g de sucre en poudre - confiture de framboise - 1 oeuf - vanille en poudre\nBattez ensemble le beurre, l'oeuf et 125 g de sucre.\nAjoutez la farine lorsque la preparation mousse, une cuiller a cafe de vanille et une pincee de sel.\nPetrissez la pate et placez-la au refrigerateur pendant 20 minutes.\nFaites des noix de pate que vous roulez dans le reste de sucre. Aplatissez un peu ces noix avant de les poser sur la plaque du four a 210 C pendant 5 minutes.\nFormez un creux au centre de chaque palet a l'aide d'une cuiller a cafe.\nVersez-y la confiture de framboise et placez-les de nouveau au four ou laissez-les dorer.\n\nPlantation: fevrier a juin et aout a nov.\nRecolte: juin-juillet puis septembre-octobre.\nExposition: soleil-mi-ombre.\nEspacement des plants: 0,50 m a 0,70 m entre chaque plant.\n\nPasseport Phytosanitaire / Plant Passport: A Rubus idaeus; B FR-RH00491; C 765883; D FR." + } + } + } + ], + "notes": [ + "Extraction manuelle depuis photos.", + "Certaines lignes de passeport ou pictogrammes sont partiellement lisibles et marquees comme interpretation quand necessaire." + ] +} diff --git a/docs/association.json b/docs/association.json new file mode 100644 index 0000000..ecf8cd1 --- /dev/null +++ b/docs/association.json @@ -0,0 +1,1563 @@ +[ + { + "id": 1, + "nom_commun": "abricotier", + "associations_favorables": [ + "basilic", + "capucine", + "tanaisie" + ], + "associations_defavorables": [ + "fusain d'europe", + "noisetier", + "orme", + "érable" + ] + }, + { + "id": 2, + "nom_commun": "absinthe", + "associations_favorables": [ + "tous les légumes" + ], + "associations_defavorables": [] + }, + { + "id": 3, + "nom_commun": "achillée millefeuille", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 4, + "nom_commun": "ail", + "associations_favorables": [ + "betterave", + "bourrache", + "camomille", + "carotte", + "céleri", + "chou", + "concombre", + "cornichon", + "fraisier", + "haricot", + "laitue", + "pomme de terre", + "radis", + "ronce cultivée", + "rose", + "tomate" + ], + "associations_defavorables": [ + "alliacées (famille)", + "asperge", + "brassicacées (famille)", + "chou", + "fève", + "haricot", + "pois", + "poireau" + ] + }, + { + "id": 5, + "nom_commun": "aneth", + "associations_favorables": [ + "betterave", + "brassicacées (famille)", + "chou", + "concombre", + "laitue", + "oignon" + ], + "associations_defavorables": [ + "carotte", + "fenouil", + "tomate" + ] + }, + { + "id": 6, + "nom_commun": "armoise", + "associations_favorables": [ + "légumes" + ], + "associations_defavorables": [] + }, + { + "id": 7, + "nom_commun": "artichaut", + "associations_favorables": [ + "asperge", + "brassicacées (famille)", + "chou", + "laitue", + "poireau" + ], + "associations_defavorables": [] + }, + { + "id": 8, + "nom_commun": "asperge", + "associations_favorables": [ + "artichaut", + "basilic", + "carotte", + "concombre", + "cornichon", + "persil", + "pois", + "pomme de terre", + "poireau", + "tomate", + "aubergine" + ], + "associations_defavorables": [ + "ail", + "betterave", + "oignon", + "alliacées (famille)" + ] + }, + { + "id": 9, + "nom_commun": "aubergine", + "associations_favorables": [ + "basilic", + "carotte", + "concombre", + "coriandre", + "estragon", + "haricot", + "laitue", + "menthe", + "origan", + "persil", + "piment", + "poivron", + "pois", + "radis", + "tomate", + "thym" + ], + "associations_defavorables": [ + "oignon", + "piment", + "poivron", + "pomme de terre", + "tomate" + ] + }, + { + "id": 10, + "nom_commun": "baguenaudier", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 11, + "nom_commun": "basilic", + "associations_favorables": [ + "asperge", + "aubergine", + "carotte", + "chou", + "courge", + "laitue", + "piment", + "poireau", + "poivron", + "tomate", + "œillet d'inde" + ], + "associations_defavorables": [ + "brassicacées (famille)", + "chou", + "concombre", + "haricot", + "laitue", + "pois", + "rue" + ] + }, + { + "id": 12, + "nom_commun": "betterave", + "associations_favorables": [ + "alliacées (famille)", + "aneth", + "aubergine", + "basilic", + "brassicacées (famille)", + "camomille", + "carotte", + "céleri", + "chou", + "chou-fleur", + "ciboulette", + "concombre", + "courge", + "fraisier", + "haricot", + "laitue", + "maïs", + "menthe", + "oignon", + "origan", + "panais", + "persil", + "pomme de terre", + "pois", + "poireau", + "radis", + "romarin", + "sauge", + "tomate", + "trèfle" + ], + "associations_defavorables": [ + "asperge", + "carotte", + "haricot", + "pomme de terre", + "poireau", + "tomate" + ] + }, + { + "id": 13, + "nom_commun": "bourrache", + "associations_favorables": [ + "courge", + "fraisier", + "haricot", + "tomate" + ], + "associations_defavorables": [] + }, + { + "id": 14, + "nom_commun": "brocoli", + "associations_favorables": [ + "ail", + "aneth", + "aurone", + "betterave", + "camomille", + "capucine", + "céleri", + "ciboulette", + "concombre", + "courge", + "fève", + "haricot", + "laitue", + "maïs", + "menthe", + "moutarde", + "oignon", + "origan", + "pomme de terre", + "radis", + "romarin", + "sauge", + "thym", + "tomate" + ], + "associations_defavorables": [ + "basilic", + "fraisier", + "haricot", + "laitue", + "radis", + "tomate" + ] + }, + { + "id": 15, + "nom_commun": "brassicacées (famille)", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 16, + "nom_commun": "brassicacées (famille, sauf chou-fleur)", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 17, + "nom_commun": "camomille", + "associations_favorables": [ + "ail", + "betterave", + "brassicacées (famille)", + "céleri", + "chou", + "chou-fleur", + "coriandre", + "fève", + "haricot", + "laitue", + "moutarde", + "oignon", + "pomme de terre" + ], + "associations_defavorables": [] + }, + { + "id": 18, + "nom_commun": "camomille allemande", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 19, + "nom_commun": "capucine", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 20, + "nom_commun": "carotte", + "associations_favorables": [ + "ail", + "alliacées (famille)", + "aneth", + "basilic", + "betterave", + "ciboulette", + "concombre", + "coriandre", + "courge", + "courgette", + "céleri", + "échalote", + "épinard", + "fève", + "fraisier", + "haricot", + "laitue", + "marjolaine", + "maïs", + "menthe", + "moutarde", + "oignon", + "panais", + "persil", + "petit pois", + "piment", + "poireau", + "pois", + "poivron", + "radis", + "romarin", + "salade", + "sauge", + "tomate", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "aneth", + "betterave", + "céleri", + "panais", + "échalote" + ] + }, + { + "id": 21, + "nom_commun": "cassissier", + "associations_favorables": [ + "absinthe", + "ciboulette", + "tanaisie" + ], + "associations_defavorables": [ + "haricot à rames", + "maïs" + ] + }, + { + "id": 22, + "nom_commun": "cerfeuil", + "associations_favorables": [ + "chou-fleur", + "laitue", + "radis" + ], + "associations_defavorables": [] + }, + { + "id": 23, + "nom_commun": "ciboulette", + "associations_favorables": [ + "carotte", + "cassissier", + "céleri", + "concombre", + "fraisier", + "laitue", + "pêcher", + "prunier", + "rose", + "tomate", + "tanaisie" + ], + "associations_defavorables": [ + "ail", + "fève", + "haricot", + "pois", + "poireau" + ] + }, + { + "id": 24, + "nom_commun": "citrouille", + "associations_favorables": [ + "capucine", + "fève", + "maïs", + "menthe", + "radis" + ], + "associations_defavorables": [ + "pomme de terre" + ] + }, + { + "id": 25, + "nom_commun": "concombre", + "associations_favorables": [ + "ail", + "aneth", + "aubergine", + "betterave", + "brassicacées (famille)", + "brocoli", + "carotte", + "chou", + "chou vert ou chou kale", + "chou-fleur", + "ciboulette", + "coriandre", + "courge", + "courgette", + "céleri", + "estragon", + "fève", + "haricot", + "haricot nain", + "haricot à rames", + "laitue", + "maïs", + "marjolaine", + "melons", + "menthe", + "moutarde", + "oignon", + "origan", + "petit pois", + "pois", + "poireau", + "pomme de terre", + "radis", + "romarin", + "sauge", + "sarriette", + "tomate", + "tournesol", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "basilic", + "pomme de terre", + "romarin", + "sauge", + "tomate" + ] + }, + { + "id": 26, + "nom_commun": "consoude", + "associations_favorables": [ + "légumes" + ], + "associations_defavorables": [] + }, + { + "id": 27, + "nom_commun": "coriandre", + "associations_favorables": [ + "ail", + "aubergine", + "betterave", + "carotte", + "carvi", + "céleri", + "chou", + "chou-fleur", + "concombre", + "courge", + "laitue", + "oignon", + "persil", + "pomme de terre", + "pois", + "radis", + "tomate" + ], + "associations_defavorables": [ + "fenouil" + ] + }, + { + "id": 28, + "nom_commun": "courge", + "associations_favorables": [ + "ail", + "aneth", + "bourrache", + "capucine", + "carotte", + "céleri", + "cucurbitacées", + "fève", + "haricot", + "haricot à rames", + "laitue", + "maïs", + "melon", + "menthe", + "nepeta", + "oignon", + "origan", + "petit pois", + "pois", + "pomme de terre", + "radis", + "sarriette", + "tomate", + "tournesol", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "pomme de terre" + ] + }, + { + "id": 29, + "nom_commun": "courgette", + "associations_favorables": [ + "ail", + "aneth", + "capucine", + "carotte", + "céleri", + "cucurbitacées", + "fève", + "haricot", + "laitue", + "maïs", + "oignon", + "petit pois", + "pois", + "pomme de terre", + "tomate" + ], + "associations_defavorables": [] + }, + { + "id": 30, + "nom_commun": "cucurbitacées", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 31, + "nom_commun": "céleri", + "associations_favorables": [ + "ail", + "betterave", + "brassicacées (famille)", + "chou", + "chou-fleur", + "concombre", + "cornichon", + "coriandre", + "courge", + "cucurbitacées", + "fève", + "haricot", + "laitue", + "oignon", + "pomme de terre", + "pois", + "poireau", + "tomate" + ], + "associations_defavorables": [ + "carotte", + "laitue", + "panais", + "persil", + "échalote" + ] + }, + { + "id": 32, + "nom_commun": "échalote", + "associations_favorables": [ + "carotte" + ], + "associations_defavorables": [ + "brassicacées (famille)", + "fève", + "haricot", + "légumineuses (fabacées)", + "pois" + ] + }, + { + "id": 33, + "nom_commun": "épinard", + "associations_favorables": [ + "alliacées (famille)", + "aubergine", + "brassicacées (famille)", + "carotte", + "céleri", + "chou", + "fraisier", + "haricot", + "laitue", + "navet", + "oignon", + "petit pois", + "pois", + "poireau", + "rue", + "tomate" + ], + "associations_defavorables": [ + "betterave", + "fenouil", + "laitue", + "pomme de terre", + "tomate" + ] + }, + { + "id": 34, + "nom_commun": "estragon", + "associations_favorables": [ + "absinthe", + "aubergine", + "sarriette", + "thym" + ], + "associations_defavorables": [] + }, + { + "id": 35, + "nom_commun": "fenouil", + "associations_favorables": [ + "asperge", + "céleri", + "cucurbitacées", + "laitue", + "poireau" + ], + "associations_defavorables": [ + "absinthe", + "brocoli", + "chou", + "concombre", + "coriandre", + "courge", + "haricot", + "maïs", + "piment", + "poivron", + "pois", + "tomate", + "œillet d'inde" + ] + }, + { + "id": 36, + "nom_commun": "fougère", + "associations_favorables": [ + "chou" + ], + "associations_defavorables": [] + }, + { + "id": 37, + "nom_commun": "fraisier", + "associations_favorables": [ + "ail", + "bourrache", + "ciboulette", + "épinard", + "haricot", + "laitue", + "myrtillier", + "oignon", + "poireau", + "romarin", + "sauge", + "thym", + "tomate" + ], + "associations_defavorables": [ + "brassicacées (famille)", + "chou", + "petit pois", + "poireau" + ] + }, + { + "id": 38, + "nom_commun": "framboisier", + "associations_favorables": [ + "achillée millefeuille", + "ail", + "lavande", + "prunier", + "rue", + "ronce cultivée", + "souci", + "tanaisie" + ], + "associations_defavorables": [ + "myrtillier", + "ronce cultivée" + ] + }, + { + "id": 39, + "nom_commun": "fève", + "associations_favorables": [ + "ail", + "aneth", + "aubergine", + "betterave", + "bourrache", + "brocoli", + "carotte", + "céleri", + "chou", + "chou de bruxelles", + "chou-fleur", + "citrouille", + "concombre", + "courge", + "épinard", + "fraisier", + "haricot", + "laitue", + "maïs", + "melon", + "navet", + "oignon", + "petit pois", + "pois", + "panais", + "pomme de terre", + "poireau", + "radis", + "romarin", + "rutabaga", + "sauge", + "tomate", + "tournesol", + "œillet d'inde" + ], + "associations_defavorables": [ + "alliacées (famille)", + "ail", + "brocoli", + "ciboulette", + "fenouil", + "haricot", + "oignon", + "piment", + "poireau", + "poivron", + "pomme de terre", + "tomate" + ] + }, + { + "id": 40, + "nom_commun": "géranium vivace blanc", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 41, + "nom_commun": "genévrier", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 42, + "nom_commun": "groseilliers à grappes et à maquereaux", + "associations_favorables": [ + "absinthe", + "ciboulette", + "tanaisie", + "tomate" + ], + "associations_defavorables": [ + "haricot à rames", + "maïs", + "trèfle" + ] + }, + { + "id": 43, + "nom_commun": "haricot", + "associations_favorables": [ + "ail", + "aneth", + "aubergine", + "betterave", + "bourrache", + "brocoli", + "carotte", + "céleri", + "chou", + "chou de bruxelles", + "chou-fleur", + "citrouille", + "concombre", + "courge", + "courgette", + "épinard", + "fraisier", + "fève", + "laitue", + "maïs", + "melon", + "moutarde", + "navet", + "oignon", + "origan", + "panais", + "petit pois", + "pois", + "pomme de terre", + "poireau", + "radis", + "romarin", + "rutabaga", + "sarriette", + "sauge", + "tomate", + "tournesol", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "ail", + "alliacées (famille)", + "betterave", + "brassicacées (famille)", + "ciboulette", + "fenouil", + "oignon", + "persil", + "piment", + "poireau", + "pois", + "poivron", + "tomate", + "échalote" + ] + }, + { + "id": 44, + "nom_commun": "haricot nain", + "associations_favorables": [ + "betterave", + "capucine", + "concombre", + "céleri", + "fraisier", + "maïs", + "petit pois", + "pois", + "sarriette" + ], + "associations_defavorables": [ + "alliacées (famille)" + ] + }, + { + "id": 45, + "nom_commun": "haricot à rames", + "associations_favorables": [ + "ail", + "camomille", + "capucine", + "carotte", + "concombre", + "courge", + "céleri", + "épinard", + "maïs", + "origan", + "petit pois", + "pois", + "pomme de terre", + "radis", + "romarin", + "sarriette", + "tomate", + "œillet d'inde" + ], + "associations_defavorables": [ + "alliacées (famille)", + "betterave", + "brassicacées (famille)", + "fenouil" + ] + }, + { + "id": 46, + "nom_commun": "hysope", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 47, + "nom_commun": "kiwi", + "associations_favorables": [ + "pomme de terre" + ], + "associations_defavorables": [ + "haricot", + "maïs", + "mâche", + "navet", + "oignon" + ] + }, + { + "id": 48, + "nom_commun": "laitue", + "associations_favorables": [ + "ail", + "aneth", + "asperge", + "aubergine", + "betterave", + "brassicacées (famille)", + "brocoli", + "carotte", + "cerfeuil", + "chou", + "chou vert ou chou kale", + "chou-fleur", + "concombre", + "courge", + "courgette", + "céleri", + "fraisier", + "fève", + "haricot", + "maïs", + "melon", + "navet", + "oignon", + "petit pois", + "pois", + "pomme de terre", + "poireau", + "radis", + "salade", + "tomate", + "trèfle" + ], + "associations_defavorables": [ + "brassicacées (famille, sauf chou-fleur et chou kale)", + "brocoli", + "artichaut", + "céleri", + "épinard", + "maïs", + "persil", + "tournesol" + ] + }, + { + "id": 49, + "nom_commun": "lavande", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 50, + "nom_commun": "laurier noble", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 51, + "nom_commun": "lin à grandes fleurs", + "associations_favorables": [ + "pomme de terre" + ], + "associations_defavorables": [] + }, + { + "id": 52, + "nom_commun": "luzerne", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 53, + "nom_commun": "marjolaine", + "associations_favorables": [ + "piment", + "poivron" + ], + "associations_defavorables": [ + "concombre" + ] + }, + { + "id": 54, + "nom_commun": "maïs", + "associations_favorables": [ + "asperge", + "betterave", + "bourrache", + "carotte", + "concombre", + "courge", + "courgette", + "cucurbitacées", + "fève", + "haricot", + "haricot nain", + "haricot à rames", + "légumineuses (fabacées)", + "melon", + "menthe", + "mâche", + "oignon", + "petit pois", + "pois", + "pomme de terre", + "potiron", + "radis", + "tomate", + "tournesol", + "topinambour", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "betterave", + "brassicacées (famille)", + "céleri", + "laitue", + "menthe", + "romarin", + "tomate" + ] + }, + { + "id": 55, + "nom_commun": "melons", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 56, + "nom_commun": "melon", + "associations_favorables": [ + "courge", + "fraisier", + "maïs", + "marjolaine", + "petit pois", + "radis", + "tomate", + "tournesol" + ], + "associations_defavorables": [ + "concombre", + "pomme de terre", + "romarin", + "sauge", + "thym" + ] + }, + { + "id": 57, + "nom_commun": "menthe", + "associations_favorables": [ + "brassicacées (famille)", + "chou", + "courge", + "petit pois", + "pois", + "radis", + "tomate" + ], + "associations_defavorables": [ + "carotte", + "concombre", + "maïs" + ] + }, + { + "id": 58, + "nom_commun": "moutarde", + "associations_favorables": [ + "achillée millefeuille", + "ail", + "armoise", + "artichaut", + "aurone", + "betterave", + "camomille", + "capucine", + "chou-rave", + "radis", + "sauge", + "thym", + "œillet d'inde" + ], + "associations_defavorables": [ + "basilic", + "petit pois", + "tomate" + ] + }, + { + "id": 59, + "nom_commun": "mâche", + "associations_favorables": [ + "maïs", + "poireau" + ], + "associations_defavorables": [ + "oignon", + "poireau" + ] + }, + { + "id": 60, + "nom_commun": "myrtillier", + "associations_favorables": [ + "fraisier" + ], + "associations_defavorables": [ + "framboisier" + ] + }, + { + "id": 61, + "nom_commun": "nepeta", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 62, + "nom_commun": "navet", + "associations_favorables": [ + "ail", + "aneth", + "armoise", + "artichaut", + "aurone", + "betterave", + "ciboulette", + "fève", + "haricot", + "laitue", + "menthe", + "oignon", + "petit pois", + "pois", + "romarin", + "sauge", + "thym", + "épinard", + "œillet d'inde" + ], + "associations_defavorables": [ + "ail", + "haricot", + "pomme de terre", + "rutabaga" + ] + }, + { + "id": 63, + "nom_commun": "nerprun alaterne", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 64, + "nom_commun": "noisetier", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 65, + "nom_commun": "noyer", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 66, + "nom_commun": "oignon", + "associations_favorables": [ + "ail", + "aneth", + "asperge", + "aubergine", + "betterave", + "brassicacées (famille)", + "brocoli", + "carotte", + "citrouille", + "concombre", + "courge", + "courgette", + "céleri", + "épinard", + "fraisier", + "fève", + "haricot", + "laitue", + "moutarde", + "panais", + "patate douce", + "persil", + "piment", + "poireau", + "pois", + "poivron", + "pomme de terre", + "radis", + "ronce cultivée", + "rose", + "sarriette", + "tomate", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "ail", + "brassicacées (famille)", + "fève", + "haricot", + "légumineuses (fabacées)", + "petit pois", + "pois", + "poireau", + "sauge", + "tomate", + "échalote" + ] + }, + { + "id": 67, + "nom_commun": "origan", + "associations_favorables": [ + "aneth", + "brocoli", + "carotte", + "chou", + "concombre", + "courge", + "haricot", + "haricot à rames", + "piment", + "poivron", + "pomme de terre", + "radis", + "romarin", + "sauge", + "thym", + "vigne" + ], + "associations_defavorables": [ + "piment" + ] + }, + { + "id": 68, + "nom_commun": "panais", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 69, + "nom_commun": "patate douce", + "associations_favorables": [ + "haricot", + "maïs" + ], + "associations_defavorables": [ + "piment", + "poivron" + ] + }, + { + "id": 70, + "nom_commun": "persil", + "associations_favorables": [ + "asperge", + "carotte", + "coriandre", + "maïs", + "piment", + "poivron", + "radis", + "romarin", + "rose", + "tomate" + ], + "associations_defavorables": [ + "céleri", + "haricot", + "laitue", + "panais", + "poireau", + "pois" + ] + }, + { + "id": 71, + "nom_commun": "piment", + "associations_favorables": [ + "aubergine", + "basilic", + "carotte", + "ciboulette", + "courge", + "laitue", + "marjolaine", + "oignon", + "origan", + "patate douce", + "persil", + "poireau", + "poivron", + "tomate", + "thym", + "œillet d'inde" + ], + "associations_defavorables": [ + "aubergine", + "brassicacées (famille)", + "ciboulette", + "fève", + "haricot", + "oignon", + "pomme de terre", + "poireau", + "pois", + "poivron", + "tomate" + ] + }, + { + "id": 72, + "nom_commun": "poireau", + "associations_favorables": [ + "asperge", + "carotte", + "céleri", + "épinard", + "fraisier", + "mâche", + "oignon", + "pomme de terre", + "tomate", + "trèfle" + ], + "associations_defavorables": [ + "ail", + "brassicacées (famille)", + "fève", + "haricot", + "légumineuses (fabacées)", + "persil", + "pois", + "sauge" + ] + }, + { + "id": 73, + "nom_commun": "poiree", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 74, + "nom_commun": "pois", + "associations_favorables": [ + "asperge", + "aubergine", + "betterave", + "carotte", + "céleri", + "chou", + "concombre", + "courge", + "courgette", + "cucurbitacées", + "fève", + "haricot", + "haricot nain", + "haricot à rames", + "laitue", + "maïs", + "melon", + "menthe", + "moutarde", + "pomme de terre", + "radis", + "romarin", + "sauge", + "tomate", + "tournesol", + "œillet d'inde" + ], + "associations_defavorables": [ + "ail", + "alliacées (famille)", + "chou", + "haricot", + "oignon", + "pomme de terre", + "poireau" + ] + }, + { + "id": 75, + "nom_commun": "poivron", + "associations_favorables": [ + "ail", + "aubergine", + "basilic", + "carotte", + "laitue", + "marjolaine", + "oignon", + "persil", + "tomate", + "thym" + ], + "associations_defavorables": [ + "fève", + "fenouil", + "haricot", + "piment", + "pomme de terre", + "poireau", + "pois", + "tomate" + ] + }, + { + "id": 76, + "nom_commun": "pomme de terre", + "associations_favorables": [ + "ail", + "asperge", + "brocoli", + "brassicacées (famille)", + "capucine", + "carotte", + "céleri", + "citrouille", + "courge", + "courgette", + "fraisier", + "fève", + "haricot", + "laitue", + "maïs", + "petit pois", + "pois", + "poireau", + "potiron", + "radis", + "raifort", + "tomate", + "tournesol", + "trèfle", + "œillet d'inde" + ], + "associations_defavorables": [ + "aubergine", + "betterave", + "concombre", + "courge", + "citrouille", + "maïs", + "navet", + "pomme", + "tomate" + ] + }, + { + "id": 77, + "nom_commun": "pommier", + "associations_favorables": [ + "achillée millefeuille", + "basilic", + "camomille allemande", + "capucine", + "nerprun alaterne", + "phacélie", + "potentille", + "ronce cultivée", + "tagète", + "trèfle" + ], + "associations_defavorables": [ + "baguenaudier" + ] + }, + { + "id": 78, + "nom_commun": "potiron", + "associations_favorables": [], + "associations_defavorables": [] + }, + { + "id": 79, + "nom_commun": "prunier", + "associations_favorables": [ + "framboisier", + "pêcher", + "poiriers", + "ronce cultivée", + "vigne" + ], + "associations_defavorables": [ + "fusain d'europe", + "noisetier", + "orme", + "érable" + ] + } +] diff --git a/docs/graine/IMG_4780.jpg b/docs/graine/IMG_4780.jpg new file mode 100644 index 0000000..ef0c30b Binary files /dev/null and b/docs/graine/IMG_4780.jpg differ diff --git a/docs/graine/IMG_4781.jpg b/docs/graine/IMG_4781.jpg new file mode 100644 index 0000000..d7c64e8 Binary files /dev/null and b/docs/graine/IMG_4781.jpg differ diff --git a/docs/graine/IMG_4782.jpg b/docs/graine/IMG_4782.jpg new file mode 100644 index 0000000..d550466 Binary files /dev/null and b/docs/graine/IMG_4782.jpg differ diff --git a/docs/graine/IMG_4783.jpg b/docs/graine/IMG_4783.jpg new file mode 100644 index 0000000..dc24e21 Binary files /dev/null and b/docs/graine/IMG_4783.jpg differ diff --git a/docs/graine/IMG_4784.jpg b/docs/graine/IMG_4784.jpg new file mode 100644 index 0000000..02fcb5c Binary files /dev/null and b/docs/graine/IMG_4784.jpg differ diff --git a/docs/graine/IMG_4785.jpg b/docs/graine/IMG_4785.jpg new file mode 100644 index 0000000..f2d276d Binary files /dev/null and b/docs/graine/IMG_4785.jpg differ diff --git a/docs/graine/IMG_4786.jpg b/docs/graine/IMG_4786.jpg new file mode 100644 index 0000000..d832148 Binary files /dev/null and b/docs/graine/IMG_4786.jpg differ diff --git a/docs/graine/IMG_4787.jpg b/docs/graine/IMG_4787.jpg new file mode 100644 index 0000000..868b08b Binary files /dev/null and b/docs/graine/IMG_4787.jpg differ diff --git a/docs/graine/IMG_4788.jpg b/docs/graine/IMG_4788.jpg new file mode 100644 index 0000000..297fc5b Binary files /dev/null and b/docs/graine/IMG_4788.jpg differ diff --git a/docs/graine/IMG_4789.jpg b/docs/graine/IMG_4789.jpg new file mode 100644 index 0000000..25656b9 Binary files /dev/null and b/docs/graine/IMG_4789.jpg differ diff --git a/docs/graine/IMG_4790.jpg b/docs/graine/IMG_4790.jpg new file mode 100644 index 0000000..effddab Binary files /dev/null and b/docs/graine/IMG_4790.jpg differ diff --git a/docs/graine/IMG_4791.jpg b/docs/graine/IMG_4791.jpg new file mode 100644 index 0000000..fff1422 Binary files /dev/null and b/docs/graine/IMG_4791.jpg differ diff --git a/docs/graine/IMG_4792.jpg b/docs/graine/IMG_4792.jpg new file mode 100644 index 0000000..c8749a5 Binary files /dev/null and b/docs/graine/IMG_4792.jpg differ diff --git a/docs/graine/IMG_4793.jpg b/docs/graine/IMG_4793.jpg new file mode 100644 index 0000000..31d5467 Binary files /dev/null and b/docs/graine/IMG_4793.jpg differ diff --git a/docs/graine/IMG_4794.jpg b/docs/graine/IMG_4794.jpg new file mode 100644 index 0000000..0d7c7a9 Binary files /dev/null and b/docs/graine/IMG_4794.jpg differ diff --git a/docs/graine/IMG_4795.jpg b/docs/graine/IMG_4795.jpg new file mode 100644 index 0000000..462bb61 Binary files /dev/null and b/docs/graine/IMG_4795.jpg differ diff --git a/docs/graine/IMG_4796.jpg b/docs/graine/IMG_4796.jpg new file mode 100644 index 0000000..4715d2f Binary files /dev/null and b/docs/graine/IMG_4796.jpg differ diff --git a/docs/graine/IMG_4797.jpg b/docs/graine/IMG_4797.jpg new file mode 100644 index 0000000..9ace76e Binary files /dev/null and b/docs/graine/IMG_4797.jpg differ diff --git a/docs/graine/IMG_4798.jpg b/docs/graine/IMG_4798.jpg new file mode 100644 index 0000000..55a7c31 Binary files /dev/null and b/docs/graine/IMG_4798.jpg differ diff --git a/docs/graine/IMG_4799.jpg b/docs/graine/IMG_4799.jpg new file mode 100644 index 0000000..a07ad35 Binary files /dev/null and b/docs/graine/IMG_4799.jpg differ diff --git a/docs/graine/IMG_4800.jpg b/docs/graine/IMG_4800.jpg new file mode 100644 index 0000000..0284a0e Binary files /dev/null and b/docs/graine/IMG_4800.jpg differ diff --git a/docs/graine/IMG_4801.jpg b/docs/graine/IMG_4801.jpg new file mode 100644 index 0000000..3e1bad0 Binary files /dev/null and b/docs/graine/IMG_4801.jpg differ diff --git a/docs/graine/IMG_4802.jpg b/docs/graine/IMG_4802.jpg new file mode 100644 index 0000000..d1bd323 Binary files /dev/null and b/docs/graine/IMG_4802.jpg differ diff --git a/docs/graine/IMG_4803.jpg b/docs/graine/IMG_4803.jpg new file mode 100644 index 0000000..667d403 Binary files /dev/null and b/docs/graine/IMG_4803.jpg differ diff --git a/docs/graine/IMG_4804.jpg b/docs/graine/IMG_4804.jpg new file mode 100644 index 0000000..b54f821 Binary files /dev/null and b/docs/graine/IMG_4804.jpg differ diff --git a/docs/graine/IMG_4805.jpg b/docs/graine/IMG_4805.jpg new file mode 100644 index 0000000..fe10ab7 Binary files /dev/null and b/docs/graine/IMG_4805.jpg differ diff --git a/docs/graine/IMG_4806.jpg b/docs/graine/IMG_4806.jpg new file mode 100644 index 0000000..d8fa650 Binary files /dev/null and b/docs/graine/IMG_4806.jpg differ diff --git a/docs/graine/IMG_4807.jpg b/docs/graine/IMG_4807.jpg new file mode 100644 index 0000000..6a4263d Binary files /dev/null and b/docs/graine/IMG_4807.jpg differ diff --git a/docs/graine/caracteristiques_plantation.json b/docs/graine/caracteristiques_plantation.json new file mode 100644 index 0000000..f107325 --- /dev/null +++ b/docs/graine/caracteristiques_plantation.json @@ -0,0 +1,783 @@ +{ + "source_dossier": "docs/graine", + "regle_groupement": "2 images consecutives = 1 plante", + "plantes": [ + { + "id": 1, + "plante": "Oignon Stockarda", + "nom_latin": "Allium cepa", + "images": [ + "IMG_4780.jpg", + "IMG_4781.jpg" + ], + "texte_extrait": { + "avant": "Oignon comestible epice a conserver ou a consommer frais.", + "arriere": "Semis de debut mars a avril, en pleine terre. Germination 15 a 20 jours." + }, + "caracteristiques_plantation": { + "semis": "Exterieur", + "periode_semis": "III-IV", + "temperature": "8-10 C", + "profondeur": "1 cm", + "espacement": "5 x 25 cm", + "exposition": "Ensoleille", + "periode_recolte": "VII-IX" + }, + "icones_significatives": [ + { + "icone": "thermometre", + "signification": "Temperature de semis", + "valeur": "8-10 C" + }, + { + "icone": "graines/ligne", + "signification": "Semis exterieur", + "valeur": "III-IV" + }, + { + "icone": "profondeur", + "signification": "Profondeur de semis", + "valeur": "1 cm" + }, + { + "icone": "espacement", + "signification": "Distance de plantation", + "valeur": "5 x 25 cm" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Ensoleille" + }, + { + "icone": "panier", + "signification": "Periode de recolte", + "valeur": "VII-IX" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "OIGNON COMESTIBLE EPICE A CONSERVER OU A CONSOMMER FRAIS\nOIGNON STOCKARDA\nALLIUM CEPA\n2 GP\nPour la culture de printemps et d'automne\nConvient pour la culture en pleine terre\n8880830", + "arriere": "Oignon Stockarda\nUtilisation: Variete mi-precoce, tres polyvalente, utilisable comme oignon de conservation et comme ciboule. Oignons ronds legerement aplatis, de couleur jaune, a la peau ferme, au poids de sortie eleve et a la duree de conservation tres longue. Crus, les oignons conviennent pour assaisonner les salades, cuits ils accompagnent de nombreux plats.\nCulture et soin: Germination 15 a 20 jours. Le semis se fait de debut mars a avril, en pleine terre. Semer a 1 cm de profondeur, tasser, recouvrir de terre et maintenir humide.\nConseil: Les oignons preferent un sol ameubli et riche en substances nutritives. Veiller a une humidite reguliere pendant toute la croissance.\nPictogrammes: 8-10 C; 1 cm; Semis en exterieur III-IV; Distance 5 x 25 cm; Exposition Ensoleille; Recolte VII-IX.\nLe contenu suffit pour environ 7 metres. 1 g." + } + } + }, + { + "id": 2, + "plante": "Laitue Attraction (ruban de graines)", + "nom_latin": "Lactuca sativa", + "images": [ + "IMG_4782.jpg", + "IMG_4783.jpg" + ], + "texte_extrait": { + "avant": "Laitue pommee tendre. Ruban de graines.", + "arriere": "Germination 7 a 12 jours. Semis en exterieur en ruban." + }, + "caracteristiques_plantation": { + "semis": "Exterieur (ruban)", + "periode_semis": "III-VI", + "temperature": "10-20 C", + "profondeur": "0,5 cm", + "espacement": "15 cm", + "exposition": "Ensoleille / semi-ombrage", + "periode_recolte": "VI-IX" + }, + "icones_significatives": [ + { + "icone": "ruban", + "signification": "Type de semis", + "valeur": "Ruban de graines" + }, + { + "icone": "thermometre", + "signification": "Temperature", + "valeur": "10-20 C" + }, + { + "icone": "graines/ligne", + "signification": "Semis exterieur", + "valeur": "III-VI" + }, + { + "icone": "espacement", + "signification": "Distance", + "valeur": "15 cm" + }, + { + "icone": "soleil-nuage", + "signification": "Exposition", + "valeur": "Ensoleille/Semi-ombrage" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "VI-IX" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "LAITUE POMMEE TENDRE\nRUBAN DE GRAINES LAITUE ATTRAKTION\nLACTUCA SATIVA\n4 PG\nPour la culture de printemps\nRuban de graines\n8882915", + "arriere": "Ruban de graines Laitue Attraktion\nUtilisation: La variete eprouvee Attraction est une laitue pommee mi-precoce avec des tetes fermes vert clair dont le coeur est d'une qualite exceptionnelle, tendre et avec peu de feuilles exterieures.\nCulture et soin: Germination 7 a 12 jours. Preferer un sol de jardin riche en humus, meuble et profond, a un endroit ensoleille a semi-ombrage. Placer le ruban de graines dans un sillon d'env. 0,5 cm de profondeur, humidifier, recouvrir d'une fine couche de terre, tasser et arroser a nouveau abondamment.\nConseil: Le sol doit etre desherbe et ameubli. Les graines sont placees dans le ruban a la distance optimale de plantation.\nPictogrammes: 10-20 C; 0,5 cm; Semis en exterieur III-VI; Distance 15 cm; Exposition Ensoleille/Semi-ombrage; Recolte VI-IX.\nLe contenu suffit pour environ 5 metres." + } + } + }, + { + "id": 3, + "plante": "Persil frise Moskrul 2", + "nom_latin": "Petroselinum crispum", + "images": [ + "IMG_4784.jpg", + "IMG_4785.jpg" + ], + "texte_extrait": { + "avant": "Feuilles finement frisees, aromatiques. Plante resistante a l'hiver.", + "arriere": "Germination 15 a 35 jours. Semis de mars a aout." + }, + "caracteristiques_plantation": { + "semis": "Exterieur", + "periode_semis": "III-VIII", + "temperature": "15-20 C", + "profondeur": "1 cm", + "espacement": "8 x 25 cm", + "exposition": "Ensoleille (possible mi-ombre selon texte)", + "periode_recolte": "V-IX" + }, + "icones_significatives": [ + { + "icone": "flocon", + "signification": "Resistance", + "valeur": "Resistant a l'hiver" + }, + { + "icone": "feuille", + "signification": "Usage", + "valeur": "Herbe aromatique" + }, + { + "icone": "thermometre", + "signification": "Temperature", + "valeur": "15-20 C" + }, + { + "icone": "graines/ligne", + "signification": "Semis exterieur", + "valeur": "III-VIII" + }, + { + "icone": "espacement", + "signification": "Distance", + "valeur": "8 x 25 cm" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "V-IX" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "FEUILLES FINEMENT FRISEES, AROMATIQUES\nPERSIL, FRISE MOSKRUL 2\nPETROSELINUM CRISPUM\n1 GP\nplante resistante a l'hiver\nherbe aromatique\n8881010", + "arriere": "Persil, frise Moskrul 2\nUtilisation: Bisannuelle. Les feuilles finement frisees et d'un vert intense possedent un arome subtil et epice. Le persil est particulierement apprecie en cuisine pour assaisonner les soupes, les sauces et les salades.\nCulture et soin: Germination 15 a 35 jours. Le semis se fait des que le sol est a l'abri du gel. Semer a 1 cm de profondeur, recouvrir d'une fine couche de terre, tasser les graines et maintenir une humidite constante.\nConseil: Le persil aime les endroits humides, semi-ombrages, riches en humus et nutritifs.\nPictogrammes: 15-20 C; 1 cm; Semis en exterieur III-VIII; Distance 8 x 25 cm; Exposition Ensoleille; Recolte V-IX.\nLe contenu suffit pour environ 1,2-1,8 metres. 3,5 g." + } + } + }, + { + "id": 4, + "plante": "Courgette de Nice a fruit rond", + "nom_latin": "Cucurbita pepo", + "images": [ + "IMG_4786.jpg", + "IMG_4787.jpg" + ], + "texte_extrait": { + "avant": "Fruits spheriques a la chair tendre.", + "arriere": "Semis en pre-culture en pot. Germination 6 a 10 jours." + }, + "caracteristiques_plantation": { + "semis": "Pre-culture en pot", + "periode_semis": "III-V", + "temperature": "15-20 C", + "profondeur": "2-3 cm", + "espacement": "60 x 60 cm", + "exposition": "Ensoleille", + "periode_recolte": "VII-VIII" + }, + "icones_significatives": [ + { + "icone": "pot", + "signification": "Mode de semis", + "valeur": "Pre-culture en pot" + }, + { + "icone": "thermometre", + "signification": "Temperature", + "valeur": "15-20 C" + }, + { + "icone": "profondeur", + "signification": "Profondeur", + "valeur": "2-3 cm" + }, + { + "icone": "espacement", + "signification": "Distance", + "valeur": "60 x 60 cm" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Ensoleille" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "VII-VIII" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "FRUITS SPHERIQUES A LA CHAIR TENDRE\nCOURGETTE DE NICE A FRUIT ROND\nCUCURBITA PEPO L.\n3 GP\nPour la culture de printemps et d'ete\nConvient pour la culture en pleine terre\n8880360", + "arriere": "Courgette De Nice a fruit rond\nUtilisation: Les varietes De Nice a fruit rond sont des courgettes rondes. La chair est de couleur creme et les jeunes fruits sont utilises comme legumes, farcis, sautes ou a l'etouffee.\nCulture et soin: Germination 6 a 10 jours. A partir de la mi-mai, les jeunes plants vigoureux peuvent etre repiques en respectant un espacement d'environ 60 x 60 cm.\nConseil: Pour la consommation, les jeunes fruits sont recoltes lorsqu'ils atteignent environ 10 cm de diametre.\nPictogrammes: 15-20 C; 2-3 cm; Semis pre-culture en pot III-V; Distance 60 x 60 cm; Exposition Ensoleille; Recolte VII-VIII.\nLe contenu suffit pour environ 7-8 plantes. 3 g." + } + } + }, + { + "id": 5, + "plante": "Pois a ecosser Merveille de Kelvedon", + "nom_latin": "Pisum sativum", + "images": [ + "IMG_4788.jpg", + "IMG_4789.jpg" + ], + "texte_extrait": { + "avant": "Variete a haut rendement.", + "arriere": "Germination 8 a 14 jours." + }, + "caracteristiques_plantation": { + "semis": "Exterieur", + "periode_semis": "II-V", + "temperature": "10-15 C", + "profondeur": "3-5 cm (lecture icone, a confirmer)", + "espacement": "5 x 40 cm", + "exposition": "Ensoleille", + "periode_recolte": "VI-VIII" + }, + "icones_significatives": [ + { + "icone": "thermometre", + "signification": "Temperature", + "valeur": "10-15 C" + }, + { + "icone": "graines/ligne", + "signification": "Semis exterieur", + "valeur": "II-V" + }, + { + "icone": "espacement", + "signification": "Distance", + "valeur": "5 x 40 cm" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Ensoleille" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "VI-VIII" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "VARIETE A HAUT RENDEMENT\nPOIS A ECOSSER MERVEILLE DE KELVEDON\nPISUM SATIVUM\n3 GP\nPour la culture de printemps et d'ete\nConvient pour la culture en exterieur", + "arriere": "Pois a ecosser Merveille de Kelvedon\nUtilisation: La variete Kelvedon Wonder est une variete precoce et productive de moelleux, au gout intense.\nCulture et soin: Germination 8 a 14 jours. Les pois sont des graines qui germent dans l'obscurite. Recouvrir completement les graines de terre et les maintenir constamment humides.\nConseil: Eviter l'eau stagnante et les bases temperates. Proteger le semis de pois contre les oiseaux voraces.\nPictogrammes: 10-15 C; profondeur env. 3-5 cm; Semis en exterieur II-V; Distance 5 x 40 cm; Exposition Ensoleille; Recolte VI-VIII.\nLe contenu suffit pour environ 50 plantes. 25 g." + } + } + }, + { + "id": 6, + "plante": "Tomates Moneymaker", + "nom_latin": "Solanum lycopersicum", + "images": [ + "IMG_4790.jpg", + "IMG_4791.jpg" + ], + "texte_extrait": { + "avant": "Tomate a tuteurer, fruits aromatiques.", + "arriere": "Semis en pre-culture en pot. Germination 12 a 18 jours." + }, + "caracteristiques_plantation": { + "semis": "Pre-culture en pot", + "periode_semis": "III-IV", + "temperature": "20-25 C", + "profondeur": "1 cm", + "espacement": "60 x 60 cm", + "exposition": "Ensoleille", + "periode_recolte": "VII-X" + }, + "icones_significatives": [ + { + "icone": "pot", + "signification": "Mode de semis", + "valeur": "Pre-culture en pot" + }, + { + "icone": "thermometre", + "signification": "Temperature", + "valeur": "20-25 C" + }, + { + "icone": "profondeur", + "signification": "Profondeur", + "valeur": "1 cm" + }, + { + "icone": "espacement", + "signification": "Distance", + "valeur": "60 x 60 cm" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Ensoleille" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "VII-X" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "TOMATE A TUTEURER AUX FRUITS AROMATIQUES ET RESISTANTS A L'ECLATEMENT\nTOMATES MONEYMAKER\nSOLANUM LYCOPERSICUM\n1 GP\nPour la culture de printemps et d'ete\nConvient pour la culture en pleine terre\n8880340", + "arriere": "Tomates Moneymaker\nUtilisation: Une variete tres productive. Les fruits de 60 a 80 g sont tres aromatiques.\nCulture et soin: Germination 12 a 18 jours. A partir de la mi-mai, les jeunes plants vigoureux peuvent etre repiques en respectant un espacement d'environ 60 x 60 cm. Les tomates ont besoin d'un tuteur et d'un sol meuble et fertilise.\nConseil: Pour l'arrosage direct, recourir a la technique du pot en terre enfoui dans le sol et rempli d'eau. Enlever les gourmands et les feuilles proches du sol.\nPictogrammes: 20-25 C; 1 cm; Semis pre-culture en pot III-IV; Distance 60 x 60 cm; Exposition Ensoleille; Recolte VII-X.\nLe contenu suffit pour environ 45 plantes. 0,3 g." + } + } + }, + { + "id": 7, + "plante": "Poireau Bleu de Solaise", + "nom_latin": "Allium porrum", + "images": [ + "IMG_4792.jpg", + "IMG_4793.jpg" + ], + "texte_extrait": { + "avant": "Resistant au froid. Semis: avril a mai. Recolte: decembre a mars.", + "arriere": "Exposition soleil, T C de germination 10 C, levee 15 a 20 jours." + }, + "caracteristiques_plantation": { + "semis": "Pleine terre / terrine-godet", + "periode_semis": "IV-V", + "temperature": "10 C (germination)", + "profondeur": "1 cm", + "espacement": "10 cm entre plants", + "exposition": "Soleil", + "periode_recolte": "XII-III", + "duree_apres_semis": "~8 mois" + }, + "icones_significatives": [ + { + "icone": "flocon", + "signification": "Resistance", + "valeur": "Resistant au froid" + }, + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Avril-Mai" + }, + { + "icone": "panier", + "signification": "Periode recolte", + "valeur": "Decembre-Mars" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "inVivo Nous on seme\nPOIREAU BLEU DE SOLAISE\nCODE PRIX 3\nCOLLECTION LEGUME FEUILLE\nRESISTANT AU FROID\nFORMAT IDEAL POUR GRAND POTAGER\nSEMIS: AVRIL A MAI\nRECOLTE: DECEMBRE A MARS\n5 x 5 m", + "arriere": "COLLECTION LEGUME FEUILLE\nConseils d'utilisation\nPeriode de semis: avril-mai\nPeriode de recolte: decembre-mars\nExposition: soleil\nT C de germination: 10 C\nTemps de levee: 15 a 20 jours\nArrosage: +++\nRecolte: des 8 mois apres les semis\nPour semer en terre: preparer l'espace, choisir la methode de semis, recouvrir, tasser, arroser, maintenir le sol humide puis eclaircir.\nTableaux methodes/indications: profondeur de semis ~1 cm, stade de repiquage ~7 cm de hauteur, espacement entre plants ~10 cm.\nPoids net: 10 g." + } + } + }, + { + "id": 8, + "plante": "Echalion Zebrune", + "nom_latin": "Allium cepa", + "images": [ + "IMG_4794.jpg", + "IMG_4795.jpg" + ], + "texte_extrait": { + "avant": "Calendrier semis/recolte par mois.", + "arriere": "Semis de fevrier a avril en lignes espacees de 20-25 cm. Recolte d'aout a octobre." + }, + "caracteristiques_plantation": { + "semis": "Pleine terre", + "periode_semis": "II-IV", + "temperature": "Sol min 10 C", + "profondeur": null, + "espacement": "20-25 cm entre lignes, eclaircissage a 8 cm", + "exposition": "Tous types de sol, prefere sols sableux", + "periode_recolte": "VIII-X", + "levee": "13-15 jours" + }, + "icones_significatives": [ + { + "icone": "calendrier mois", + "signification": "Periodes semis/recolte", + "valeur": "Semis II-IV, recolte VIII-X" + }, + { + "icone": "thermometre", + "signification": "Temperature sol", + "valeur": "10 C min" + }, + { + "icone": "etape 1", + "signification": "Semis", + "valeur": "Lignes 20-25 cm" + }, + { + "icone": "etape 2", + "signification": "Eclaircissage", + "valeur": "8 cm" + }, + { + "icone": "etape 3", + "signification": "Recolte", + "valeur": "Aout-Octobre" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vilmorin depuis 1743\nCODE 2\nEchalion Zebrune\nCalendrier semis/recolte par mois (pastilles sur fevrier-avril et aout-octobre).", + "arriere": "Allium cepa\nEchalion Zebrune\nLevee en 13/15 jours\nTemperature du sol 10 C mini\nCette variete est proche du type echalote cuisse de poulet, avec sa forme allongee et sa couleur cuivree.\nPlantes compagnes: l'echalion aime la proximite de la poiree.\nConseil culture: pousse partout mais apprecie les sols sableux, craint l'humidite.\n1. Semis: semez de fevrier a avril, en pleine terre, en lignes espacees de 20-25 cm.\n2. Eclaircissage: quand vos echalions ont 3-4 feuilles, arracher les plus petits; conserver les plus vigoureux, afin de ne laisser qu'un echalion tous les 8 cm.\n3. Recolte: recoltez d'aout a octobre. Arrachez par temps sec, laissez secher sur le sol quelques jours puis stockez au sec." + } + } + }, + { + "id": 9, + "plante": "Courge Musquee Sucrine du Berry", + "nom_latin": "Cucurbita moschata", + "images": [ + "IMG_4796.jpg", + "IMG_4797.jpg" + ], + "texte_extrait": { + "avant": "Adaptee aux recettes salees et sucrees. Jusqu'a 10 pieds.", + "arriere": "Semis de mars a mai, 4-5 graines par trou, trous distants de 1 m x 1,50 m." + }, + "caracteristiques_plantation": { + "semis": "Pleine terre", + "periode_semis": "III-V", + "temperature": "Sol min 15 C", + "profondeur": "Trou peu profond", + "espacement": "1 m x 1,5 m", + "exposition": "Ensoleillee", + "periode_recolte": "IX-XII", + "levee": "6-8 jours" + }, + "icones_significatives": [ + { + "icone": "calendrier mois", + "signification": "Periodes", + "valeur": "Semis III-V, recolte IX-XII" + }, + { + "icone": "thermometre", + "signification": "Temperature sol", + "valeur": "15 C min" + }, + { + "icone": "capsule 'jusqu'a'", + "signification": "Rendement", + "valeur": "Jusqu'a 10 pieds" + }, + { + "icone": "etape semis", + "signification": "Nombre de graines", + "valeur": "4-5 graines/trou" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vilmorin depuis 1743\nCODE 3\nLes Legumes d'autrefois\nCourge Musquee Sucrine du Berry\nAdaptee aux recettes salees et sucrees\nCalendrier semis/recolte par mois\nJusqu'a 10 pieds", + "arriere": "Cucurbita moschata\nCourge Musquee Sucrine du Berry\nLevee en 6/8 jours\nTemperature du sol 15 C mini\nLa courge Sucrine du Berry est une variete coureuse produisant 5 a 8 fruits par pied, de 12 a 15 cm de diametre dans la partie renflee, de 1 a 3 kg en moyenne.\nConseil cuisine: delicieuse en soupes, tartes, puree ou a l'aperitif en croustilles.\nPlantes compagnes: aime la proximite du radis.\nConseil culture: pour avoir de grosses courges, recouvrir la tige de terre pour permettre la creation de nouvelles racines; aime l'exposition ensoleillee.\n1. Semis: semez 4-5 graines de mars a mai, dans des petits trous peu profonds, distants de 1 m x 1,50 m.\n2. Eclaircissage: garder le plus vigoureux quand 3-4 feuilles.\n3. Recolte: recoltez de septembre a decembre." + } + } + }, + { + "id": 10, + "plante": "Laitue Pommee Grosse Blonde Paresseuse", + "nom_latin": null, + "images": [ + "IMG_4798.jpg", + "IMG_4799.jpg" + ], + "texte_extrait": { + "avant": "Resistante a la chaleur. Je seme avril a juillet. Je recolte 3 mois apres le semis.", + "arriere": "Temperature minimum du sol 10 C. Levee en 8-10 jours." + }, + "caracteristiques_plantation": { + "semis": "Sous abri puis pleine terre / semis direct", + "periode_semis": "IV-VII", + "temperature": "Sol min 10 C", + "profondeur": "~3 cm (semis en terrine selon notice)", + "espacement": null, + "exposition": null, + "periode_recolte": "Fin VI-X", + "duree_apres_semis": "~3 mois" + }, + "icones_significatives": [ + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Avril-Juillet" + }, + { + "icone": "panier", + "signification": "Recolte", + "valeur": "3 mois apres semis" + }, + { + "icone": "tableau mensuel", + "signification": "Calendrier", + "valeur": "Semis IV-VII, recolte fin VI-X" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vilmorin depuis 1743\nCODE 1\nLaitue Pommee Grosse Blonde Paresseuse\nResistante a la chaleur - Tardive\nJe seme: AVRIL A JUILLET\n5 x 5 m\nJe recolte: 3 MOIS apres les semis", + "arriere": "Variete recommandee pour des recoltes d'ete-automne, resistante a la chaleur et lente a la montee a graines.\nJe seme: d'avril a juillet, tous les 15 jours pour des recoltes echelonnees.\nJe recolte: de fin juin a octobre, 3 mois apres le semis.\nJe deguste: feuilles crues, en salade ou braisees.\nNos secrets pour reussir votre recolte:\n- Temperature minimum du sol 10 C\n- Levee en 8-10 jours\n- Semer en terrine (1 graine tous les 3 cm, recouvrir de terreau, arroser, placer sous abri)\n- Ou semer en pleine terre en avril-mai quand le sol se rechauffe\n- Repiquer au stade 5-6 feuilles\nCalendrier en pictogrammes: semis IV-VII, recolte fin VI-X." + } + } + }, + { + "id": 11, + "plante": "Chou Pomme de Brunswick", + "nom_latin": null, + "images": [ + "IMG_4800.jpg", + "IMG_4801.jpg" + ], + "texte_extrait": { + "avant": "Je seme avril-juillet. Je recolte 3-4 mois apres semis.", + "arriere": "Temperature minimum du sol 15 C. Levee en 6-8 jours." + }, + "caracteristiques_plantation": { + "semis": "Terrine/godet puis pleine terre", + "periode_semis": "IV-VII", + "temperature": "Sol min 15 C", + "profondeur": null, + "espacement": "60 x 50 cm apres repiquage", + "exposition": null, + "periode_recolte": "VII-XI", + "duree_apres_semis": "3-4 mois" + }, + "icones_significatives": [ + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Avril-Juillet" + }, + { + "icone": "panier", + "signification": "Periode recolte", + "valeur": "Juillet-Novembre" + }, + { + "icone": "tableau mensuel", + "signification": "Calendrier", + "valeur": "Semis IV-VII, recolte VII-XI" + }, + { + "icone": "thermometre", + "signification": "Temperature sol", + "valeur": "15 C min" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vilmorin depuis 1743\nCODE 0\nChou Pomme de Brunswick\nPomme tres volumineuse\nPour des recoltes d'ete-automne\nJe seme: AVRIL - JUILLET\nJusqu'a 90 pieds\nJe recolte: 3-4 MOIS apres semis", + "arriere": "Variete tardive aux feuilles vertes produisant une pomme volumineuse (jusqu'a 3,5 kg), compacte et tres serree.\nJe seme: d'avril a juillet, dans une terre fraiche, humide et riche d'engrais naturels.\nJe recolte: de juillet a novembre, 3-4 mois apres le semis.\nJe deguste: pommes crues, rapees en salade, ou cuites en potee.\nNos secrets pour reussir votre recolte:\n- Temperature minimum du sol 15 C\n- Levee en 6-8 jours\n- Semis en terrine (2-3 graines) puis repiquage\n- Semis direct possible en avril-mai (1 graine tous les 30 cm)\n- Repiquer en pleine terre a 60 x 50 cm au stade 5-6 feuilles\nCalendrier en pictogrammes: semis IV-VII, recolte VII-XI." + } + } + }, + { + "id": 12, + "plante": "Chou-fleur Nautilus HF1", + "nom_latin": null, + "images": [ + "IMG_4802.jpg", + "IMG_4803.jpg" + ], + "texte_extrait": { + "avant": "Semis: mars a juillet. Recolte: juillet a novembre.", + "arriere": "Exposition soleil. T C de germination 15 C. Levee 5 jours." + }, + "caracteristiques_plantation": { + "semis": "Sous abri / godet / pleine terre", + "periode_semis": "III-VII", + "temperature": "15 C (germination)", + "profondeur": "< 1 cm", + "espacement": "70 cm entre plants", + "exposition": "Soleil", + "periode_recolte": "VII-XI", + "duree_apres_semis": "~4 mois" + }, + "icones_significatives": [ + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Mars-Juillet" + }, + { + "icone": "panier", + "signification": "Periode recolte", + "valeur": "Juillet-Novembre" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + }, + { + "icone": "thermometre", + "signification": "Temperature germination", + "valeur": "15 C" + }, + { + "icone": "profondeur", + "signification": "Profondeur semis", + "valeur": "< 1 cm" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "inVivo Nous on seme\nCHOU-FLEUR NAUTILUS HF1\nCODE PRIX 4\nCOLLECTION LEGUME FEUILLE\nRECOLTE GENEREUSE\nSEMIS: MARS A JUILLET\nRECOLTE: JUILLET A NOVEMBRE\nJusqu'a 60 pieds", + "arriere": "COLLECTION LEGUME FEUILLE\nLe Chou-Fleur Nautilus HF1 est une variete hybride precoce, productive et de qualite gustative.\nConseils d'utilisation:\nPeriode de semis: mars a juillet\nPeriode de recolte: juillet a novembre\nExposition: soleil\nT C de germination: 15 C\nTemps de levee: 5 jours\nArrosage: ++\nRecolte: 4 mois apres les semis\nPour semer en terre: preparer l'espace, recouvrir, tasser, arroser et maintenir le sol humide.\nIndications sur semis: profondeur < 1 cm; stade de repiquage 4-5 feuilles; espacement entre plants 70 cm.\nPoids net: 0,3 g." + } + } + }, + { + "id": 13, + "plante": "Tomate Cornue Cornabel HF1", + "nom_latin": "Solanum lycopersicum", + "images": [ + "IMG_4804.jpg", + "IMG_4805.jpg" + ], + "texte_extrait": { + "avant": "Je seme fevrier-mai. Je recolte 5 mois apres le semis.", + "arriere": "Temperature minimum du sol 18-20 C. Levee en 6-8 jours." + }, + "caracteristiques_plantation": { + "semis": "Godet/terrine puis pleine terre", + "periode_semis": "II-V", + "temperature": "18-20 C (20 C recommande au semis en godet)", + "profondeur": null, + "espacement": "50 x 80 cm", + "exposition": null, + "periode_recolte": "VII-X", + "duree_apres_semis": "~5 mois" + }, + "icones_significatives": [ + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Fin fevrier-mai" + }, + { + "icone": "panier", + "signification": "Periode recolte", + "valeur": "Juillet-Octobre" + }, + { + "icone": "thermometre", + "signification": "Temperature sol", + "valeur": "18-20 C" + }, + { + "icone": "tableau mensuel", + "signification": "Calendrier", + "valeur": "Semis II-V, recolte VII-X" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "Vilmorin depuis 1743\nCODE 3\nGRAINES D'EXCEPTION\nTomate Cornue Cornabel HF1\nJe seme: FEVRIER - MAI\nJusqu'a 25 pieds\nJe recolte: 5 MOIS apres le semis\nRESISTE AUX MALADIES", + "arriere": "Variete hybride de type cornue, tres resistante aux maladies (verticilliose, fusariose, va).\nAmelioration de la tomate Cornue des Andes, fruits longs (15 cm), charnus, lourds (jusqu'a 200 g), chair fondante, peu acide et sans pepins.\nJe seme: de fin fevrier a mai, dans un sol riche en amendements.\nJe recolte: de juillet a octobre, 5 mois apres le semis.\nJe deguste: fruits crus coupes en lamelles pour salades estivales.\nNos secrets pour reussir votre recolte:\n- Temperature minimum du sol 18-20 C\n- Levee en 6-8 jours\n- Semis en godet (2 graines) ou pleine terre en avril-mai si sol rechauffe\n- Repiquer en mai-juin a 50 x 80 cm\nCalendrier en pictogrammes: semis II-V, recolte VII-X." + } + } + }, + { + "id": 14, + "plante": "Pois mangetout Carouby de Maussane", + "nom_latin": "Pisum sativum", + "images": [ + "IMG_4806.jpg", + "IMG_4807.jpg" + ], + "texte_extrait": { + "avant": "Semis: fevrier a novembre. Recolte: mai a juillet.", + "arriere": "Exposition soleil. T C de germination 20 C. Levee 6-8 jours." + }, + "caracteristiques_plantation": { + "semis": "Pleine terre / ligne / poquet", + "periode_semis": "II-XI (selon sachet)", + "temperature": "20 C (germination)", + "profondeur": "3 cm", + "espacement": "40 cm entre plants", + "exposition": "Soleil", + "periode_recolte": "V-VII (ou 3 mois apres semis de printemps)", + "duree_apres_semis": "3 mois (printemps), 6-7 mois (automne)" + }, + "icones_significatives": [ + { + "icone": "main semis", + "signification": "Periode semis", + "valeur": "Fevrier-Novembre" + }, + { + "icone": "panier", + "signification": "Periode recolte", + "valeur": "Mai-Juillet" + }, + { + "icone": "soleil", + "signification": "Exposition", + "valeur": "Soleil" + }, + { + "icone": "thermometre", + "signification": "Temperature germination", + "valeur": "20 C" + }, + { + "icone": "goutte", + "signification": "Arrosage", + "valeur": "Soutenu (+)" + } + ], + "detail": { + "texte_integral_visible": { + "avant": "inVivo Nous on seme\nPOIS MANGETOUT CAROUBY DE MAUSSANE\nPied demi-nain - H. 90 cm\nCODE PRIX 2\nCOLLECTION POIS\nFACILE A CULTIVER\nSEMIS: FEVRIER A NOVEMBRE\nRECOLTE: MAI A JUILLET\n4 x 5 m", + "arriere": "COLLECTION POIS\nLe Pois Carouby de Maussane (Pisum sativum L) est une variete demi-naine, tardive, a production importante et assez groupee.\nConseils d'utilisation:\nPeriode de semis: fevrier a novembre\nPeriode de recolte: mai a juillet\nExposition: soleil\nT C de germination: 20 C\nTemps de levee: 6 a 8 jours\nArrosage: +++\nRecolte: 3 mois apres les semis de printemps, 6 a 7 mois apres semis d'automne\nIndications sur semis: espacement 40 cm (10 graines) en ligne; 60 cm en poquet; profondeur 3 cm; espacement entre plants 40 cm.\nEntretien: biner en surface, butter, tuteurer, veiller a l'arrosage regulier.\nRecolte: recolter juste au debut de formation des grains.\nPoids net: 200 g." + } + } + } + ], + "notes": [ + "Extraction faite manuellement depuis photos (sans OCR automatique).", + "Quelques valeurs tres fines (ex: profondeur/espacements sur certains sachets) peuvent necessiter une verification visuelle complementaire." + ] +} \ No newline at end of file diff --git a/docs/plans/2026-03-08-intrants-fabrications-design.md b/docs/plans/2026-03-08-intrants-fabrications-design.md new file mode 100644 index 0000000..35a1cc6 --- /dev/null +++ b/docs/plans/2026-03-08-intrants-fabrications-design.md @@ -0,0 +1,140 @@ +# 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 | diff --git a/docs/plans/2026-03-08-intrants-fabrications.md b/docs/plans/2026-03-08-intrants-fabrications.md new file mode 100644 index 0000000..76edd64 --- /dev/null +++ b/docs/plans/2026-03-08-intrants-fabrications.md @@ -0,0 +1,1326 @@ +# Intrants & Fabrications — Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Ajouter la gestion des achats d'intrants (terreau, engrais, traitements) et des fabrications maison (compost, décoctions, purins) dans une vue unique avec deux onglets, liée aux jardins/plantations/tâches. + +**Architecture:** Deux tables SQLite (`achat_intrant` + `fabrication`), deux routers FastAPI, une vue Vue 3 `IntratsView.vue` avec onglets. Les ingrédients de fabrication sont stockés en JSON. Liaisons optionnelles vers garden/planting/task. + +**Tech Stack:** FastAPI + SQLModel + SQLite · Vue 3 + Pinia + Tailwind CSS Gruvbox Dark + +--- + +### Task 1 : Modèles SQLModel backend + +**Files:** +- Create: `backend/app/models/intrant.py` +- Modify: `backend/app/models/__init__.py` + +**Step 1: Créer le fichier modèle** + +```python +# backend/app/models/intrant.py +from datetime import datetime, timezone +from typing import List, Optional +from sqlalchemy import Column +from sqlalchemy import JSON as SA_JSON +from sqlmodel import Field, SQLModel + + +class AchatIntrant(SQLModel, table=True): + __tablename__ = "achat_intrant" + + id: Optional[int] = Field(default=None, primary_key=True) + categorie: str # terreau | engrais | traitement | autre + nom: str + marque: Optional[str] = None + boutique_nom: Optional[str] = None + boutique_url: Optional[str] = None + prix: Optional[float] = None + poids: Optional[str] = None # "20L", "1kg", "500ml" + date_achat: Optional[str] = None # ISO date + dluo: Optional[str] = None # ISO date + notes: Optional[str] = None + jardin_id: Optional[int] = Field(default=None, foreign_key="garden.id") + plantation_id: Optional[int] = Field(default=None, foreign_key="planting.id") + tache_id: Optional[int] = Field(default=None, foreign_key="task.id") + created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + + +class Ingredient(SQLModel): + """Modèle pour un ingrédient de fabrication (non persisté seul).""" + nom: str + quantite: str # "1kg", "10L" + + +class Fabrication(SQLModel, table=True): + __tablename__ = "fabrication" + + id: Optional[int] = Field(default=None, primary_key=True) + type: str # compost | decoction | purin | autre + nom: str + ingredients: Optional[List[dict]] = Field( + default=None, + sa_column=Column("ingredients", SA_JSON, nullable=True), + ) + date_debut: Optional[str] = None # ISO date + date_fin_prevue: Optional[str] = None # ISO date + statut: str = "en_cours" # en_cours | pret | utilise | echec + quantite_produite: Optional[str] = None # "8L", "50kg" + notes: Optional[str] = None + jardin_id: Optional[int] = Field(default=None, foreign_key="garden.id") + plantation_id: Optional[int] = Field(default=None, foreign_key="planting.id") + tache_id: Optional[int] = Field(default=None, foreign_key="task.id") + created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + + +class FabricationStatutUpdate(SQLModel): + statut: str +``` + +**Step 2: Enregistrer dans `__init__.py`** + +Ajouter à la fin de `backend/app/models/__init__.py` : +```python +from app.models.intrant import AchatIntrant, Fabrication # noqa +``` + +**Step 3: Vérifier que SQLModel crée bien les tables** + +```bash +cd backend +python3 -c "from app.models.intrant import AchatIntrant, Fabrication; print('OK')" +``` +Expected: `OK` + +**Step 4: Commit** + +```bash +git add backend/app/models/intrant.py backend/app/models/__init__.py +git commit -m "feat(intrants): add AchatIntrant + Fabrication SQLModel" +``` + +--- + +### Task 2 : Migration BDD + +**Files:** +- Modify: `backend/app/migrate.py` + +**Step 1: Ajouter les sections dans `EXPECTED_COLUMNS`** + +Dans `backend/app/migrate.py`, après la section `"astuce"`, ajouter : + +```python + "achat_intrant": [ + ("categorie", "TEXT", None), + ("nom", "TEXT", None), + ("marque", "TEXT", None), + ("boutique_nom", "TEXT", None), + ("boutique_url", "TEXT", None), + ("prix", "REAL", None), + ("poids", "TEXT", None), + ("date_achat", "TEXT", None), + ("dluo", "TEXT", None), + ("notes", "TEXT", None), + ("jardin_id", "INTEGER", None), + ("plantation_id", "INTEGER", None), + ("tache_id", "INTEGER", None), + ], + "fabrication": [ + ("type", "TEXT", None), + ("nom", "TEXT", None), + ("ingredients", "TEXT", None), + ("date_debut", "TEXT", None), + ("date_fin_prevue", "TEXT", None), + ("statut", "TEXT", "'en_cours'"), + ("quantite_produite", "TEXT", None), + ("notes", "TEXT", None), + ("jardin_id", "INTEGER", None), + ("plantation_id", "INTEGER", None), + ("tache_id", "INTEGER", None), + ], +``` + +**Step 2: Appliquer la migration manuellement** + +```bash +python3 - <<'EOF' +import sqlite3 + +conn = sqlite3.connect('data/jardin.db') + +# Créer achat_intrant si absente +conn.execute(""" + CREATE TABLE IF NOT EXISTS achat_intrant ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + categorie TEXT NOT NULL, + nom TEXT NOT NULL, + marque TEXT, + boutique_nom TEXT, + boutique_url TEXT, + prix REAL, + poids TEXT, + date_achat TEXT, + dluo TEXT, + notes TEXT, + jardin_id INTEGER REFERENCES garden(id), + plantation_id INTEGER REFERENCES planting(id), + tache_id INTEGER REFERENCES task(id), + created_at TEXT DEFAULT (datetime('now')) + ) +""") + +# Créer fabrication si absente +conn.execute(""" + CREATE TABLE IF NOT EXISTS fabrication ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + type TEXT NOT NULL, + nom TEXT NOT NULL, + ingredients TEXT, + date_debut TEXT, + date_fin_prevue TEXT, + statut TEXT DEFAULT 'en_cours', + quantite_produite TEXT, + notes TEXT, + jardin_id INTEGER REFERENCES garden(id), + plantation_id INTEGER REFERENCES planting(id), + tache_id INTEGER REFERENCES task(id), + created_at TEXT DEFAULT (datetime('now')) + ) +""") + +conn.commit() +conn.close() +print("Tables créées") +EOF +``` +Expected: `Tables créées` + +**Step 3: Commit** + +```bash +git add backend/app/migrate.py +git commit -m "feat(intrants): add migration for achat_intrant + fabrication tables" +``` + +--- + +### Task 3 : Router achats (CRUD) + +**Files:** +- Create: `backend/app/routers/achats.py` + +**Step 1: Créer le router** + +```python +# backend/app/routers/achats.py +from typing import List, Optional +from fastapi import APIRouter, Depends, HTTPException, Query, status +from sqlmodel import Session, select +from app.database import get_session +from app.models.intrant import AchatIntrant + +router = APIRouter(tags=["intrants"]) + + +@router.get("/achats", response_model=List[AchatIntrant]) +def list_achats( + categorie: Optional[str] = Query(None), + jardin_id: Optional[int] = Query(None), + session: Session = Depends(get_session), +): + q = select(AchatIntrant) + if categorie: + q = q.where(AchatIntrant.categorie == categorie) + if jardin_id: + q = q.where(AchatIntrant.jardin_id == jardin_id) + return session.exec(q.order_by(AchatIntrant.created_at.desc())).all() + + +@router.post("/achats", response_model=AchatIntrant, status_code=status.HTTP_201_CREATED) +def create_achat(a: AchatIntrant, session: Session = Depends(get_session)): + session.add(a) + session.commit() + session.refresh(a) + return a + + +@router.get("/achats/{id}", response_model=AchatIntrant) +def get_achat(id: int, session: Session = Depends(get_session)): + a = session.get(AchatIntrant, id) + if not a: + raise HTTPException(404, "Achat introuvable") + return a + + +@router.put("/achats/{id}", response_model=AchatIntrant) +def update_achat(id: int, data: AchatIntrant, session: Session = Depends(get_session)): + a = session.get(AchatIntrant, id) + if not a: + raise HTTPException(404, "Achat introuvable") + for k, v in data.model_dump(exclude_unset=True, exclude={"id", "created_at"}).items(): + setattr(a, k, v) + session.add(a) + session.commit() + session.refresh(a) + return a + + +@router.delete("/achats/{id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_achat(id: int, session: Session = Depends(get_session)): + a = session.get(AchatIntrant, id) + if not a: + raise HTTPException(404, "Achat introuvable") + session.delete(a) + session.commit() +``` + +**Step 2: Commit** + +```bash +git add backend/app/routers/achats.py +git commit -m "feat(intrants): CRUD router for achats" +``` + +--- + +### Task 4 : Router fabrications (CRUD + PATCH statut) + +**Files:** +- Create: `backend/app/routers/fabrications.py` + +**Step 1: Créer le router** + +```python +# backend/app/routers/fabrications.py +from typing import List, Optional +from fastapi import APIRouter, Depends, HTTPException, Query, status +from sqlmodel import Session, select +from app.database import get_session +from app.models.intrant import Fabrication, FabricationStatutUpdate + +router = APIRouter(tags=["intrants"]) + + +@router.get("/fabrications", response_model=List[Fabrication]) +def list_fabrications( + type: Optional[str] = Query(None), + statut: Optional[str] = Query(None), + jardin_id: Optional[int] = Query(None), + session: Session = Depends(get_session), +): + q = select(Fabrication) + if type: + q = q.where(Fabrication.type == type) + if statut: + q = q.where(Fabrication.statut == statut) + if jardin_id: + q = q.where(Fabrication.jardin_id == jardin_id) + return session.exec(q.order_by(Fabrication.created_at.desc())).all() + + +@router.post("/fabrications", response_model=Fabrication, status_code=status.HTTP_201_CREATED) +def create_fabrication(f: Fabrication, session: Session = Depends(get_session)): + session.add(f) + session.commit() + session.refresh(f) + return f + + +@router.get("/fabrications/{id}", response_model=Fabrication) +def get_fabrication(id: int, session: Session = Depends(get_session)): + f = session.get(Fabrication, id) + if not f: + raise HTTPException(404, "Fabrication introuvable") + return f + + +@router.put("/fabrications/{id}", response_model=Fabrication) +def update_fabrication(id: int, data: Fabrication, session: Session = Depends(get_session)): + f = session.get(Fabrication, id) + if not f: + raise HTTPException(404, "Fabrication introuvable") + for k, v in data.model_dump(exclude_unset=True, exclude={"id", "created_at"}).items(): + setattr(f, k, v) + session.add(f) + session.commit() + session.refresh(f) + return f + + +@router.patch("/fabrications/{id}/statut", response_model=Fabrication) +def update_statut(id: int, data: FabricationStatutUpdate, session: Session = Depends(get_session)): + f = session.get(Fabrication, id) + if not f: + raise HTTPException(404, "Fabrication introuvable") + valid = {"en_cours", "pret", "utilise", "echec"} + if data.statut not in valid: + raise HTTPException(400, f"Statut invalide. Valeurs: {valid}") + f.statut = data.statut + session.add(f) + session.commit() + session.refresh(f) + return f + + +@router.delete("/fabrications/{id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_fabrication(id: int, session: Session = Depends(get_session)): + f = session.get(Fabrication, id) + if not f: + raise HTTPException(404, "Fabrication introuvable") + session.delete(f) + session.commit() +``` + +**Step 2: Commit** + +```bash +git add backend/app/routers/fabrications.py +git commit -m "feat(intrants): CRUD + statut router for fabrications" +``` + +--- + +### Task 5 : Enregistrer les routers dans main.py + +**Files:** +- Modify: `backend/app/main.py` + +**Step 1: Ajouter l'import** + +Dans le bloc `from app.routers import (`, ajouter après `identify,` : +```python + achats, + fabrications, +``` + +**Step 2: Ajouter les includes** + +Après `app.include_router(identify.router, prefix="/api")`, ajouter : +```python +app.include_router(achats.router, prefix="/api") +app.include_router(fabrications.router, prefix="/api") +``` + +**Step 3: Tester l'API** + +```bash +cd backend && uvicorn app.main:app --reload --port 8060 +# Dans un autre terminal: +curl http://localhost:8060/api/achats +# Expected: [] +curl http://localhost:8060/api/fabrications +# Expected: [] +``` + +**Step 4: Commit** + +```bash +git add backend/app/main.py +git commit -m "feat(intrants): register achats + fabrications routers" +``` + +--- + +### Task 6 : API frontend (achats.ts + fabrications.ts) + +**Files:** +- Create: `frontend/src/api/achats.ts` +- Create: `frontend/src/api/fabrications.ts` + +**Step 1: Créer `achats.ts`** + +```typescript +// frontend/src/api/achats.ts +import client from './client' + +export interface AchatIntrant { + id?: number + categorie: string // terreau | engrais | traitement | autre + nom: string + marque?: string + boutique_nom?: string + boutique_url?: string + prix?: number + poids?: string + date_achat?: string + dluo?: string + notes?: string + jardin_id?: number + plantation_id?: number + tache_id?: number +} + +export const achatsApi = { + list: (params?: { categorie?: string; jardin_id?: number }) => + client.get('/api/achats', { params }).then(r => r.data), + get: (id: number) => client.get(`/api/achats/${id}`).then(r => r.data), + create: (a: Partial) => client.post('/api/achats', a).then(r => r.data), + update: (id: number, a: Partial) => client.put(`/api/achats/${id}`, a).then(r => r.data), + delete: (id: number) => client.delete(`/api/achats/${id}`), +} +``` + +**Step 2: Créer `fabrications.ts`** + +```typescript +// frontend/src/api/fabrications.ts +import client from './client' + +export interface Ingredient { + nom: string + quantite: string +} + +export interface Fabrication { + id?: number + type: string // compost | decoction | purin | autre + nom: string + ingredients?: Ingredient[] + date_debut?: string + date_fin_prevue?: string + statut?: string // en_cours | pret | utilise | echec + quantite_produite?: string + notes?: string + jardin_id?: number + plantation_id?: number + tache_id?: number +} + +export const fabricationsApi = { + list: (params?: { type?: string; statut?: string; jardin_id?: number }) => + client.get('/api/fabrications', { params }).then(r => r.data), + get: (id: number) => client.get(`/api/fabrications/${id}`).then(r => r.data), + create: (f: Partial) => client.post('/api/fabrications', f).then(r => r.data), + update: (id: number, f: Partial) => client.put(`/api/fabrications/${id}`, f).then(r => r.data), + updateStatut: (id: number, statut: string) => client.patch(`/api/fabrications/${id}/statut`, { statut }).then(r => r.data), + delete: (id: number) => client.delete(`/api/fabrications/${id}`), +} +``` + +**Step 3: Commit** + +```bash +git add frontend/src/api/achats.ts frontend/src/api/fabrications.ts +git commit -m "feat(intrants): frontend API clients for achats + fabrications" +``` + +--- + +### Task 7 : Stores Pinia + +**Files:** +- Create: `frontend/src/stores/achats.ts` +- Create: `frontend/src/stores/fabrications.ts` + +**Step 1: Créer `stores/achats.ts`** + +```typescript +// frontend/src/stores/achats.ts +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { achatsApi, type AchatIntrant } from '@/api/achats' + +export const useAchatsStore = defineStore('achats', () => { + const achats = ref([]) + const loading = ref(false) + + async function fetchAll(params?: { categorie?: string }) { + loading.value = true + try { achats.value = await achatsApi.list(params) } + finally { loading.value = false } + } + + async function create(a: Partial) { + const created = await achatsApi.create(a) + achats.value.unshift(created) + return created + } + + async function remove(id: number) { + await achatsApi.delete(id) + achats.value = achats.value.filter(a => a.id !== id) + } + + return { achats, loading, fetchAll, create, remove } +}) +``` + +**Step 2: Créer `stores/fabrications.ts`** + +```typescript +// frontend/src/stores/fabrications.ts +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { fabricationsApi, type Fabrication } from '@/api/fabrications' + +export const useFabricationsStore = defineStore('fabrications', () => { + const fabrications = ref([]) + const loading = ref(false) + + async function fetchAll(params?: { type?: string; statut?: string }) { + loading.value = true + try { fabrications.value = await fabricationsApi.list(params) } + finally { loading.value = false } + } + + async function create(f: Partial) { + const created = await fabricationsApi.create(f) + fabrications.value.unshift(created) + return created + } + + async function updateStatut(id: number, statut: string) { + const updated = await fabricationsApi.updateStatut(id, statut) + const idx = fabrications.value.findIndex(f => f.id === id) + if (idx !== -1) fabrications.value[idx] = updated + return updated + } + + async function remove(id: number) { + await fabricationsApi.delete(id) + fabrications.value = fabrications.value.filter(f => f.id !== id) + } + + return { fabrications, loading, fetchAll, create, updateStatut, remove } +}) +``` + +**Step 3: Commit** + +```bash +git add frontend/src/stores/achats.ts frontend/src/stores/fabrications.ts +git commit -m "feat(intrants): Pinia stores for achats + fabrications" +``` + +--- + +### Task 8 : Route + Navigation + +**Files:** +- Modify: `frontend/src/router/index.ts` +- Modify: `frontend/src/App.vue` +- Modify: `frontend/src/components/AppDrawer.vue` + +**Step 1: Ajouter la route dans `router/index.ts`** + +Après `{ path: '/outils', ... }` : +```typescript +{ path: '/intrants', component: () => import('@/views/IntratsView.vue') }, +``` + +**Step 2: Ajouter dans `App.vue` (liste `links`)** + +Après `{ to: '/outils', label: 'Outils', icon: '🔧' }` : +```typescript +{ to: '/intrants', label: 'Intrants', icon: '🧪' }, +``` + +**Step 3: Ajouter dans `AppDrawer.vue` (liste `links`)** + +Après `{ to: '/outils', label: 'Outils' }` : +```typescript +{ to: '/intrants', label: '🧪 Intrants' }, +``` + +**Step 4: Commit** + +```bash +git add frontend/src/router/index.ts frontend/src/App.vue frontend/src/components/AppDrawer.vue +git commit -m "feat(intrants): add /intrants route + sidebar nav" +``` + +--- + +### Task 9 : IntratsView.vue — structure + onglet Achats + +**Files:** +- Create: `frontend/src/views/IntratsView.vue` + +**Step 1: Créer la vue complète** + +```vue + +