용어 체계: 값=anchoring_value(정수‰)·가격=anchoring_price·조정=adjustment·구간=price_range·표본=sample - DB: rate_adjustments→anchoring.adjustments (id→adjustment_id, price_bracket_index→price_range_index, nego_count→sample_count, anchor_rate_before/after→anchoring_value_before/after, consumed_session_ids→used_session_ids) - sessions: target_anchoring_price→anchoring_price, anchor_rate_permille→anchoring_value, last_offered_price→last_offer_price, anchoring_adjustment_id→used_by_adjustment_id - 뷰: rate_history/current_rates→value_history/current_values, delta_permille→value_change - 코드: calc_price_range_index·calc_anchoring_price·evaluate_samples·get_current_value· get_latest_adjusted_value·get_current_anchoring_value·fetch_current_values·get_base_anchoring_value· Adjustment(ORM)·update_last_offer_price, 상수 ANCHORING_VALUE_MIN/MAX·ADJUSTMENT_STEP· PRICE_RANGE_COUNT/INDEX_MAX, 배치 로그 키 bracket=→price_range= - API: negodata protocol 필드 target_anchoring_price→anchoring_price (front 생성 모델·컴포넌트 동반) - 기존 DB 마이그레이션 신설: schedules/anchoring/migrations/20260706_rename_anchoring.sql (멱등 DO 블록 — 테이블·컬럼·뷰·인덱스·PK 제약. 코드 배포와 동시 적용 필요) - postgres-init 01·04, 문서 6종 동기화 - 실배포 전 수정 포함: main.py argparse 화(--dry-run 단독·오타 플래그 기동 전 차단), 박제 정합식 calc_anchoring_price 재사용, clamped 지표가 실제 포화만 집계(경계값 유지 제외) 주의: sessions.anchoring_value(정수‰)와 quotation_settings.anchoring_value(구 float 비율)는 같은 이름·다른 단위 — 구 컬럼은 미변경. 검증: 모듈 20·negodata 50·backend 57 테스트 통과, front tsc·vite build 통과, 로컬 DB 마이그레이션 적용 후 배치 dry-run·상주 기동·양 서버 부팅 확인. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
152 lines
15 KiB
PL/PgSQL
152 lines
15 KiB
PL/PgSQL
-- 견적상세 UI 케이스별 데모 시드 (dev DB: negosium_db)
|
|
-- 안전: 아래 데모 qt_id / 그 세션만 지우고 다시 넣는다(다른 데이터 무손상). 재실행 가능.
|
|
-- user=모모나(b874f33d) / setting=40614764 / version=...030 / item=고압 에어 컴프레서(a3d1fff5)
|
|
-- close_reason(CloseReason): 1=낙찰,2=가격재협상,3=동가재입찰,4=미참여재소집,5=가격유찰,6=동가유찰,7=미참여유찰,8=거부유찰
|
|
BEGIN;
|
|
|
|
DELETE FROM negotiation.sessions WHERE quotation_id IN (
|
|
'aaaa0001-0000-0000-0000-000000000001',
|
|
'aaaa0002-0000-0000-0000-000000000002',
|
|
'aaaa0003-0000-0000-0000-000000000003',
|
|
'aaaa0004-0000-0000-0000-000000000004',
|
|
'aaaa0005-0000-0000-0000-000000000005',
|
|
'aaaa0006-0000-0000-0000-000000000006',
|
|
'aaaa0007-0000-0000-0000-000000000007',
|
|
'aaaa0008-0000-0000-0000-000000000008',
|
|
'aaaa0009-0000-0000-0000-000000000009',
|
|
'aaaa0010-0000-0000-0000-000000000010'
|
|
);
|
|
DELETE FROM quotation.quotations WHERE qt_id IN (
|
|
'aaaa0001-0000-0000-0000-000000000001',
|
|
'aaaa0002-0000-0000-0000-000000000002',
|
|
'aaaa0003-0000-0000-0000-000000000003',
|
|
'aaaa0004-0000-0000-0000-000000000004',
|
|
'aaaa0005-0000-0000-0000-000000000005',
|
|
'aaaa0006-0000-0000-0000-000000000006',
|
|
'aaaa0007-0000-0000-0000-000000000007',
|
|
'aaaa0008-0000-0000-0000-000000000008',
|
|
'aaaa0009-0000-0000-0000-000000000009',
|
|
'aaaa0010-0000-0000-0000-000000000010'
|
|
);
|
|
|
|
-- ── 견적 10건 (close_reason 8종 전부 + 진행중) ────────────────────────────
|
|
INSERT INTO quotation.quotations
|
|
(qt_id, user_id, qt_setting_id, version_id, name, number, type, round, status,
|
|
start_time, end_time, manager_name, manager_email, manager_contact_number, memo,
|
|
iteration, preferred_sp_yn, preferred_sp_id, preferred_sp_name, equal_bid_yn, equal_bid_data,
|
|
close_reason, md_price, supplier_type, created_at, updated_at, deleted)
|
|
VALUES
|
|
-- ① 낙찰(절감): 목표 400,000 → 낙찰 372,000
|
|
('aaaa0001-0000-0000-0000-000000000001','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'① 낙찰(절감) 데모','EST-DEMO-01',4,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','낙찰·목표대비 절감 케이스',
|
|
1, true,'9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','(주)대한정밀', null, null,
|
|
1, 400000, 1, now(), now(), false),
|
|
-- ② 낙찰(목표초과): 목표 350,000 → 낙찰 368,000 (over_action=낙찰)
|
|
('aaaa0002-0000-0000-0000-000000000002','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'② 낙찰(목표초과) 데모','EST-DEMO-02',4,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','낙찰이지만 목표가 초과 케이스',
|
|
1, true,'69e7057a-5919-48cd-b329-13b833bff994','서울산업소재(주)', null, null,
|
|
1, 350000, 1, now(), now(), false),
|
|
-- ③ 동가 재입찰(REGEN_EQUAL): 두 곳 390,000 동률 → 재입찰 진행
|
|
('aaaa0003-0000-0000-0000-000000000003','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'③ 동가 재입찰 데모','EST-DEMO-03',2,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','동가 발생·다음 라운드 재입찰 케이스',
|
|
1, false, null, null, true,
|
|
'[{"supplier_id":"9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09","supplier_name":"(주)대한정밀","bid_price":390000},{"supplier_id":"747897ec-adab-4f3e-9076-15803ddf821f","supplier_name":"글로벌테크놀로지","bid_price":390000}]'::jsonb,
|
|
3, 400000, 1, now(), now(), false),
|
|
-- ④ 거부 유찰(FAIL_REJECT): 협상거부로 마감
|
|
('aaaa0004-0000-0000-0000-000000000004','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'④ 거부 유찰 데모','EST-DEMO-04',2,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','협상 거부로 유찰 케이스',
|
|
1, null, null, null, null, null,
|
|
8, 400000, 1, now(), now(), false),
|
|
-- ⑤ 미참여 재소집(REGEN_NOSHOW): 전원 미참여 → 다음 라운드 재소집
|
|
('aaaa0005-0000-0000-0000-000000000005','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑤ 미참여 재소집 데모','EST-DEMO-05',1,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','전원 미참여·다음 라운드 재소집 케이스',
|
|
1, false, null, null, false, null,
|
|
4, 400000, 1, now(), now(), false),
|
|
-- ⑥ 진행중: 일부 투찰 완료, 아직 안 닫힘 (close_reason NULL)
|
|
('aaaa0006-0000-0000-0000-000000000006','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑥ 진행중 데모','EST-DEMO-06',4,1,2,
|
|
now()-interval '1 day', now()+interval '1 day','김담당','mgr@imk.kr','010-1111-1111','협상 진행중·현재 최저 투찰 케이스',
|
|
1, null, null, null, null, null,
|
|
null, 400000, 1, now(), now(), false),
|
|
-- ⑦ 가격 재협상(REGEN_PRICE): 단독 최저가 420,000 > 목표 350,000 → 재협상 진행
|
|
('aaaa0007-0000-0000-0000-000000000007','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑦ 가격 재협상 데모','EST-DEMO-07',4,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','목표 초과 → 재협상(더 깎기) 진행 케이스',
|
|
1, false, null, null, false, null,
|
|
2, 350000, 1, now(), now(), false),
|
|
-- ⑧ 가격 유찰(FAIL_PRICE): 단독 최저가 430,000 > 목표 350,000, over_action=유찰(또는 한도소진) → 유찰
|
|
('aaaa0008-0000-0000-0000-000000000008','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑧ 가격 유찰 데모','EST-DEMO-08',4,1,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','목표 초과 → 유찰 케이스',
|
|
1, false, null, null, false, null,
|
|
5, 350000, 1, now(), now(), false),
|
|
-- ⑨ 동가 유찰(FAIL_EQUAL): 동가지만 재입찰 한도 소진/유찰 정책 → 유찰
|
|
('aaaa0009-0000-0000-0000-000000000009','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑨ 동가 유찰 데모','EST-DEMO-09',2,2,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','동가지만 재입찰 한도 소진 → 유찰 케이스',
|
|
1, false, null, null, true,
|
|
'[{"supplier_id":"9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09","supplier_name":"(주)대한정밀","bid_price":405000},{"supplier_id":"69e7057a-5919-48cd-b329-13b833bff994","supplier_name":"서울산업소재(주)","bid_price":405000}]'::jsonb,
|
|
6, 400000, 1, now(), now(), false),
|
|
-- ⑩ 미참여 유찰(FAIL_NOSHOW): 전원 미참여 + 재소집 한도 소진 → 유찰
|
|
('aaaa0010-0000-0000-0000-000000000010','b874f33d-afc3-4498-a9c2-19bc5ae8faba',
|
|
'40614764-43d5-4c45-a2f7-ccf659884c37','00000000-0000-0000-0000-000000000030',
|
|
'⑩ 미참여 유찰 데모','EST-DEMO-10',1,2,3,
|
|
now()-interval '2 days', now()-interval '1 hour','김담당','mgr@imk.kr','010-1111-1111','전원 미참여 + 재소집 한도 소진 → 유찰 케이스',
|
|
1, false, null, null, false, null,
|
|
7, 400000, 1, now(), now(), false);
|
|
|
|
-- ── 세션 ────────────────────────────────────────────────────────────────
|
|
-- 공통: item=a3d1fff5, DeliveryType 협력사배송=1
|
|
INSERT INTO negotiation.sessions
|
|
(session_id, quotation_id, item_id, supplier_id, qt_number, qt_round, qt_type,
|
|
target_price, status, bid_price, bid_at, end_time,
|
|
reject_reason, reject_price, reject_delivery_type, anchoring_price, email_sent_at,
|
|
created_at, updated_at, deleted)
|
|
VALUES
|
|
-- ① 낙찰(절감): S1 372,000(낙찰) / S2 389,000 / S3 395,000
|
|
('b0000001-0000-0000-0000-000000000001','aaaa0001-0000-0000-0000-000000000001','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-01',1,4,400000,3,372000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
('b0000001-0000-0000-0000-000000000002','aaaa0001-0000-0000-0000-000000000001','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-01',1,4,400000,3,389000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
('b0000001-0000-0000-0000-000000000003','aaaa0001-0000-0000-0000-000000000001','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','747897ec-adab-4f3e-9076-15803ddf821f','EST-DEMO-01',1,4,400000,3,395000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,null,now()-interval '2 days',now(),false),
|
|
-- ② 낙찰(초과): S2 368,000(낙찰, 목표 350k 초과) / S1 375,000
|
|
('b0000002-0000-0000-0000-000000000001','aaaa0002-0000-0000-0000-000000000002','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-02',1,4,350000,3,368000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,346500,now()-interval '2 days',now(),now(),false),
|
|
('b0000002-0000-0000-0000-000000000002','aaaa0002-0000-0000-0000-000000000002','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-02',1,4,350000,3,375000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,346500,now()-interval '2 days',now(),now(),false),
|
|
-- ③ 동가 재입찰: S1 390,000 / S3 390,000
|
|
('b0000003-0000-0000-0000-000000000001','aaaa0003-0000-0000-0000-000000000003','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-03',1,2,400000,3,390000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
('b0000003-0000-0000-0000-000000000002','aaaa0003-0000-0000-0000-000000000003','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','747897ec-adab-4f3e-9076-15803ddf821f','EST-DEMO-03',1,2,400000,3,390000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
-- ④ 거부 유찰: S4 협상거부(reject) / S5 미참여
|
|
('b0000004-0000-0000-0000-000000000001','aaaa0004-0000-0000-0000-000000000004','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','bcee5c78-ee13-4499-8e3d-132e2645dd6a','EST-DEMO-04',1,2,400000,5,null,null,now()-interval '1 hour','단가가 맞지 않아 참여를 거부합니다',430000,1,396000,now()-interval '2 days',now()-interval '2 days',now(),false),
|
|
('b0000004-0000-0000-0000-000000000002','aaaa0004-0000-0000-0000-000000000004','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','ffaf086d-6630-4c2e-9ae9-01843b86ff5f','EST-DEMO-04',1,2,400000,4,null,null,now()-interval '1 hour',null,null,null,396000,null,now()-interval '2 days',now(),false),
|
|
-- ⑤ 미참여 재소집: S1, S2 둘 다 미참여
|
|
('b0000005-0000-0000-0000-000000000001','aaaa0005-0000-0000-0000-000000000005','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-05',1,1,400000,4,null,null,now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now()-interval '2 days',now(),false),
|
|
('b0000005-0000-0000-0000-000000000002','aaaa0005-0000-0000-0000-000000000005','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-05',1,1,400000,4,null,null,now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now()-interval '2 days',now(),false),
|
|
-- ⑥ 진행중: S1 385,000 투찰완료 / S2 협상중 / S3 생성됨
|
|
('b0000006-0000-0000-0000-000000000001','aaaa0006-0000-0000-0000-000000000006','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-06',1,4,400000,3,385000,now()-interval '3 hour',now()+interval '1 day',null,null,null,396000,now()-interval '1 day',now(),now(),false),
|
|
('b0000006-0000-0000-0000-000000000002','aaaa0006-0000-0000-0000-000000000006','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-06',1,4,400000,2,null,null,now()+interval '1 day',null,null,null,396000,now()-interval '1 day',now(),now(),false),
|
|
('b0000006-0000-0000-0000-000000000003','aaaa0006-0000-0000-0000-000000000006','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','747897ec-adab-4f3e-9076-15803ddf821f','EST-DEMO-06',1,4,400000,1,null,null,now()+interval '1 day',null,null,null,396000,null,now()-interval '1 day',now(),false),
|
|
-- ⑦ 가격 재협상: S1 420,000(단독, 목표 350k 초과)
|
|
('b0000007-0000-0000-0000-000000000001','aaaa0007-0000-0000-0000-000000000007','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-07',1,4,350000,3,420000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,346500,now()-interval '2 days',now(),now(),false),
|
|
-- ⑧ 가격 유찰: S1 430,000(단독, 목표 350k 초과)
|
|
('b0000008-0000-0000-0000-000000000001','aaaa0008-0000-0000-0000-000000000008','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-08',1,4,350000,3,430000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,346500,now()-interval '2 days',now(),now(),false),
|
|
-- ⑨ 동가 유찰: S1 405,000 / S2 405,000 (동률)
|
|
('b0000009-0000-0000-0000-000000000001','aaaa0009-0000-0000-0000-000000000009','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-09',2,2,400000,3,405000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
('b0000009-0000-0000-0000-000000000002','aaaa0009-0000-0000-0000-000000000009','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-09',2,2,400000,3,405000,now()-interval '2 hour',now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now(),now(),false),
|
|
-- ⑩ 미참여 유찰: S1, S2 둘 다 미참여
|
|
('b0000010-0000-0000-0000-000000000001','aaaa0010-0000-0000-0000-000000000010','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','9795c2e5-3ac2-4e44-aeb5-c6c5e3053f09','EST-DEMO-10',2,1,400000,4,null,null,now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now()-interval '2 days',now(),false),
|
|
('b0000010-0000-0000-0000-000000000002','aaaa0010-0000-0000-0000-000000000010','a3d1fff5-3169-4717-8d12-48e2f3b0d32d','69e7057a-5919-48cd-b329-13b833bff994','EST-DEMO-10',2,1,400000,4,null,null,now()-interval '1 hour',null,null,null,396000,now()-interval '2 days',now()-interval '2 days',now(),false);
|
|
|
|
COMMIT;
|