o2o-negosium-original/postgres-init/03-seed-negodata.sql
Mina Choi 01e80281d1 [chore] negodata: 데모 시드 데이터 정비
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:00:15 +09:00

172 lines
15 KiB
SQL

-- negodata 전용 로컬/개발 시드 — company.companies + company.users 만 채운다.
-- (negodata 로그인은 company.users 를 쓴다. negosium 의 company.tbl_account 는 대상이 아님.)
-- 전체/공용 시드가 아니다. 재실행 안전(WHERE NOT EXISTS) — 운영 DB 에는 적용하지 않는다.
-- admin 계정은 negodata 프론트 로그인 폼 기본값(admin / admin1234)에 대응한다.
-- 적용(도커 postgres): docker exec -i negosium-db psql -U postgres -d negosium_db < postgres-init/03-seed-negodata.sql
\connect negosium_db
-- 회사 1개 (고정 UUID). status 1=active.
INSERT INTO company.companies (company_id, name, email, status)
SELECT '00000000-0000-0000-0000-000000000001', 'Negosium', 'admin@negosium.dev', 1
WHERE NOT EXISTS (
SELECT 1 FROM company.companies WHERE company_id = '00000000-0000-0000-0000-000000000001'
);
-- admin 유저. password 는 'admin1234' 의 bcrypt 해시(백엔드 GetHashedPW 와 동일 알고리즘, checkpw 로 검증됨).
-- role 2=manager (UserRole.MANAGER; ADMIN 코드는 enum 에 없어 최상위인 MANAGER 사용). status 1=active.
INSERT INTO company.users (user_id, company_id, id, password, name, email, last_accessed_at, status, role)
SELECT '00000000-0000-0000-0000-000000000002',
'00000000-0000-0000-0000-000000000001',
'admin',
'$2b$12$oq5qlcYQ4BNywh9iS7cF1OBP6kGBvB6SfsGgVknCiJ6lMSW5cjW.C',
'admin', 'admin@negosium.dev', now(), 1, 2
WHERE NOT EXISTS (
SELECT 1 FROM company.users WHERE id = 'admin' AND deleted = FALSE
);
-- 데모 상품 5개. company_id/user_id 는 'admin' 유저의 소속에서 가져온다
-- (clean DB=Negosium, 테스트가 남긴 DB=그 회사 — 어느 쪽이든 admin 으로 로그인하면 보이도록).
-- category 는 프론트 categoriesList 와 맞춤. quantity_unit 은 ORM(String) 기준 varchar 라벨.
INSERT INTO partner.items (item_id, company_id, user_id, name, code, price, category, model_name, spec, moq, lead_time, manufacturer, made_in, quantity_unit, vat_yn, delivery_fee_yn, internet_lowest_price_yn, category_type)
SELECT v.item_id, u.company_id, u.user_id, v.name, v.code, v.price, v.category, v.model_name, v.spec, v.moq, v.lead_time, v.manufacturer, v.made_in, v.quantity_unit, v.vat_yn, v.delivery_fee_yn, FALSE, v.category_type
FROM company.users u
CROSS JOIN (VALUES
('00000000-0000-0000-0000-000000000010'::uuid, '리튬인산철 배터리 모듈', 'BAT-LFP-100', 1250000::bigint, '에너지/배터리', 'LFP-100A', '3.2V 100Ah', '10', 14::smallint, '한성에너지', '대한민국', 'EA', TRUE, TRUE, 1),
('00000000-0000-0000-0000-000000000011'::uuid, '산업용 6축 로봇암', 'ROB-6AX-22', 18900000::bigint, '자동화설비', 'RX-6A', '가반하중 12kg', '1', 30::smallint, '오토메카', '일본', 'EA', TRUE, FALSE, 2),
('00000000-0000-0000-0000-000000000012'::uuid, 'MEMS 가속도 센서', 'SEN-MEMS-3A', 8500::bigint, '반도체소자/센서', 'MA-3X', '±16g 3축', '100', 7::smallint, '센서텍', '대만', 'EA', TRUE, TRUE, 3),
('00000000-0000-0000-0000-000000000013'::uuid, '탄소섬유 시트', 'MAT-CF-12', 320000::bigint, '신소재', 'CF-T700', '0.5T 1000x1000', '5', 21::smallint, '카본소재', '대한민국', 'BOX', TRUE, FALSE, 4),
('00000000-0000-0000-0000-000000000014'::uuid, '광트랜시버 SFP+ 10G', 'OPT-SFP-10G', 95000::bigint, '광학/통신', 'SFP-10G-LR', '10km LC', '20', 10::smallint, '옵틱링크', '중국', 'EA', TRUE, TRUE, 5)
) AS v(item_id, name, code, price, category, model_name, spec, moq, lead_time, manufacturer, made_in, quantity_unit, vat_yn, delivery_fee_yn, category_type)
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM partner.items i WHERE i.item_id = v.item_id);
-- 견적 세팅 1개 (admin 소유, 고정 UUID). target_margin_rate 는 비율(0.12 = 12%), anchoring_value 0.01, card_count 3.
-- 견적(quotations)이 qt_setting_id 로 참조하므로 선행 시드.
INSERT INTO quotation.quotation_settings (qt_setting_id, user_id, target_margin_rate, anchoring_value, card_count)
SELECT '00000000-0000-0000-0000-000000000020', u.user_id, 0.12, 0.01, 3
FROM company.users u
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM quotation.quotation_settings qs WHERE qs.qt_setting_id = '00000000-0000-0000-0000-000000000020');
-- 협상전략 버전 1개 (admin 소유, 고정 UUID). quotations.version_id 가 NOT NULL 이라 참조 대상으로 시드.
INSERT INTO card.versions (version_id, user_id, code, name)
SELECT '00000000-0000-0000-0000-000000000030', u.user_id, 1, '기본전략'
FROM company.users u
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM card.versions vv WHERE vv.version_id = '00000000-0000-0000-0000-000000000030');
-- 데모 견적 4건. status 코드 = QuotationStatus(1=견적생성 2=견적진행중 3=견적마감 4=협상보류),
-- type 코드 = QuotationType(1=재협상 2=재견적). 마감기한은 시드 적용 시점 기준 상대시각.
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_name, equal_bid_yn, equal_bid_data
)
SELECT v.qt_id, u.user_id, '00000000-0000-0000-0000-000000000020', '00000000-0000-0000-0000-000000000030',
v.name, v.number, v.type, v.round, v.status,
v.start_time, v.end_time, v.manager_name, v.manager_email, v.manager_contact_number, v.memo,
v.iteration, v.preferred_sp_yn, v.preferred_sp_name, v.equal_bid_yn, v.equal_bid_data
FROM company.users u
CROSS JOIN (VALUES
('00000000-0000-0000-0000-000000000040'::uuid, '사무용 복합기 대량구매 재견적', 'EST-202606-1001', 2::smallint, 1, 1::smallint,
now(), now() + interval '5 day', '김조달', 'buyer1@negosium.dev', '02-1000-2001', '연간 단가계약 목적 재견적', 0, NULL, NULL, NULL, NULL::jsonb),
('00000000-0000-0000-0000-000000000041'::uuid, '리튬인산철 배터리 단가 재협상', 'EST-202606-1002', 1::smallint, 2, 2::smallint,
now() - interval '2 day', now() + interval '3 day', '이매입', 'buyer2@negosium.dev', '02-1000-2002', '2차 라운드 진행중', 1, NULL, NULL, NULL, NULL::jsonb),
('00000000-0000-0000-0000-000000000042'::uuid, 'MEMS 가속도 센서 연간 단가견적', 'EST-202606-1003', 2::smallint, 1, 3::smallint,
now() - interval '10 day', now() - interval '1 day', '박구매', 'buyer3@negosium.dev', '02-1000-2003', '낙찰 완료, 동일가 발생', 1, TRUE, '센서텍', TRUE, '{"part-a":730000,"part-b":730000}'::jsonb),
('00000000-0000-0000-0000-000000000043'::uuid, '산업용 6축 로봇암 도입 협상', 'EST-202606-1004', 1::smallint, 1, 4::smallint,
now() - interval '4 day', now() + interval '2 day', '최담당', 'buyer4@negosium.dev', '02-1000-2004', '관리자 사유로 협상보류', 0, NULL, NULL, NULL, NULL::jsonb)
) AS v(qt_id, name, number, type, round, status, start_time, end_time, manager_name, manager_email, manager_contact_number, memo, iteration, preferred_sp_yn, preferred_sp_name, equal_bid_yn, equal_bid_data)
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM quotation.quotations q WHERE q.qt_id = v.qt_id);
-- 협력사 3곳 (admin 소유). 협상 세션의 supplier_id 가 참조한다.
INSERT INTO partner.suppliers (supplier_id, company_id, user_id, name, code, manager_name, manager_email, manager_contact_number, priority)
SELECT v.supplier_id, u.company_id, u.user_id, v.name, v.code, v.manager_name, v.manager_email, v.manager_contact_number, v.priority
FROM company.users u
CROSS JOIN (VALUES
('00000000-0000-0000-0000-000000000050'::uuid, '(주)우성테크놀로지', 'SUP-01', '김우성', 'woosung@vendor.dev', '02-500-1001', 'HIGH'),
('00000000-0000-0000-0000-000000000051'::uuid, '대현정밀공업(주)', 'SUP-02', '이대현', 'daehyun@vendor.dev', '02-500-1002', 'MEDIUM'),
('00000000-0000-0000-0000-000000000052'::uuid, '센서텍', 'SUP-03', '박센서', 'sensortech@vendor.dev', '02-500-1003', 'HIGH')
) AS v(supplier_id, name, code, manager_name, manager_email, manager_contact_number, priority)
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM partner.suppliers s WHERE s.supplier_id = v.supplier_id);
-- 협상카드 2장 (admin 유저). 채팅에서 card_id 로 사용된다.
INSERT INTO card.nego_cards (nego_card_id, user_id, name, number, script)
SELECT v.nego_card_id, u.user_id, v.name, v.number, v.script
FROM company.users u
CROSS JOIN (VALUES
('00000000-0000-0000-0000-000000000060'::uuid, '즉시수용 인센티브', 'NC-01', '지금 수용하시면 차기 견적 우선참여와 추가 물량을 보장합니다.'),
('00000000-0000-0000-0000-000000000061'::uuid, '단가 매칭 보장', 'NC-02', '경쟁사 최저가에 맞춰주시면 즉시 낙찰 처리하겠습니다.')
) AS v(nego_card_id, name, number, script)
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM card.nego_cards c WHERE c.nego_card_id = v.nego_card_id);
-- 협상 세션. status=SessionStatus(1=협상중 2=협상종료 3=협상거부), qt_type=QuotationType(1=재협상 2=재견적).
-- (sessions 엔 user_id 가 없어 고정 UUID 로 직접 삽입. 견적/상품/협력사 시드에 의존.)
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
)
VALUES
-- 견적 0041(배터리 재협상, 진행중) — 1:1 세션
('00000000-0000-0000-0000-000000000070', '00000000-0000-0000-0000-000000000041', '00000000-0000-0000-0000-000000000010', '00000000-0000-0000-0000-000000000050',
'EST-202606-1002', 2, 1, 1125000, 1, 1180000, now() - interval '1 day', now() + interval '3 day', NULL, NULL, NULL),
-- 견적 0042(MEMS 센서 재견적, 마감) — 1:N 세션 3개 (낙찰/동일가/거부)
('00000000-0000-0000-0000-000000000071', '00000000-0000-0000-0000-000000000042', '00000000-0000-0000-0000-000000000012', '00000000-0000-0000-0000-000000000052',
'EST-202606-1003', 1, 2, 7600, 2, 7300, now() - interval '2 day', now() - interval '1 day', NULL, NULL, NULL),
('00000000-0000-0000-0000-000000000072', '00000000-0000-0000-0000-000000000042', '00000000-0000-0000-0000-000000000012', '00000000-0000-0000-0000-000000000051',
'EST-202606-1003', 1, 2, 7600, 2, 7300, now() - interval '2 day', now() - interval '1 day', NULL, NULL, NULL),
('00000000-0000-0000-0000-000000000073', '00000000-0000-0000-0000-000000000042', '00000000-0000-0000-0000-000000000012', '00000000-0000-0000-0000-000000000050',
'EST-202606-1003', 1, 2, 7600, 3, NULL, NULL, now() - interval '1 day', '제조 원가 미달로 제시 단가 수용 불가', 8200, 2),
-- 견적 0043(로봇암 재협상, 보류) — 1:1 세션
('00000000-0000-0000-0000-000000000074', '00000000-0000-0000-0000-000000000043', '00000000-0000-0000-0000-000000000011', '00000000-0000-0000-0000-000000000050',
'EST-202606-1004', 1, 1, 17010000, 1, 18200000, now() - interval '2 day', now() + interval '2 day', NULL, NULL, NULL)
ON CONFLICT (session_id) DO NOTHING;
-- 협상 채팅. sender=ChatSender(1=봇 2=협력사), card_type=1=협상카드. card_used_yn=TRUE 인 행이 '사용 카드' 탭 소스.
INSERT INTO negotiation.chats (chat_id, session_id, card_id, seq, sender, target_price, card_used_yn, indicator_value, card_type)
VALUES
-- 세션 0070 (배터리)
('00000000-0000-0000-0000-000000000080', '00000000-0000-0000-0000-000000000070', NULL, 1, 1, 1125000, FALSE, NULL, NULL),
('00000000-0000-0000-0000-000000000081', '00000000-0000-0000-0000-000000000070', NULL, 2, 2, 1250000, FALSE, NULL, NULL),
('00000000-0000-0000-0000-000000000082', '00000000-0000-0000-0000-000000000070', '00000000-0000-0000-0000-000000000060', 3, 1, 1150000, TRUE, 0.08, 1),
('00000000-0000-0000-0000-000000000083', '00000000-0000-0000-0000-000000000070', NULL, 4, 2, 1180000, FALSE, NULL, NULL),
-- 세션 0071 (센서, 낙찰)
('00000000-0000-0000-0000-000000000084', '00000000-0000-0000-0000-000000000071', NULL, 1, 1, 7600, FALSE, NULL, NULL),
('00000000-0000-0000-0000-000000000085', '00000000-0000-0000-0000-000000000071', NULL, 2, 2, 7800, FALSE, NULL, NULL),
('00000000-0000-0000-0000-000000000086', '00000000-0000-0000-0000-000000000071', '00000000-0000-0000-0000-000000000061', 3, 1, 7400, TRUE, 0.05, 1),
('00000000-0000-0000-0000-000000000087', '00000000-0000-0000-0000-000000000071', NULL, 4, 2, 7300, FALSE, NULL, NULL),
-- 세션 0072 (센서, 동일가)
('00000000-0000-0000-0000-000000000088', '00000000-0000-0000-0000-000000000072', NULL, 1, 1, 7600, FALSE, NULL, NULL),
('00000000-0000-0000-0000-000000000089', '00000000-0000-0000-0000-000000000072', NULL, 2, 2, 7300, FALSE, NULL, NULL),
-- 세션 0073 (센서, 거부)
('00000000-0000-0000-0000-00000000008a', '00000000-0000-0000-0000-000000000073', NULL, 1, 1, 7600, FALSE, NULL, NULL),
('00000000-0000-0000-0000-00000000008b', '00000000-0000-0000-0000-000000000073', NULL, 2, 2, 8200, FALSE, NULL, NULL),
-- 세션 0074 (로봇암)
('00000000-0000-0000-0000-00000000008c', '00000000-0000-0000-0000-000000000074', NULL, 1, 1, 17010000, FALSE, NULL, NULL),
('00000000-0000-0000-0000-00000000008d', '00000000-0000-0000-0000-000000000074', '00000000-0000-0000-0000-000000000060', 2, 1, 17500000, TRUE, 0.06, 1),
('00000000-0000-0000-0000-00000000008e', '00000000-0000-0000-0000-000000000074', NULL, 3, 2, 18200000, FALSE, NULL, NULL)
ON CONFLICT (chat_id) DO NOTHING;
-- 와일드카드 2장 (admin 유저). 채팅에서 card_type=2 로 사용된다.
INSERT INTO card.wild_cards (wild_card_id, user_id, name, number, script, condition, available)
SELECT v.wild_card_id, u.user_id, v.name, v.number, v.script, v.condition, TRUE
FROM company.users u
CROSS JOIN (VALUES
('00000000-0000-0000-0000-000000000062'::uuid, '긴급마감 압박', 'WC-01', '오늘 자정까지 확정 시 단가를 동결하고 우선 배정합니다.', '마감 24시간 이내'),
('00000000-0000-0000-0000-000000000063'::uuid, '독점공급 보장', 'WC-02', '연간 독점 공급권을 보장하는 대신 추가 인하를 요청합니다.', '연간 계약 전환 시')
) AS v(wild_card_id, name, number, script, condition)
WHERE u.id = 'admin' AND u.deleted = FALSE
AND NOT EXISTS (SELECT 1 FROM card.wild_cards w WHERE w.wild_card_id = v.wild_card_id);
-- 세션마다 카드 사용 기록이 남도록 보강(0072 와일드 / 0073 협상 / 0074 와일드). card_type 1=협상 2=와일드.
INSERT INTO negotiation.chats (chat_id, session_id, card_id, seq, sender, target_price, card_used_yn, indicator_value, card_type)
VALUES
('00000000-0000-0000-0000-000000000090', '00000000-0000-0000-0000-000000000072', '00000000-0000-0000-0000-000000000062', 3, 1, 7500, TRUE, 0.04, 2),
('00000000-0000-0000-0000-000000000091', '00000000-0000-0000-0000-000000000073', '00000000-0000-0000-0000-000000000061', 3, 1, 7500, TRUE, 0.03, 1),
('00000000-0000-0000-0000-000000000092', '00000000-0000-0000-0000-000000000074', '00000000-0000-0000-0000-000000000063', 4, 1, 18000000, TRUE, 0.05, 2)
ON CONFLICT (chat_id) DO NOTHING;