96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
"""世界模型 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)
|