diff --git a/postgres-init/00-init.sql b/postgres-init/00-init.sql index f4d6921..1cee41b 100644 --- a/postgres-init/00-init.sql +++ b/postgres-init/00-init.sql @@ -1,5 +1,6 @@ -- 단일 초기화 파일 — 스키마 DDL 전부를 이 한 파일로 적용한다 (구 01~05 통합, 2026-07-07). -- 시드(임시 데이터)는 temp-data.sql 로 분리. 전부 IF NOT EXISTS 라 재실행 안전. +-- 기존 DB 에 재실행하면 말미의 "기존 DB 보정(ALTER)" 섹션이 최신 스키마로 맞춰준다. -- -- 단일 PostgreSQL 인스턴스, 단일 database(negosium_db) 안에서 도메인별 schema 로 묶는다. -- postgres (1개 서버, 5432) @@ -646,3 +647,22 @@ SELECT DISTINCT ON (company_id, supplier_type, price_range_index) created_at AS last_adjusted_at FROM anchoring.adjustments ORDER BY company_id, supplier_type, price_range_index, adjustment_id DESC; + + +-- ============================================================ +-- 기존 DB 보정(ALTER) — 재실행 시 기존 DB 를 최신 스키마로 맞춘다 +-- ============================================================ +-- 위 CREATE TABLE IF NOT EXISTS 는 기존 테이블을 바꾸지 못하므로, 컬럼 추가/타입 변경은 +-- 멱등 ALTER 로 여기에 함께 둔다. 신규 DB 에는 전부 no-op. +-- 새 스키마 변경 시 위 테이블 정의와 이 섹션을 동시에 갱신한다 (구 04-alter*.sql 의 역할). +-- 기준선: 2026-07-07 main 스키마. 그보다 오래된 DB 는 git 이력의 04-alter*.sql 을 먼저 적용. + +-- [2026-07-07] 협상 카드: script 길이 제한 해제(TEXT) + 톤·전략 분류 컬럼 +ALTER TABLE card.nego_cards ALTER COLUMN script TYPE TEXT; +ALTER TABLE card.wild_cards ALTER COLUMN script TYPE TEXT; +ALTER TABLE card.nego_cards + ADD COLUMN IF NOT EXISTS tone SMALLINT NULL, -- 카드 톤(CardTone): 1=강경, 2=정중, 3=우호, 4=중립, 5=단호 + ADD COLUMN IF NOT EXISTS strategy_type SMALLINT NULL; -- 전략 유형(CardStrategyType): 1=경쟁, 2=수용, 3=고수, 4=협력, 5=선점, 6=종결 +ALTER TABLE card.wild_cards + ADD COLUMN IF NOT EXISTS tone SMALLINT NULL, -- 카드 톤(CardTone): 1=강경, 2=정중, 3=우호, 4=중립, 5=단호 + ADD COLUMN IF NOT EXISTS strategy_type SMALLINT NULL; -- 전략 유형(CardStrategyType): 1=경쟁, 2=수용, 3=고수, 4=협력, 5=선점, 6=종결 diff --git a/postgres-init/ENUM_TYPE.md b/postgres-init/ENUM_TYPE.md new file mode 100644 index 0000000..56baab7 --- /dev/null +++ b/postgres-init/ENUM_TYPE.md @@ -0,0 +1,212 @@ +# 코드값(ENUM) 조견표 + +`00-init.sql`·`temp-data.sql`에서 SMALLINT 코드로 쓰는 값들의 정리표. + +- **DB에는 PG ENUM/CHECK를 걸지 않는다** — 컬럼은 전부 SMALLINT 코드, 의미는 애플리케이션 enum이 부여한다. +- **진실 원천은 각 서비스의 enums.py**이며 이 문서는 조견표다. 어긋나면 enums.py가 맞다. + - negosium: `backend/common/enums.py` + - negodata: `negodata/backend/common/enums.py` + - learning 스키마: agent 소유(`agent/common/database/model/models.py`) + - anchoring 스키마: schedules/anchoring 소유(`schedules/anchoring/docs/개발용.md` §6) +- **갱신 규칙**: 코드값 컬럼을 추가/변경할 때 enums.py와 이 문서를 함께 갱신한다. + +## 계정/회사 + +### AccountStatus / UserStatus / CompanyStatus — 상태 + +`company.companies.status` · `company.users.status` · `supplier.supplier_users.status` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | ACTIVE | 활성 | +| 2 | INACTIVE | 비활성 | + +### UserRole — 유저 권한 + +`company.users.role` · `supplier.supplier_users.role` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | USER | 일반 유저 | +| 2 | OWNER / MANAGER | 아래 참고 | + +> 값 2의 이름이 서비스마다 다른 것은 **의도된 설계**다 — 두 테이블의 권한 체계가 서로 다르다. negodata(`company.users`)는 `OWNER`(최고관리자: 자기 회사 직원 계정 생성·관리), negosium(`supplier.supplier_users`)은 `MANAGER`(매니저). + +### TokenType — 토큰 종류 + +`company.user_tokens.type` · `supplier.supplier_user_tokens.type` + +| 값 | 코드명 | +|---|---| +| 1 | ACCESS | +| 2 | REFRESH | + +## 견적/협상 + +### QuotationType (negosium은 QtType) — 견적/세션 유형 + +`quotation.quotations.type` · `negotiation.sessions.qt_type`(스냅샷) + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | RENEGO | 재협상 (1:1) | +| 2 | REQUOTE | 재견적 (1:N) | +| 3 | NEW_NEGO | 신규협상 (1:1) | +| 4 | NEW_QUOTE | 신규견적 (1:N) | + +1·2(재)는 기존 데이터 보존을 위해 고정, 신규가 3·4. + +### QuotationStatus — 견적 진행 상태 + +`quotation.quotations.status` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | CREATED | 견적생성 | +| 2 | IN_PROGRESS | 견적진행중 | +| 3 | CLOSED | 견적마감 | + +### SessionStatus — 협상 세션 진행 상태 + +`negotiation.sessions.status` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | CREATED | 협상생성 | +| 2 | IN_PROGRESS | 협상중 | +| 3 | DONE | 협상완료 | +| 4 | NOT_PARTICIPATED | 미참여 | +| 5 | REJECTED | 협상거부 | + +### CloseReason — 견적 마감 사유 + +`quotation.quotations.close_reason` (미마감이면 NULL) + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | AWARDED | 낙찰 (기준 충족 단독 최저가) | +| 5 | OPEN_PRICE | 개찰: 최저가가 낙찰 기준 미달 → 낙찰자 미정 | +| 6 | OPEN_EQUAL | 개찰: 동가(최저가 동점) | +| 7 | OPEN_NOSHOW | 개찰: 전원 미응찰 | +| 8 | OPEN_REJECT | 개찰: 협상거부 존재 | + +2~4는 폐지된 구 자동재협상(REGEN_*) 코드 — 재사용 금지. 개찰은 결렬(유찰)이 아니라 "낙찰자 미정으로 마감"이며 담당자가 수동 처리한다. + +### PriceGateAction — 낙찰 기준(가격게이트) 판정 + +`quotation.quotations.mid_action`(앵커링가<투찰가≤목표가 구간) · `over_action`(목표가<투찰가 구간) + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | AWARD | 낙찰(자동) | +| 2 | OPEN | 개찰(낙찰자 미정 마감) | + +투찰가≤앵커링가는 항상 낙찰. 1:1 협상은 over 항상 OPEN(mid만 선택), 1:N 경매는 mid=over=AWARD 강제. + +### SupplierType — 협력사(공급채널) 유형 + +`quotation.quotations.supplier_type` · `partner.supplier_items.supply_type` · `anchoring.adjustments.supplier_type` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 0 | NONE | 없음(미지정) | +| 1 | DISTRIBUTION | 유통 | +| 2 | MANUFACTURE | 제조 | +| 3 | SOLE_AGENCY | 총판 | + +anchoring.adjustments는 1~3만 사용(0 없음 — δ: 유통20/제조10/총판15). `supplier_items.supply_type`은 `quotations.supplier_type`과 의미 단위가 달라 컬럼명을 달리 씀(값 집합은 동일). + +### NotificationType — 알림 유형 + +`company.notifications.type` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | SUCCESS | 낙찰(단독 최저가) | +| 2 | REGENERATED | 다음 라운드 자동 생성(동가/미참여) | +| 3 | FAILURE | 결렬: 낙찰 없이 마감 | +| 4 | CREATED | 견적 생성됨(작성 직후) | + +## 채팅/카드 + +### ChatSender — 채팅 발신 주체 + +`negotiation.chats.sender` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | BOT | 고객사(갑) — bot 메시지 | +| 2 | USER | 협력사(을) — user 입력 | + +### CardType — 카드 유형 + +`negotiation.chats.card_type` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | NEGO | 일반 협상카드 (card.nego_cards) | +| 2 | WILD | 와일드카드 (card.wild_cards) | + +### CardUsageType — 카드 적용 견적 구분 + +`card.nego_cards.usage_type` · `card.wild_cards.usage_type` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | COMMON | 공통(모두 적용) — 기본 | +| 2 | NEW | 신규견적전용 | +| 3 | REUSE | 재견적전용 | + +### CardTone — 카드 톤 ⚠️ 앱 enum 미정의 + +`card.nego_cards.tone` · `card.wild_cards.tone` (2026-07-07 카드 시드와 함께 도입 — enums.py 추가 필요) + +| 값 | 의미 | +|---|---| +| 1 | 강경 | +| 2 | 정중 | +| 3 | 우호 | +| 4 | 중립 | +| 5 | 단호 | + +### CardStrategyType — 카드 전략 유형 ⚠️ 앱 enum 미정의 + +`card.nego_cards.strategy_type` · `card.wild_cards.strategy_type` (2026-07-07 카드 시드와 함께 도입 — enums.py 추가 필요) + +| 값 | 의미 | +|---|---| +| 1 | 경쟁 | +| 2 | 수용 | +| 3 | 고수 | +| 4 | 협력 | +| 5 | 선점 | +| 6 | 종결 | + +> 참고: negodata의 `CardStatus`(ACTIVE=1/INACTIVE=2)는 DB 컬럼이 아니다 — API 응답 전용으로, `card.wild_cards.available`(BOOLEAN)에 매핑된다. + +## 배송/기타 + +### DeliveryType — 배송 유형 + +`partner.items.delivery_type` · `negotiation.sessions.reject_delivery_type` + +| 값 | 코드명 | 의미 | +|---|---|---| +| 1 | SUPPLIER | 협력사배송 | +| 2 | COURIER | 지정택배배송 | +| 3 | PICKUP | 픽업배송 | + +### learning.q_table_versions.scope — Q-Table 버전 스코프 (agent 소유) + +| 값 | 의미 | +|---|---| +| 1 | base (공유 베이스) | +| 2 | tenant (테넌트 전용) | + +### 매핑 미확정(앱에서 자유 사용) 코드 컬럼 + +| 컬럼 | 비고 | +|---|---| +| `company.companies.industry` | 업종 — 필요한 만큼 숫자에 매핑하여 사용 | +| `partner.item_internet_lowest_prices.website` | 크롤링 대상 사이트 — 앱 enum 매핑 | +| `partner.item_internet_lowest_prices.ai_model` | 사용 AI 모델 — 앱 enum 매핑 |