from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.models.user import User from app.models.project import Project from app.models.episode import Episode from app.schemas.episode import EpisodeCreate, EpisodeResponse from app.services.auth import get_current_user router = APIRouter(prefix="/api/projects/{project_id}/episodes", tags=["episodes"]) async def _get_user_project(project_id: int, user: User, db: AsyncSession) -> Project: result = await db.execute( select(Project).where(Project.id == project_id, Project.user_id == user.id) ) project = result.scalar_one_or_none() if not project: raise HTTPException(status_code=404, detail="Project not found") return project @router.get("", response_model=list[EpisodeResponse]) async def list_episodes( project_id: int, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_user_project(project_id, user, db) result = await db.execute( select(Episode) .where(Episode.project_id == project_id) .order_by(Episode.episode_number) ) return list(result.scalars().all()) @router.post("", response_model=EpisodeResponse, status_code=201) async def create_episode( project_id: int, data: EpisodeCreate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_user_project(project_id, user, db) episode = Episode(project_id=project_id, **data.model_dump(exclude_none=True)) db.add(episode) await db.commit() await db.refresh(episode) return episode @router.get("/{episode_id}", response_model=EpisodeResponse) async def get_episode( project_id: int, episode_id: int, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): await _get_user_project(project_id, user, db) result = await db.execute( select(Episode).where(Episode.id == episode_id, Episode.project_id == project_id) ) episode = result.scalar_one_or_none() if not episode: raise HTTPException(status_code=404, detail="Episode not found") return episode