"""世界模型 API(河图枢运行时,api-spec §12)。""" from fastapi import APIRouter, Depends, Query from app.api.v1.deps import get_current_user from app.schemas.auth import CurrentUser from app.schemas.common import Page from app.schemas.world import ( WorldEntityCreateRequest, WorldEntityResponse, WorldGraphResponse, WorldRelationCreateRequest, WorldRelationResponse, ) from app.services.world import ( create_entity, create_relation, delete_relation, get_entity_by_id, get_graph, list_entities_page, list_relations_page, ) router = APIRouter(prefix="/world", tags=["world"]) @router.get("/entities", response_model=Page[WorldEntityResponse]) async def list_entities( current_user: CurrentUser = Depends(get_current_user), character_id: str | None = Query(default=None, description="所属人物;省略取当前激活。"), type: str | None = Query(default=None, description="按实体类型过滤(契约字典 §11.1)。"), page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=100), ) -> Page[WorldEntityResponse]: return await list_entities_page( character_id, entity_type=type, page=page, page_size=page_size, owner_scope=current_user.owner_scope, ) @router.post("/entities", response_model=WorldEntityResponse) async def create_entity_api( payload: WorldEntityCreateRequest, current_user: CurrentUser = Depends(get_current_user), ) -> WorldEntityResponse: return await create_entity(payload, owner_scope=current_user.owner_scope) @router.get("/entities/{entity_id}", response_model=WorldEntityResponse) async def get_entity( entity_id: str, current_user: CurrentUser = Depends(get_current_user), ) -> WorldEntityResponse: return await get_entity_by_id(entity_id, owner_scope=current_user.owner_scope) @router.get("/relations", response_model=Page[WorldRelationResponse]) async def list_relations( current_user: CurrentUser = Depends(get_current_user), character_id: str | None = Query(default=None, description="所属人物;省略取当前激活。"), page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=100), ) -> Page[WorldRelationResponse]: return await list_relations_page( character_id, page=page, page_size=page_size, owner_scope=current_user.owner_scope ) @router.post("/relations", response_model=WorldRelationResponse) async def create_relation_api( payload: WorldRelationCreateRequest, current_user: CurrentUser = Depends(get_current_user), ) -> WorldRelationResponse: return await create_relation(payload, owner_scope=current_user.owner_scope) @router.delete("/relations/{relation_id}", status_code=204) async def delete_relation_api( relation_id: str, current_user: CurrentUser = Depends(get_current_user), ) -> None: await delete_relation(relation_id, owner_scope=current_user.owner_scope) @router.get("/graph", response_model=WorldGraphResponse) async def world_graph( current_user: CurrentUser = Depends(get_current_user), character_id: str | None = Query(default=None, description="所属人物;省略取当前激活。"), ) -> WorldGraphResponse: """返回人物的完整世界图谱(无分页),供前端 D3/Force 图谱渲染。""" return await get_graph(character_id, owner_scope=current_user.owner_scope)