"""叩心 API:候选生成、约束裁决与派发。""" from fastapi import APIRouter, Depends from pydantic import BaseModel, Field from app.api.v1.deps import get_current_user from app.domains.kouxin import service from app.schemas.auth import CurrentUser knock_router = APIRouter(prefix="/knocking", tags=["kouxin"]) class CandidateCreateRequest(BaseModel): character_id: str trigger: str = "manual" draft: str = Field(min_length=1, max_length=2000) class DispatchRequest(BaseModel): draft_override: str | None = None @knock_router.post("/candidates", status_code=201) async def create_candidate_api( payload: CandidateCreateRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.create_candidate( character_id=payload.character_id, owner_scope=user.owner_scope, trigger=payload.trigger, draft=payload.draft, ) @knock_router.get("/candidates") async def list_candidates_api( user: CurrentUser = Depends(get_current_user) ) -> list[dict]: return await service.list_candidates(user.owner_scope) @knock_router.get("/ruling/{character_id}") async def ruling_api( character_id: str, user: CurrentUser = Depends(get_current_user) ) -> dict: """约束裁决预检(总开关/静默/频率/预算)。""" return await service.rule(character_id, user.owner_scope) @knock_router.post("/candidates/{candidate_id}/dispatch") async def dispatch_api( candidate_id: str, payload: DispatchRequest, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.dispatch( candidate_id, user.owner_scope, draft_override=payload.draft_override ) @knock_router.post("/candidates/{candidate_id}/dismiss") async def dismiss_api( candidate_id: str, user: CurrentUser = Depends(get_current_user) ) -> dict: return await service.dismiss(candidate_id, user.owner_scope)