diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index e69de29..a0ccd9a 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -0,0 +1,5 @@ +from app.models.garden import Garden, GardenCell, GardenImage, Measurement # noqa +from app.models.plant import PlantVariety, PlantImage # noqa +from app.models.planting import Planting, PlantingEvent # noqa +from app.models.task import Task # noqa +from app.models.settings import UserSettings, LunarCalendarEntry # noqa diff --git a/backend/app/models/garden.py b/backend/app/models/garden.py new file mode 100644 index 0000000..48b361c --- /dev/null +++ b/backend/app/models/garden.py @@ -0,0 +1,53 @@ +from datetime import datetime +from typing import Optional +from sqlmodel import Field, SQLModel + + +class Garden(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + nom: str + description: Optional[str] = None + type: str = "plein_air" # plein_air | serre | tunnel + latitude: Optional[float] = None + longitude: Optional[float] = None + altitude: Optional[float] = None + adresse: Optional[str] = None + exposition: Optional[str] = None + ombre: Optional[str] = None # ombre | mi-ombre | plein_soleil + sol_type: Optional[str] = None + sol_ph: Optional[float] = None + grille_largeur: int = 6 + grille_hauteur: int = 4 + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + +class GardenCell(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + garden_id: int = Field(foreign_key="garden.id", index=True) + col: int + row: int + libelle: Optional[str] = None + largeur_m: Optional[float] = None + hauteur_m: Optional[float] = None + etat: str = "libre" # libre | occupe + notes: Optional[str] = None + + +class GardenImage(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + garden_id: int = Field(foreign_key="garden.id", index=True) + filename: str + caption: Optional[str] = None + created_at: datetime = Field(default_factory=datetime.utcnow) + + +class Measurement(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + garden_id: int = Field(foreign_key="garden.id", index=True) + temp_air: Optional[float] = None + temp_sol: Optional[float] = None + humidite_air: Optional[float] = None + humidite_sol: Optional[float] = None + source: str = "manuel" # manuel | capteur + ts: datetime = Field(default_factory=datetime.utcnow) diff --git a/backend/app/models/plant.py b/backend/app/models/plant.py new file mode 100644 index 0000000..a58a4cd --- /dev/null +++ b/backend/app/models/plant.py @@ -0,0 +1,35 @@ +from datetime import datetime +from typing import Optional +from sqlmodel import Field, SQLModel + + +class PlantVariety(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + nom_commun: str + nom_botanique: Optional[str] = None + variete: Optional[str] = None + famille: Optional[str] = None + tags: Optional[str] = None # CSV + type_plante: Optional[str] = None # legume | fruit | aromatique | fleur + besoin_eau: Optional[str] = None # faible | moyen | fort + besoin_soleil: Optional[str] = None + espacement_cm: Optional[int] = None + temp_min_c: Optional[float] = None + duree_culture_j: Optional[int] = None + profondeur_semis_cm: Optional[float] = None + sol_conseille: Optional[str] = None + semis_interieur_mois: Optional[str] = None # ex: "2,3" + semis_exterieur_mois: Optional[str] = None + repiquage_mois: Optional[str] = None + plantation_mois: Optional[str] = None + recolte_mois: Optional[str] = None + notes: Optional[str] = None + created_at: datetime = Field(default_factory=datetime.utcnow) + + +class PlantImage(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + variety_id: int = Field(foreign_key="plantvariety.id", index=True) + filename: str + caption: Optional[str] = None + created_at: datetime = Field(default_factory=datetime.utcnow) diff --git a/backend/app/models/planting.py b/backend/app/models/planting.py new file mode 100644 index 0000000..c8bf9e7 --- /dev/null +++ b/backend/app/models/planting.py @@ -0,0 +1,30 @@ +from datetime import date, datetime +from typing import Optional +from sqlmodel import Field, SQLModel + + +class Planting(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + garden_id: int = Field(foreign_key="garden.id", index=True) + variety_id: int = Field(foreign_key="plantvariety.id", index=True) + cell_id: Optional[int] = Field(default=None, foreign_key="gardencell.id") + date_semis: Optional[date] = None + date_plantation: Optional[date] = None + date_repiquage: Optional[date] = None + quantite: int = 1 + statut: str = "prevu" # prevu | en_cours | termine | echoue + date_recolte_debut: Optional[date] = None + date_recolte_fin: Optional[date] = None + rendement_estime: Optional[float] = None + rendement_reel: Optional[float] = None + notes: Optional[str] = None + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + +class PlantingEvent(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + planting_id: int = Field(foreign_key="planting.id", index=True) + type: str # arrosage | taille | traitement | observation | autre + note: Optional[str] = None + ts: datetime = Field(default_factory=datetime.utcnow) diff --git a/backend/app/models/settings.py b/backend/app/models/settings.py new file mode 100644 index 0000000..d9074cf --- /dev/null +++ b/backend/app/models/settings.py @@ -0,0 +1,17 @@ +from datetime import date +from typing import Optional +from sqlmodel import Field, SQLModel + + +class UserSettings(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + cle: str = Field(unique=True) + valeur: str + + +class LunarCalendarEntry(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + jour: date = Field(unique=True) + phase: str # nouvelle_lune | premier_quartier | pleine_lune | dernier_quartier | croissante | decroissante + type_jour: Optional[str] = None # racine | feuille | fleur | fruit + lune_montante: Optional[bool] = None diff --git a/backend/app/models/task.py b/backend/app/models/task.py new file mode 100644 index 0000000..47c0761 --- /dev/null +++ b/backend/app/models/task.py @@ -0,0 +1,17 @@ +from datetime import date, datetime +from typing import Optional +from sqlmodel import Field, SQLModel + + +class Task(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + titre: str + description: Optional[str] = None + garden_id: Optional[int] = Field(default=None, foreign_key="garden.id") + planting_id: Optional[int] = Field(default=None, foreign_key="planting.id") + priorite: str = "normale" # basse | normale | haute + echeance: Optional[date] = None + recurrence: Optional[str] = None # quotidien | hebdomadaire | mensuel + statut: str = "a_faire" # a_faire | en_cours | fait | annule + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow)