- 백엔드: quotation 목록 search 파라미터(name/number ILIKE) 추가; card 목록 is_wildcard 탭 필터 + total_nego/total_wild 탭 카운트 추가; status/type 코드 int 비교 보정 - 프론트: cards/quotation 검색·상태·유형 필터·페이지네이션을 useServerList 기반 서버사이드로 전환; 엔터 즉시검색 + 디바운스 500ms·최소 2글자; 죽은 client 필터 훅(useCardFilters/useQuotationFilters) 제거 - generated 파라미터/응답 타입 손보강(listCardsParams.is_wildcard, listQuotationsParams.search, resCardList.total_nego/total_wild) — orval 재생성 시 동일 - 견적 상세 Drawer→Sheet 분리, useOverlayParams→useOverlayRouter, CreateQuotationWizard→QuotationCreateModal Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from typing import Any, Optional
|
|
|
|
from pydantic import ConfigDict
|
|
|
|
from common.enums import CardStatus
|
|
from common.models.gmodel import Res_PageProtocol, Res_WebPacketProtocol, WebPacketProtocol
|
|
|
|
|
|
class CardProtocol(WebPacketProtocol):
|
|
pass
|
|
|
|
|
|
class Req_CreateCard(CardProtocol):
|
|
is_wildcard: bool = False
|
|
name: Optional[str] = None
|
|
number: Optional[str] = None
|
|
script: Optional[str] = None
|
|
edit_script: Optional[Any] = None
|
|
status: int = CardStatus.ACTIVE.value # 와일드카드 적용 여부(available 매핑). 일반카드는 무시.
|
|
condition: Optional[str] = None # 와일드카드 전용
|
|
memo: Optional[str] = None # 와일드카드 전용
|
|
|
|
|
|
class Req_UpdateCard(CardProtocol):
|
|
name: Optional[str] = None
|
|
number: Optional[str] = None
|
|
script: Optional[str] = None
|
|
edit_script: Optional[Any] = None
|
|
status: Optional[int] = None
|
|
condition: Optional[str] = None
|
|
memo: Optional[str] = None
|
|
|
|
|
|
# 통합 카드 표현(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
|
|
name: Optional[str] = None
|
|
number: Optional[str] = None
|
|
script: Optional[str] = None
|
|
edit_script: Optional[Any] = None
|
|
status: int = CardStatus.ACTIVE.value
|
|
condition: Optional[str] = None
|
|
memo: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
|
|
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
|