import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from rehearsalhub.db.engine import get_session from rehearsalhub.db.models import Member from rehearsalhub.dependencies import get_current_member from rehearsalhub.schemas.band import BandCreate, BandRead, BandReadWithMembers, BandUpdate from rehearsalhub.repositories.band import BandRepository from rehearsalhub.services.band import BandService router = APIRouter(prefix="/bands", tags=["bands"]) @router.get("", response_model=list[BandRead]) async def list_bands( session: AsyncSession = Depends(get_session), current_member: Member = Depends(get_current_member), ): repo = BandRepository(session) bands = await repo.list_for_member(current_member.id) return [BandRead.model_validate(b) for b in bands] @router.post("", response_model=BandRead, status_code=status.HTTP_201_CREATED) async def create_band( data: BandCreate, session: AsyncSession = Depends(get_session), current_member: Member = Depends(get_current_member), ): svc = BandService(session) try: band = await svc.create_band(data, current_member.id, creator=current_member) except ValueError as e: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e)) except LookupError as e: raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e)) return BandRead.model_validate(band) @router.get("/{band_id}", response_model=BandReadWithMembers) async def get_band( band_id: uuid.UUID, session: AsyncSession = Depends(get_session), current_member: Member = Depends(get_current_member), ): svc = BandService(session) try: await svc.assert_membership(band_id, current_member.id) except PermissionError: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Not a member") band = await svc.get_band_with_members(band_id) if band is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Band not found") return BandReadWithMembers.model_validate(band) @router.patch("/{band_id}", response_model=BandRead) async def update_band( band_id: uuid.UUID, data: BandUpdate, session: AsyncSession = Depends(get_session), current_member: Member = Depends(get_current_member), ): repo = BandRepository(session) role = await repo.get_member_role(band_id, current_member.id) if role != "admin": raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin only") band = await repo.get_by_id(band_id) if band is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Band not found") updates: dict = {} if data.nc_folder_path is not None: path = data.nc_folder_path.strip() updates["nc_folder_path"] = (path.rstrip("/") + "/") if path else None if updates: band = await repo.update(band, **updates) return BandRead.model_validate(band)