commit
This commit is contained in:
96
backend/app/api/endpoints/projects.py
Normal file
96
backend/app/api/endpoints/projects.py
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import selectinload
|
||||
from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
from app.db.session import get_db
|
||||
from app.models.project import Project as ProjectModel
|
||||
from app.models.scene import Scene as SceneModel
|
||||
from app.models.shot import Shot as ShotModel
|
||||
from app.schemas.project import Project, ProjectCreate
|
||||
from app.schemas.script import ScriptAnalysisResponse
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.post("/", response_model=Project)
|
||||
async def create_project(
|
||||
project_in: ProjectCreate,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
project = ProjectModel(**project_in.model_dump())
|
||||
db.add(project)
|
||||
await db.commit()
|
||||
await db.refresh(project)
|
||||
return project
|
||||
|
||||
@router.get("/", response_model=List[Project])
|
||||
async def list_projects(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
result = await db.execute(select(ProjectModel).offset(skip).limit(limit))
|
||||
return result.scalars().all()
|
||||
|
||||
@router.post("/{project_id}/import-script")
|
||||
async def import_script(
|
||||
project_id: UUID,
|
||||
script_data: ScriptAnalysisResponse,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
# Verify project exists
|
||||
project = await db.get(ProjectModel, project_id)
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
|
||||
# Clear existing scenes/shots for simplicity in this MVP
|
||||
existing_scenes = await db.execute(select(SceneModel).where(SceneModel.project_id == project_id))
|
||||
for scene in existing_scenes.scalars():
|
||||
await db.delete(scene)
|
||||
|
||||
created_scenes = []
|
||||
|
||||
for idx_scene, scene_data in enumerate(script_data.scenes):
|
||||
scene_db = SceneModel(
|
||||
project_id=project_id,
|
||||
slugline=scene_data.heading,
|
||||
raw_content=scene_data.description,
|
||||
sequence_number=idx_scene + 1,
|
||||
)
|
||||
db.add(scene_db)
|
||||
await db.flush() # get ID
|
||||
|
||||
for idx_shot, shot_data in enumerate(scene_data.shots):
|
||||
shot_db = ShotModel(
|
||||
scene_id=scene_db.id,
|
||||
description=shot_data.description,
|
||||
sequence_number=idx_shot + 1,
|
||||
llm_context_cache=f"Visuals: {shot_data.visual_notes or 'None'}\nDialogue: {shot_data.dialogue or 'None'}",
|
||||
status="draft"
|
||||
)
|
||||
db.add(shot_db)
|
||||
|
||||
created_scenes.append(scene_db)
|
||||
|
||||
await db.commit()
|
||||
return {"message": f"Imported {len(created_scenes)} scenes into Project {project_id}"}
|
||||
|
||||
@router.get("/{project_id}/script")
|
||||
async def get_project_script(
|
||||
project_id: UUID,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
# Fetch Project with Scenes and Shots
|
||||
stmt = (
|
||||
select(SceneModel)
|
||||
.options(selectinload(SceneModel.shots))
|
||||
.where(SceneModel.project_id == project_id)
|
||||
.order_by(SceneModel.sequence_number)
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
scenes = result.scalars().all()
|
||||
|
||||
return {"scenes": scenes}
|
||||
Reference in New Issue
Block a user