o2o-negosium-original/agent/router/v1/card/card.py

52 lines
2.3 KiB
Python

"""카드 매핑 API (card-update / card-search, tenant 스코프).
PoC: action_id ↔ card_id 매핑을 learning.tenant_action_cards 에 둔다(config 기본 + DB override).
카드 스크립트 본문은 ScriptRepository(tenants/<id>/resources)가 담당 — 여기선 매핑만.
"""
from typing import Optional
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from common.enums import ErrorType
from negotiation.qtable.infra.repository.learning_repository import LearningRepository
from router.deps import get_tenant_engine
from tenancy.registry import TenantEngine
router = APIRouter(prefix="/v1", tags=["Card"], responses={404: {"description": "Not found"}})
async def _merged_mapping(engine: TenantEngine) -> dict:
"""config 기본 매핑 위에 DB override 를 얹은 action→card 최종 매핑."""
mapping = {int(a): c for a, c in engine.config.action_mapping.action_to_card.items()}
overrides = await LearningRepository(engine.company_id).get_action_cards()
for o in overrides:
mapping[o["action_id"]] = o["card_id"]
return mapping
class CardUpdateReq(BaseModel):
action_id: int
card_id: str
@router.post("/card-update", summary="카드 매핑 갱신(action→card)")
async def card_update(req: CardUpdateReq, engine: TenantEngine = Depends(get_tenant_engine)):
if not (0 <= req.action_id < engine.action_space_size):
return {"success": False, "desc": "action_id out of range",
"action_space_size": engine.action_space_size}
err = await LearningRepository(engine.company_id).upsert_action_card(req.action_id, req.card_id)
return {"success": err == ErrorType.SUCCESS, "company_id": engine.company_id,
"action_id": req.action_id, "card_id": req.card_id, "desc": err.name}
@router.get("/card-search", summary="카드 검색(전체 매핑 또는 card_id 조회)")
async def card_search(card_id: Optional[str] = None, engine: TenantEngine = Depends(get_tenant_engine)):
mapping = await _merged_mapping(engine)
if card_id:
hits = [a for a, c in mapping.items() if c == card_id]
return {"company_id": engine.company_id, "card_id": card_id, "action_ids": hits, "found": bool(hits)}
return {"company_id": engine.company_id,
"mapping": [{"action_id": a, "card_id": c} for a, c in sorted(mapping.items())]}