feat(backend): settings, upload media, seed données démo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,9 +36,13 @@ app.include_router(tasks.router, prefix="/api")
|
||||
app.include_router(settings.router, prefix="/api")
|
||||
app.include_router(media.router, prefix="/api")
|
||||
|
||||
# Note: le mount StaticFiles sera ajouté ici dans Task 6
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
# Monter uploads seulement si le dossier existe
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
if os.path.isdir(UPLOAD_DIR):
|
||||
app.mount("/uploads", StaticFiles(directory=UPLOAD_DIR, html=False), name="uploads")
|
||||
|
||||
@@ -1,2 +1,29 @@
|
||||
from fastapi import APIRouter
|
||||
router = APIRouter()
|
||||
import os
|
||||
import uuid
|
||||
from fastapi import APIRouter, File, HTTPException, UploadFile
|
||||
from app.config import UPLOAD_DIR
|
||||
|
||||
router = APIRouter(tags=["media"])
|
||||
|
||||
ALLOWED_EXT = {".jpg", ".jpeg", ".png", ".webp", ".gif"}
|
||||
|
||||
|
||||
@router.post("/upload")
|
||||
async def upload_file(file: UploadFile = File(...)):
|
||||
ext = os.path.splitext(file.filename or "")[-1].lower()
|
||||
if ext not in ALLOWED_EXT:
|
||||
raise HTTPException(status_code=400, detail="Format non supporté")
|
||||
filename = f"{uuid.uuid4().hex}{ext}"
|
||||
dest = os.path.join(UPLOAD_DIR, filename)
|
||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||
content = await file.read()
|
||||
with open(dest, "wb") as f:
|
||||
f.write(content)
|
||||
return {"filename": filename, "url": f"/uploads/{filename}"}
|
||||
|
||||
|
||||
@router.delete("/upload/{filename}", status_code=204)
|
||||
def delete_file(filename: str):
|
||||
path = os.path.join(UPLOAD_DIR, filename)
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
@@ -1,2 +1,39 @@
|
||||
from fastapi import APIRouter
|
||||
router = APIRouter()
|
||||
from datetime import date
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlmodel import Session, select
|
||||
from app.database import get_session
|
||||
from app.models.settings import UserSettings, LunarCalendarEntry
|
||||
|
||||
router = APIRouter(tags=["réglages"])
|
||||
|
||||
|
||||
@router.get("/settings")
|
||||
def get_settings(session: Session = Depends(get_session)):
|
||||
rows = session.exec(select(UserSettings)).all()
|
||||
return {r.cle: r.valeur for r in rows}
|
||||
|
||||
|
||||
@router.put("/settings")
|
||||
def update_settings(data: dict, session: Session = Depends(get_session)):
|
||||
for cle, valeur in data.items():
|
||||
row = session.exec(select(UserSettings).where(UserSettings.cle == cle)).first()
|
||||
if row:
|
||||
row.valeur = str(valeur)
|
||||
else:
|
||||
row = UserSettings(cle=cle, valeur=str(valeur))
|
||||
session.add(row)
|
||||
session.commit()
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.get("/lunar")
|
||||
def get_lunar(month: str, session: Session = Depends(get_session)):
|
||||
year, m = map(int, month.split("-"))
|
||||
first = date(year, m, 1)
|
||||
last_m, last_y = (m + 1, year) if m < 12 else (1, year + 1)
|
||||
last = date(last_y, last_m, 1)
|
||||
return session.exec(
|
||||
select(LunarCalendarEntry)
|
||||
.where(LunarCalendarEntry.jour >= first)
|
||||
.where(LunarCalendarEntry.jour < last)
|
||||
).all()
|
||||
|
||||
@@ -1,2 +1,78 @@
|
||||
from datetime import date
|
||||
from sqlmodel import Session, select
|
||||
from app.database import engine
|
||||
import app.models # noqa
|
||||
|
||||
|
||||
def run_seed():
|
||||
pass
|
||||
from app.models.garden import Garden, GardenCell, Measurement
|
||||
from app.models.plant import PlantVariety
|
||||
from app.models.planting import Planting, PlantingEvent
|
||||
from app.models.task import Task
|
||||
|
||||
with Session(engine) as session:
|
||||
if session.exec(select(Garden)).first():
|
||||
return # déjà seedé
|
||||
|
||||
jardin = Garden(
|
||||
nom="Mon potager",
|
||||
description="Potager principal plein sud",
|
||||
type="plein_air",
|
||||
exposition="S",
|
||||
ombre="plein_soleil",
|
||||
sol_type="limoneux",
|
||||
grille_largeur=6,
|
||||
grille_hauteur=4,
|
||||
)
|
||||
session.add(jardin)
|
||||
session.flush()
|
||||
|
||||
for row in range(4):
|
||||
for col in range(6):
|
||||
session.add(GardenCell(
|
||||
garden_id=jardin.id,
|
||||
col=col, row=row,
|
||||
libelle=f"{chr(65 + row)}{col + 1}",
|
||||
))
|
||||
|
||||
session.add(Measurement(garden_id=jardin.id, temp_air=18.0, humidite_air=65.0))
|
||||
|
||||
tomate = PlantVariety(
|
||||
nom_commun="Tomate", variete="Andine Cornue",
|
||||
famille="Solanacées", type_plante="legume",
|
||||
besoin_eau="fort", espacement_cm=60,
|
||||
plantation_mois="4,5", recolte_mois="7,8,9",
|
||||
)
|
||||
courgette = PlantVariety(
|
||||
nom_commun="Courgette", variete="Verte",
|
||||
famille="Cucurbitacées", type_plante="legume",
|
||||
besoin_eau="moyen", espacement_cm=80,
|
||||
plantation_mois="5,6", recolte_mois="7,8",
|
||||
)
|
||||
salade = PlantVariety(
|
||||
nom_commun="Laitue", variete="Batavia",
|
||||
famille="Astéracées", type_plante="legume",
|
||||
besoin_eau="moyen", espacement_cm=25,
|
||||
)
|
||||
session.add_all([tomate, courgette, salade])
|
||||
session.flush()
|
||||
|
||||
p1 = Planting(
|
||||
garden_id=jardin.id, variety_id=tomate.id,
|
||||
date_plantation=date(2026, 5, 1), quantite=6, statut="en_cours",
|
||||
)
|
||||
p2 = Planting(
|
||||
garden_id=jardin.id, variety_id=courgette.id,
|
||||
date_plantation=date(2026, 5, 15), quantite=3, statut="prevu",
|
||||
)
|
||||
session.add_all([p1, p2])
|
||||
session.flush()
|
||||
|
||||
session.add(PlantingEvent(planting_id=p1.id, type="arrosage", note="Arrosage du matin"))
|
||||
|
||||
session.add(Task(titre="Arroser les tomates", priorite="haute",
|
||||
statut="a_faire", garden_id=jardin.id))
|
||||
session.add(Task(titre="Traiter contre les pucerons", priorite="normale", statut="a_faire"))
|
||||
session.add(Task(titre="Préparer le compost", priorite="basse", statut="en_cours"))
|
||||
|
||||
session.commit()
|
||||
|
||||
Reference in New Issue
Block a user