Files
gartenmanager/backend/app/api/v1/plantings.py

79 lines
2.9 KiB
Python
Raw Normal View History

from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.deps import get_session, get_tenant_context, require_min_role
from app.crud.bed import crud_bed
from app.crud.planting import crud_planting
from app.models.user import TenantRole
from app.schemas.planting import PlantingCreate, PlantingRead, PlantingUpdate
router = APIRouter(tags=["Bepflanzungen"])
TenantCtx = Annotated[tuple, Depends(get_tenant_context)]
WriteCtx = Annotated[tuple, Depends(require_min_role(TenantRole.READ_WRITE))]
async def _get_bed_or_404(db: AsyncSession, bed_id: UUID, tenant_id: UUID):
bed = await crud_bed.get(db, id=bed_id)
if not bed or bed.tenant_id != tenant_id:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Beet nicht gefunden.")
return bed
@router.get("/beds/{bed_id}/plantings", response_model=list[PlantingRead])
async def list_plantings(
bed_id: UUID,
db: Annotated[AsyncSession, Depends(get_session)],
ctx: TenantCtx,
) -> list[PlantingRead]:
_, tenant_id = ctx
await _get_bed_or_404(db, bed_id, tenant_id)
plantings = await crud_planting.get_multi_for_bed(db, bed_id=bed_id)
return [PlantingRead.model_validate(p) for p in plantings]
@router.post("/beds/{bed_id}/plantings", response_model=PlantingRead, status_code=status.HTTP_201_CREATED)
async def create_planting(
bed_id: UUID,
body: PlantingCreate,
db: Annotated[AsyncSession, Depends(get_session)],
ctx: WriteCtx,
) -> PlantingRead:
_, tenant_id, _ = ctx
await _get_bed_or_404(db, bed_id, tenant_id)
planting = await crud_planting.create_for_bed(db, obj_in=body, bed_id=bed_id)
return PlantingRead.model_validate(planting)
@router.put("/plantings/{planting_id}", response_model=PlantingRead)
async def update_planting(
planting_id: UUID,
body: PlantingUpdate,
db: Annotated[AsyncSession, Depends(get_session)],
ctx: WriteCtx,
) -> PlantingRead:
_, tenant_id, _ = ctx
planting = await crud_planting.get(db, id=planting_id)
if not planting:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bepflanzung nicht gefunden.")
await _get_bed_or_404(db, planting.bed_id, tenant_id)
updated = await crud_planting.update(db, db_obj=planting, obj_in=body)
return PlantingRead.model_validate(updated)
@router.delete("/plantings/{planting_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_planting(
planting_id: UUID,
db: Annotated[AsyncSession, Depends(get_session)],
ctx: WriteCtx,
) -> None:
_, tenant_id, _ = ctx
planting = await crud_planting.get(db, id=planting_id)
if not planting:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Bepflanzung nicht gefunden.")
await _get_bed_or_404(db, planting.bed_id, tenant_id)
await crud_planting.remove(db, id=planting_id)