"""河图世界 API(/worlds):境界 CRUD、实体关系、正史视图。""" from fastapi import APIRouter, Depends, status from pydantic import BaseModel, Field from app.api.v1.deps import get_current_user from app.domains.hetu import service from app.schemas.auth import CurrentUser world_router = APIRouter(prefix="/worlds", tags=["hetu"]) class CreateWorldRequest(BaseModel): name: str = Field(min_length=1, max_length=120) description: str = "" rules: dict = Field(default_factory=dict) lorebook_id: str | None = None class UpdateWorldRequest(BaseModel): name: str | None = None description: str | None = None rules: dict | None = None lorebook_id: str | None = None class EntityRequest(BaseModel): kind: str = "concept" name: str = Field(min_length=1, max_length=120) description: str = "" attrs: dict = Field(default_factory=dict) class RelationRequest(BaseModel): source_entity_id: str target_entity_id: str relation: str = Field(min_length=1, max_length=80) note: str = "" @world_router.post("", status_code=status.HTTP_201_CREATED) async def create_world( payload: CreateWorldRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.create_world( owner_scope=user.owner_scope, name=payload.name, description=payload.description, rules=payload.rules, lorebook_id=payload.lorebook_id, ) @world_router.get("") async def list_worlds(user: CurrentUser = Depends(get_current_user)) -> list[dict]: return await service.list_worlds(user.owner_scope) @world_router.get("/{world_id}") async def get_world(world_id: str, user: CurrentUser = Depends(get_current_user)) -> dict: return await service.get_world(world_id, user.owner_scope) @world_router.patch("/{world_id}") async def update_world( world_id: str, payload: UpdateWorldRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.update_world( world_id, user.owner_scope, name=payload.name, description=payload.description, rules=payload.rules, lorebook_id=payload.lorebook_id, ) @world_router.delete("/{world_id}") async def archive_world(world_id: str, user: CurrentUser = Depends(get_current_user)) -> dict: return await service.archive_world(world_id, user.owner_scope) @world_router.post("/{world_id}/entities", status_code=status.HTTP_201_CREATED) async def add_entity( world_id: str, payload: EntityRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.add_entity( world_id, user.owner_scope, kind=payload.kind, name=payload.name, description=payload.description, attrs=payload.attrs, ) @world_router.get("/{world_id}/entities") async def list_entities(world_id: str, user: CurrentUser = Depends(get_current_user)) -> list[dict]: return await service.list_entities(world_id, user.owner_scope) @world_router.post("/{world_id}/relations", status_code=status.HTTP_201_CREATED) async def add_relation( world_id: str, payload: RelationRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.add_relation( world_id, user.owner_scope, source_entity_id=payload.source_entity_id, target_entity_id=payload.target_entity_id, relation=payload.relation, note=payload.note, ) @world_router.get("/{world_id}/relations") async def list_relations(world_id: str, user: CurrentUser = Depends(get_current_user)) -> list[dict]: return await service.list_relations(world_id, user.owner_scope) @world_router.get("/{world_id}/chronicle") async def world_chronicle(world_id: str, user: CurrentUser = Depends(get_current_user)) -> dict: return await service.world_chronicle(world_id, user.owner_scope)