o2o-negosium-original/negodata/backend/router/v1/quotation_setting/protocol.py
Mina Choi e23349c11e [feat] negodata: 마감 close_reason 개편 + 견적상세 단가조정 스펙트럼
- 마감사유 quotations.close_reason(SMALLINT, 8종) 신설 — 낙찰/재협상3종/유찰4종 구분, 재생성 한도 카운팅. quotation_settings 에 mid_action·over_action·regen_limit(3구간 가격정책) 추가. models.py·enums.py·01-schema.sql·crud·service·테스트 정합.
- 프론트 노출: CloseReason/PriceGateAction 라벨·배지, 목록 마감결과 컬럼, 견적세팅 모달 3구간. orval 생성모델 갱신.
- 견적상세 결과밴드: 목표가→낙찰가→절감 stat 트리오를 단가조정 흐름 스펙트럼(목표가·최저·최고 투찰가)으로 교체. lowestBid/highestBid 는 bid_price 파생(DB 컬럼 아님), 최초가 컬럼 없어 시작앵커=최고 투찰가로 대체. 라벨 방향 값순 번갈아 배치로 겹침 방지.
- 라벨 정정: "단독 낙찰"→"낙찰"(낙찰은 단수), "목표 대비"→"목표가 대비".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 08:37:40 +09:00

59 lines
1.8 KiB
Python

import uuid
from datetime import datetime
from typing import Optional
from pydantic import ConfigDict
from common.enums import PriceGateAction
from common.models.gmodel import Res_WebPacketProtocol, WebPacketProtocol
class QuotationSettingProtocol(WebPacketProtocol):
pass
class Req_CreateQuotationSetting(QuotationSettingProtocol):
target_margin_rate: float
anchoring_value: float = 0.01
card_count: int = 3
mid_action: PriceGateAction = PriceGateAction.AWARD # 앵커링가<투찰가≤목표가 마감 처리
over_action: PriceGateAction = PriceGateAction.AWARD # 목표가<투찰가 마감 처리
regen_limit: int = 1 # 재생성 최대 횟수(체인 전체, 사유 무관)
class Req_UpdateQuotationSetting(QuotationSettingProtocol):
target_margin_rate: Optional[float] = None
anchoring_value: Optional[float] = None
card_count: Optional[int] = None
mid_action: Optional[PriceGateAction] = None
over_action: Optional[PriceGateAction] = None
regen_limit: Optional[int] = None
class QuotationSettingData(WebPacketProtocol):
model_config = ConfigDict(from_attributes=True)
qt_setting_id: uuid.UUID
user_id: Optional[uuid.UUID] = None
target_margin_rate: float
anchoring_value: float
card_count: int
mid_action: PriceGateAction = PriceGateAction.AWARD
over_action: PriceGateAction = PriceGateAction.AWARD
regen_limit: int = 1
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
class Res_QuotationSetting(Res_WebPacketProtocol):
setting: Optional[QuotationSettingData] = None
class Res_QuotationSettingList(Res_WebPacketProtocol):
settings: list[QuotationSettingData] = []
total: int = 0
class Res_DeleteQuotationSetting(Res_WebPacketProtocol):
pass