import uuid from fastapi import APIRouter, status from app.api.deps import CurrentUser, SessionDep from app.schemas.source import SourceCreate, SourceRead, SourceUpdate from app.services import source_service, tree_service router = APIRouter(prefix="/trees", tags=["sources"]) @router.post("/{tree_id}/sources", response_model=SourceRead, status_code=status.HTTP_201_CREATED) async def create_source( tree_id: uuid.UUID, data: SourceCreate, session: SessionDep, current: CurrentUser ) -> SourceRead: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) source = await source_service.create_source( session, actor=current, tree=tree, **data.model_dump() ) return SourceRead.model_validate(source) @router.get("/{tree_id}/sources", response_model=list[SourceRead]) async def list_sources( tree_id: uuid.UUID, session: SessionDep, current: CurrentUser ) -> list[SourceRead]: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) sources = await source_service.list_sources(session, viewer_id=current.id, tree=tree) return [SourceRead.model_validate(s) for s in sources] @router.get("/{tree_id}/sources/{source_id}", response_model=SourceRead) async def get_source( tree_id: uuid.UUID, source_id: uuid.UUID, session: SessionDep, current: CurrentUser ) -> SourceRead: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) source = await source_service.get_source( session, viewer_id=current.id, tree=tree, source_id=source_id ) return SourceRead.model_validate(source) @router.patch("/{tree_id}/sources/{source_id}", response_model=SourceRead) async def update_source( tree_id: uuid.UUID, source_id: uuid.UUID, data: SourceUpdate, session: SessionDep, current: CurrentUser, ) -> SourceRead: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) source = await source_service.update_source( session, actor=current, tree=tree, source_id=source_id, changes=data.model_dump(exclude_unset=True), ) return SourceRead.model_validate(source) @router.delete("/{tree_id}/sources/{source_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_source( tree_id: uuid.UUID, source_id: uuid.UUID, session: SessionDep, current: CurrentUser ) -> None: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) await source_service.delete_source(session, actor=current, tree=tree, source_id=source_id)