import uuid from fastapi import APIRouter, status from app.api.deps import CurrentUser, SessionDep from app.schemas.name import NameCreate, NameRead, NameUpdate from app.services import name_service, tree_service # Names are nested under their person (which is nested under the tree tenant). router = APIRouter(prefix="/trees", tags=["names"]) @router.get("/{tree_id}/persons/{person_id}/names", response_model=list[NameRead]) async def list_names( tree_id: uuid.UUID, person_id: uuid.UUID, session: SessionDep, current: CurrentUser ) -> list[NameRead]: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) names = await name_service.list_names( session, viewer_id=current.id, tree=tree, person_id=person_id ) return [NameRead.model_validate(n) for n in names] @router.post( "/{tree_id}/persons/{person_id}/names", response_model=NameRead, status_code=status.HTTP_201_CREATED, ) async def create_name( tree_id: uuid.UUID, person_id: uuid.UUID, data: NameCreate, session: SessionDep, current: CurrentUser, ) -> NameRead: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) name = await name_service.create_name( session, actor=current, tree=tree, person_id=person_id, name_type=data.name_type, given=data.given, surname=data.surname, prefix=data.prefix, suffix=data.suffix, nickname=data.nickname, is_primary=data.is_primary, ) return NameRead.model_validate(name) @router.patch( "/{tree_id}/persons/{person_id}/names/{name_id}", response_model=NameRead ) async def update_name( tree_id: uuid.UUID, person_id: uuid.UUID, name_id: uuid.UUID, data: NameUpdate, session: SessionDep, current: CurrentUser, ) -> NameRead: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) name = await name_service.update_name( session, actor=current, tree=tree, person_id=person_id, name_id=name_id, changes=data.model_dump(exclude_unset=True), ) return NameRead.model_validate(name) @router.delete( "/{tree_id}/persons/{person_id}/names/{name_id}", status_code=status.HTTP_204_NO_CONTENT, ) async def delete_name( tree_id: uuid.UUID, person_id: uuid.UUID, name_id: uuid.UUID, session: SessionDep, current: CurrentUser, ) -> None: tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id) await name_service.delete_name( session, actor=current, tree=tree, person_id=person_id, name_id=name_id )