o2o-negosium-original/negodata/backend/common/enums.py
Mina Choi eb6612af1c [refactor] negodata: 도메인 코드값 enum 정비 — 백엔드 정본 + 프론트 생성타입 사용
- 백엔드: 도메인 enum CodeEnum 상속(x-enum-varnames) → orval이 이름 있는 enum 생성. 응답 필드 enum 타입 지정(요청은 int 유지). ENUM_LABELS/DOMAIN_ENUMS·/v1/enums 제거
- 프론트: 생성 enum + 라벨맵으로 교체(매직넘버·발명 어휘 제거), 견적·세션 상태 코드화, role/delivery 라벨 프론트 소유
- 동반 정리: unwrap 캐스트·목업(buildSessions·데모)·死코드 제거, mapItem toMinPrice dedupe

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:06:26 +09:00

172 lines
4.8 KiB
Python

from enum import Enum, auto
from fastapi import HTTPException
class CodeEnum(Enum):
"""OpenAPI 스키마에 x-enum-varnames(멤버 이름)을 실어 orval 이 이름 있는 enum 을 생성하게 하는 베이스."""
@classmethod
def __get_pydantic_json_schema__(cls, core_schema, handler):
json_schema = handler(core_schema)
json_schema = handler.resolve_ref_schema(json_schema)
json_schema["x-enum-varnames"] = [m.name for m in cls]
return json_schema
class ErrorType(Enum):
"""서버 전역 결과 코드. Res_WebPacketProtocol.result 에 담겨 클라이언트로 전달된다.
HTTP status 와 겹치지 않도록 구간을 분리해서 관리한다.
"""
SUCCESS = 0
FAIL = 1
# DB / Redis 에러
DB_RUN_FAILED = 10
DB_ALREADY_SAME_KEY = auto()
DB_INVALID_KEY = auto()
DB_EMPTY_DATA = auto()
DB_INVALID_TYPE = auto()
# 요청/직렬화 에러
JSON_PARSE_ERROR = 100
INVALID_REQUEST_DATA = auto()
INTERNAL_EXCEPTION = auto()
# http 에러 코드와 겹치지 않게 설정 - router 전용 예외 발생 옵션
HTTP_INVALID_CLIENT_REQUEST = 419
HTTP_TO_MANY_REQUEST = 429
HTTP_INVALID_CLIENT_ACCESS = 433
HTTP_ACCESS_TOKEN_EXPIRED = 434
HTTP_REFRESH_TOKEN_EXPIRED = 435
HTTP_INVALID_TOKEN_ACCESS = 436
# 계정 관련 에러
ACCOUNT_INVALID_INFO = 1200
ACCOUNT_ALREADY_EXIST = auto()
ACCOUNT_BLOCKED_USER = auto()
# 상품 관련 에러
ITEM_NOT_FOUND = 1300
ITEM_CODE_DUPLICATE = auto()
# 협력사 관련 에러
SUPPLIER_NOT_FOUND = 1400
SUPPLIER_CODE_DUPLICATE = auto()
# 견적 관련 에러
QUOTATION_NOT_FOUND = 1500
# 견적 설정 관련 에러
QUOTATION_SETTING_NOT_FOUND = 1600
# 협상카드 관련 에러
CARD_NOT_FOUND = 1700
# 이미지 업로드 관련 에러
IMAGE_INVALID_TYPE = 1800
IMAGE_TOO_LARGE = auto()
IMAGE_UPLOAD_FAILED = auto()
# ErrorType 의 HTTP_* 값과 status_code 를 맞춰 router 단에서 raise 한다.
EXCEPTION_INVALID_CLIENT_REQUEST = HTTPException(status_code=ErrorType.HTTP_INVALID_CLIENT_REQUEST.value, detail=ErrorType.HTTP_INVALID_CLIENT_REQUEST.name)
EXCEPTION_TO_MANY_REQUEST = HTTPException(status_code=ErrorType.HTTP_TO_MANY_REQUEST.value, detail=ErrorType.HTTP_TO_MANY_REQUEST.name)
EXCEPTION_INVALID_CLIENT_ACCESS = HTTPException(status_code=ErrorType.HTTP_INVALID_CLIENT_ACCESS.value, detail=ErrorType.HTTP_INVALID_CLIENT_ACCESS.name)
EXCEPTION_ACCESS_TOKEN_EXPIRED = HTTPException(status_code=ErrorType.HTTP_ACCESS_TOKEN_EXPIRED.value, detail=ErrorType.HTTP_ACCESS_TOKEN_EXPIRED.name)
EXCEPTION_REFRESH_TOKEN_EXPIRED = HTTPException(status_code=ErrorType.HTTP_REFRESH_TOKEN_EXPIRED.value, detail=ErrorType.HTTP_REFRESH_TOKEN_EXPIRED.name)
EXCEPTION_HTTP_INVALID_TOKEN_ACCESS = HTTPException(status_code=ErrorType.HTTP_INVALID_TOKEN_ACCESS.value, detail=ErrorType.HTTP_INVALID_TOKEN_ACCESS.name)
class DBType(Enum):
"""논리 DB 구분. 모델마다 DBType() 으로 자신이 속한 DB 를 반환한다.
DB 가 늘어나면 여기에 추가하고 db_session_manager 의 맵에 등록만 하면 된다.
"""
MAIN = 1
class DBWRType(Enum):
"""Read / Write 접속 구분. 조회는 DB_READ, 변경은 DB_WRITE 엔진을 사용한다."""
DB_READ = 1
DB_WRITE = 2
# 도메인 코드값
class UserStatus(CodeEnum):
"""users.status 코드값."""
ACTIVE = 1
INACTIVE = 2
class UserRole(CodeEnum):
"""users.role 코드값."""
USER = 1
MANAGER = 2
class CompanyStatus(CodeEnum):
"""companies.status 코드값."""
ACTIVE = 1
INACTIVE = 2
class QuotationType(CodeEnum):
"""quotations.type 코드값. 1=renego(재협상 1:1), 2=requote(재견적 1:N)."""
RENEGO = 1
REQUOTE = 2
class QuotationStatus(CodeEnum):
"""quotations.status 코드값(SMALLINT). 프론트 견적상태 뱃지와 매핑된다."""
CREATED = 1
ACTIVE = 2
CLOSED = 3
ON_HOLD = 4
class SessionStatus(CodeEnum):
"""negotiation.sessions.status 코드값. 협력사별 협상 세션 진행 상태."""
CREATED = 1
IN_PROGRESS = 2
DONE = 3
NOT_PARTICIPATED = 4
REJECTED = 5
class ChatSender(CodeEnum):
"""negotiation.chats.sender 코드값. 채팅 발신 주체."""
BOT = 1
USER = 2
class DeliveryType(CodeEnum):
"""items.delivery_type 코드값. 협상 채팅의 배송형태 선택지와 동일 집합."""
PARTNER = 1 # 협력사배송
COURIER = 2 # 지정택배배송
PICKUP = 3 # 픽업배송
class CardStatus(CodeEnum):
"""nego_cards.status 코드값. 와일드카드의 협상 적용 여부(수동 승인). 일반 협상카드는 상시 ACTIVE."""
ACTIVE = 1
INACTIVE = 2
class CardType(CodeEnum):
"""negotiation.chats.card_type / quotation_cards.type 코드값. 1=nego_card, 2=wild_card."""
NEGO = 1
WILD = 2