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.models.user import TenantRole from app.schemas.bed import BedCreate, BedDetailRead, BedRead, BedUpdate router = APIRouter(prefix="/beds", tags=["Beete"]) TenantCtx = Annotated[tuple, Depends(get_tenant_context)] WriteCtx = Annotated[tuple, Depends(require_min_role(TenantRole.READ_WRITE))] AdminCtx = Annotated[tuple, Depends(require_min_role(TenantRole.TENANT_ADMIN))] @router.get("", response_model=list[BedRead]) async def list_beds( db: Annotated[AsyncSession, Depends(get_session)], ctx: TenantCtx, ) -> list[BedRead]: _, tenant_id = ctx beds = await crud_bed.get_multi_for_tenant(db, tenant_id=tenant_id) return [BedRead.model_validate(b) for b in beds] @router.get("/{bed_id}", response_model=BedDetailRead) async def get_bed( bed_id: UUID, db: Annotated[AsyncSession, Depends(get_session)], ctx: TenantCtx, ) -> BedDetailRead: _, tenant_id = ctx bed = await crud_bed.get_with_plantings(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 BedDetailRead.model_validate(bed) @router.post("", response_model=BedRead, status_code=status.HTTP_201_CREATED) async def create_bed( body: BedCreate, db: Annotated[AsyncSession, Depends(get_session)], ctx: WriteCtx, ) -> BedRead: _, tenant_id, _ = ctx bed = await crud_bed.create_for_tenant(db, obj_in=body, tenant_id=tenant_id) return BedRead.model_validate(bed) @router.put("/{bed_id}", response_model=BedRead) async def update_bed( bed_id: UUID, body: BedUpdate, db: Annotated[AsyncSession, Depends(get_session)], ctx: WriteCtx, ) -> BedRead: _, tenant_id, _ = ctx 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.") updated = await crud_bed.update(db, db_obj=bed, obj_in=body) return BedRead.model_validate(updated) @router.delete("/{bed_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_bed( bed_id: UUID, db: Annotated[AsyncSession, Depends(get_session)], ctx: AdminCtx, ) -> None: _, tenant_id, _ = ctx 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.") await crud_bed.remove(db, id=bed_id)