import uuid from datetime import datetime from typing import Any, Optional from pydantic import ConfigDict from common.enums import CardStatus, CardUsageType from common.models.gmodel import Res_PageProtocol, Res_WebPacketProtocol, WebPacketProtocol class CardProtocol(WebPacketProtocol): pass class Req_CreateCard(CardProtocol): is_wildcard: bool = False is_shared: bool = False # True(전체 공용 등록)는 거부된다 — 공용 카드는 DB 시드로만 관리. 항상 False 로 보낼 것 name: Optional[str] = None number: Optional[str] = None script: Optional[str] = None edit_script: Optional[Any] = None usage_type: int = CardUsageType.COMMON.value # 카드 적용 견적 구분(CardUsageType): 1=공통 2=신규견적전용 3=재견적전용 status: int = CardStatus.ACTIVE.value # 와일드카드 적용 여부(available 매핑). 일반카드는 무시. condition: Optional[str] = None # 와일드카드 전용 memo: Optional[str] = None # 와일드카드 전용 tactic: Optional[Any] = None # 전술 운영 규칙 {"min_round": N, "closing": bool}. 제안가는 script 변수 파싱(agent) class Req_UpdateCard(CardProtocol): name: Optional[str] = None number: Optional[str] = None script: Optional[str] = None edit_script: Optional[Any] = None usage_type: Optional[int] = None # 카드 적용 견적 구분(CardUsageType): 1=공통 2=신규견적전용 3=재견적전용 status: Optional[int] = None condition: Optional[str] = None memo: Optional[str] = None tactic: Optional[Any] = None # 전술 운영 규칙 {"min_round": N, "closing": bool} # 통합 카드 표현(nego_cards + wild_cards 공통). class CardData(WebPacketProtocol): model_config = ConfigDict(from_attributes=True) nego_card_id: uuid.UUID # 통합 식별자(일반=nego_card_id / 와일드=wild_card_id) user_id: Optional[uuid.UUID] = None is_wildcard: bool = False is_shared: bool = False # 전체(공용) 카드 여부 = user_id NULL. 목록 배지/폼 스코프 표시용 creator_name: Optional[str] = None # 작성자(등록자) 이름. user_id→company.users.name 조인. 공용 카드는 None name: Optional[str] = None number: Optional[str] = None script: Optional[str] = None edit_script: Optional[Any] = None usage_type: CardUsageType = CardUsageType.COMMON # 카드 적용 견적 구분: 1=공통 2=신규견적전용 3=재견적전용 status: CardStatus = CardStatus.ACTIVE condition: Optional[str] = None memo: Optional[str] = None tactic: Optional[Any] = None # 전술 운영 규칙 {"min_round": N, "closing": bool} created_at: Optional[datetime] = None updated_at: Optional[datetime] = None success_rate: float = 0.0 # 카드 성공률(사용 세션 중 타결 비율). #12 순위용 used_count: int = 0 # 카드 사용 세션 수(표본) class Res_Card(Res_WebPacketProtocol): card: Optional[CardData] = None class Res_CardList(Res_PageProtocol): cards: list[CardData] = [] total_nego: int = 0 # 협상카드 탭 카운트(검색 필터 반영) total_wild: int = 0 # 와일드카드 탭 카운트(검색 필터 반영) class Res_DeleteCard(Res_WebPacketProtocol): pass