o2o-negosium-original/backend/router/v1/auth/protocol.py
Mina Choi 71ef28110b [feat] negodata·agent·negosium: 협상 기준가 회사별 선택(공급가/매입가) + 공급사 포털 안내 회사설정화
어느 가격이 "공급사에 지불하는 단가"인지는 회사마다 달라, 컬럼을 합치는 대신 회사가 고르게 했다.
판정은 settings.features.nego_baseline_field 1순위, 미설정 회사는 price 만 숨겼으면 purchase_price 폴백.
판정식 정본은 negodata/backend/common/nego_baseline.py (agent·negosium backend 가 같은 규칙 미러).

- negodata front: 회사 설정에 협상 기준가 라디오(선택지마다 실제 나갈 문장 미리보기 + 학습 경고),
  '공급사 포털 안내' 탭 신설(협상 유의사항·헬프데스크 연락처), 용어 카탈로그에 target_price·supplier 추가.
  인터넷 최저가는 숨김 대상에서 제외(신규 견적의 유일한 목표가 후보).
  상품 등록 기본값에서 개발용 더미 제거(price 1,000,000·PROD-BAT-###·800,000·대한민국·10 EA·14).
- agent: get_item_price → get_item_baseline (기준가·호칭·회사 용어사전을 한 쿼리로),
  "기존 공급가 대비" 하드코딩을 회사 용어로 치환 + 받침 기준 조사 자동 보정,
  협상 스크립트 4종의 협력사·목표가·배송형태 용어를 {label_*} 토큰화, input_options 도 변수 치환 적용.
- negosium: 협상 화면 기준 단가·배송형태 라벨을 회사 설정 기준으로, 유의사항 본문과 헬프데스크 연락처를
  하드코딩에서 회사 설정으로(미등록 시 영역 숨김). 유의사항의 VAT·배송비 문구 삭제(IMK 0803 ⑥).
- negodata backend: LPS 검색 가격 힌트를 items.price 고정에서 기준가 규칙으로.

검증: 기준가 설정 3 × 숨김 4 = 12조합에서 협상 멘트·포털 표시·LPS 힌트가 전부 일치.
agent 테스트 176건 통과. 보고서 negodata/docs/nego-baseline-verification.md
2026-08-05 11:47:06 +09:00

77 lines
3.6 KiB
Python

from pydantic import Field
from common.models.gmodel import Res_WebPacketProtocol, WebPacketProtocol
# 라우터 폴더마다 protocol.py 를 두고 Req_/Res_ 를 정의한다 (protocol 규약).
class AuthProtocol(WebPacketProtocol):
pass
class Req_Login(AuthProtocol):
id: str = Field("", description="로그인 ID")
pw: str = Field("", description="비밀번호(평문, 서버에서 bcrypt 해시·검증)")
class Res_Login(Res_WebPacketProtocol):
su_id: str = Field("", description="유저 식별자(uuid)")
name: str = Field("", description="유저 개인 이름")
supplier_id: str = Field("", description="소속 공급사 uuid(partner.suppliers)")
supplier_name: str = Field("", description="공급사명")
role: int = Field(0, description="권한 코드 1=user, 2=manager (UserRole)")
access_token: str = Field("", description="액세스 토큰(JWT)")
refresh_token: str = Field("", description="리프레시 토큰(JWT)")
class Req_CreateAccount(AuthProtocol):
supplier_id: str = Field("", max_length=36, description="소속 공급사 uuid(partner.suppliers.supplier_id)")
id: str = Field("", max_length=20, description="로그인 ID")
pw: str = Field("", description="비밀번호(평문, 서버에서 bcrypt 해시)")
name: str = Field("", max_length=50, description="이름")
email: str = Field("", max_length=255, description="이메일")
contact_number: str = Field("", max_length=20, description="연락처")
role: int = Field(1, description="권한 코드 1=user, 2=manager (UserRole)")
class Res_CreateAccount(Res_WebPacketProtocol):
su_id: str = Field("", description="생성된 유저 식별자(uuid)")
class Res_RefreshToken(Res_WebPacketProtocol):
access_token: str = Field("", description="재발급된 액세스 토큰(JWT)")
class Res_Me(Res_WebPacketProtocol):
su_id: str = Field("", description="유저 식별자(uuid)")
id: str = Field("", description="로그인 ID")
name: str = Field("", description="유저 개인 이름")
supplier_id: str = Field("", description="소속 공급사 uuid")
supplier_name: str = Field("", description="공급사명")
role: int = Field(0, description="권한 코드 1=user, 2=manager (UserRole)")
branding: dict = Field(default_factory=dict, description="소속 회사 브랜딩(companies.settings.branding). 서비스명/로고/색")
session_fields: list = Field(default_factory=list, description="협상완료 부가정보 필드 정의(companies.settings.session_fields). 공급사가 타결 후 입력")
guide_notices: list = Field(default_factory=list, description="협상 유의사항 항목(companies.settings.guide_notices). 빈 값이면 포털 기본 문구")
class Res_Logout(Res_WebPacketProtocol):
pass
class Res_PopupStatus(Res_WebPacketProtocol):
service_info: bool = Field(False, description="협상 유의사항(서비스 안내) 팝업 '안내 보지 않기' 여부")
class Req_HidePopup(AuthProtocol):
popup_type: str = Field("", description="숨길 팝업 종류: service_info")
class Res_HidePopup(Res_WebPacketProtocol):
pass
class Res_SessionBranding(Res_WebPacketProtocol):
service_name: str = Field("", description="회사 서비스명(companies.settings.branding.service_name). 미설정 시 빈 값")
logo_url: str = Field("", description="회사 로고 URL")
primary_color: str = Field("", description="브랜드 색상(hex)")
helpdesk: list = Field(default_factory=list, description="헬프데스크 연락처 줄 목록(companies.settings.branding.helpdesk). 한 줄 = 담당자 한 명")