[fix] postgres-init: 카드 시드를 운영 현행에 맞춤 — 중반 카드 앵커가 인용 + 목표가 카드 종결 전용

협상 중반에 목표가를 부르면 이후 올려줄 금액이 없어져 남은 카드가 같은 값만 반복한다.
제안은 앵커가 → 중간가 → 목표가로 수렴해야 하므로 시드를 그 순서에 맞춘다.

- NGC-010 향후 거래 연계 · NGC-011 양보 가치 강조: 제시 금액 {target_price} → {anchor_price}
- tactic: WC-01 종결 전용 추가, WC-04 min_round 2 → 종결 전용, WC-05 종결 전용 + min_round 2,
  WC-02 min_round 2 추가 (WC-03 종전 유지)

init-data.sql · dbeaver/4_cards_reset_dbeaver.sql 동일 반영.
검증: 임시 DB 에 1_init + 4_cards_reset 적용 후 tactic·변수 확인.
This commit is contained in:
Mina Choi 2026-08-10 11:41:25 +09:00
parent 86d50c1291
commit 37fa65707f
2 changed files with 23 additions and 14 deletions

View File

@ -13,6 +13,7 @@ DELETE FROM card.wild_cards WHERE user_id IS NULL;
-- 기본가(DB 존재): -- 기본가(DB 존재):
-- {target_price} 목표가격(고객사 지향가) 접미: 원(VAT별도) -- {target_price} 목표가격(고객사 지향가) 접미: 원(VAT별도)
-- {anchoring_price} 앵커링가격(고객사 하한) 접미: 원(VAT별도) -- {anchoring_price} 앵커링가격(고객사 하한) 접미: 원(VAT별도)
-- {anchor_price} 위와 같은 값(카드 에디터 칩 표기 '앵커가')
-- {internet_lowest_price} 인터넷 최저가 접미: 원(VAT별도) -- {internet_lowest_price} 인터넷 최저가 접미: 원(VAT별도)
-- 세션값(협상 중 직전 제시가): -- 세션값(협상 중 직전 제시가):
-- {prev_customer_price} 고객사 직전 제시가 접미: 원 -- {prev_customer_price} 고객사 직전 제시가 접미: 원
@ -98,20 +99,20 @@ SELECT * FROM (VALUES
-- 10. 향후 거래 연계 — tone 4(중립) · strategy 4(협력) -- 10. 향후 거래 연계 — tone 4(중립) · strategy 4(협력)
(NULL::uuid, '향후 거래 연계', 'NGC-010', (NULL::uuid, '향후 거래 연계', 'NGC-010',
'이번 거래의 가격을 {target_price}원(VAT별도)으로 조정하는 대신, {customer_condition}을 함께 검토해 주실 것을 제안 드립니다. '이번 거래의 가격을 {anchor_price}원(VAT별도)으로 조정하는 대신, {customer_condition}을 함께 검토해 주실 것을 제안 드립니다.
당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다.', 당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다.',
'[{"type": "paragraph", "children": [{"text": "이번 거래의 가격을 "}, {"type": "variable", "name": "target_price", "label": "목표가격(고객사 지향가)", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로 조정하는 대신, "}, {"type": "variable", "name": "customer_condition", "label": "고객사 교환·요구 조건", "children": [{"text": ""}], "style": {"bold": true}}, {"text": "을 함께 검토해 주실 것을 제안 드립니다."}]}, {"type": "paragraph", "children": [{"text": "당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다."}]}]'::jsonb, '[{"type": "paragraph", "children": [{"text": "이번 거래의 가격을 "}, {"type": "variable", "name": "anchor_price", "label": "앵커가", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로 조정하는 대신, "}, {"type": "variable", "name": "customer_condition", "label": "고객사 교환·요구 조건", "children": [{"text": ""}], "style": {"bold": true}}, {"text": "을 함께 검토해 주실 것을 제안 드립니다."}]}, {"type": "paragraph", "children": [{"text": "당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다."}]}]'::jsonb,
1, 4, 4), 1, 4, 4),
-- 11. 양보 가치 강조 — tone 4(중립) · strategy 4(협력) -- 11. 양보 가치 강조 — tone 4(중립) · strategy 4(협력)
(NULL::uuid, '양보 가치 강조', 'NGC-011', (NULL::uuid, '양보 가치 강조', 'NGC-011',
'이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다. '이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다.
{target_price}원(VAT별도)으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다. {anchor_price}원(VAT별도)으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다.
당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다.', 당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다.',
'[{"type": "paragraph", "children": [{"text": "이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다."}]}, {"type": "paragraph", "children": [{"type": "variable", "name": "target_price", "label": "목표가격(고객사 지향가)", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정", "bold": true}, {"text": "이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다."}]}, {"type": "paragraph", "children": [{"text": "당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다."}]}]'::jsonb, '[{"type": "paragraph", "children": [{"text": "이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다."}]}, {"type": "paragraph", "children": [{"type": "variable", "name": "anchor_price", "label": "앵커가", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정", "bold": true}, {"text": "이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다."}]}, {"type": "paragraph", "children": [{"text": "당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다."}]}]'::jsonb,
1, 4, 4) 1, 4, 4)
) AS v(user_id, name, number, script, edit_script, usage_type, tone, strategy_type) ) AS v(user_id, name, number, script, edit_script, usage_type, tone, strategy_type)
WHERE NOT EXISTS (SELECT 1 FROM card.nego_cards WHERE user_id IS NULL AND deleted = FALSE); WHERE NOT EXISTS (SELECT 1 FROM card.nego_cards WHERE user_id IS NULL AND deleted = FALSE);
@ -172,8 +173,11 @@ WHERE NOT EXISTS (SELECT 1 FROM card.wild_cards WHERE user_id IS NULL AND delete
-- 와일드카드 전술 운영 규칙(tactic) — init-data.sql 과 동일(멱등). -- 와일드카드 전술 운영 규칙(tactic) — init-data.sql 과 동일(멱등).
UPDATE card.wild_cards SET tactic = '{"closing": true}'::jsonb UPDATE card.wild_cards SET tactic = '{"closing": true}'::jsonb
WHERE number IN ('WC-03', 'WC-05') AND user_id IS NULL AND deleted = FALSE WHERE number IN ('WC-01', 'WC-03', 'WC-04') AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb);
UPDATE card.wild_cards SET tactic = '{"closing": true, "min_round": 2}'::jsonb
WHERE number = 'WC-05' AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb); AND (tactic IS NULL OR tactic = '{}'::jsonb);
UPDATE card.wild_cards SET tactic = '{"min_round": 2}'::jsonb UPDATE card.wild_cards SET tactic = '{"min_round": 2}'::jsonb
WHERE number = 'WC-04' AND user_id IS NULL AND deleted = FALSE WHERE number = 'WC-02' AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb); AND (tactic IS NULL OR tactic = '{}'::jsonb);

View File

@ -122,20 +122,20 @@ SELECT * FROM (VALUES
-- 10. 향후 거래 연계 — tone 4(중립) · strategy 4(협력) -- 10. 향후 거래 연계 — tone 4(중립) · strategy 4(협력)
(NULL::uuid, '향후 거래 연계', 'NGC-010', (NULL::uuid, '향후 거래 연계', 'NGC-010',
'이번 거래의 가격을 {target_price}원(VAT별도)으로 조정하는 대신, {customer_condition}을 함께 검토해 주실 것을 제안 드립니다. '이번 거래의 가격을 {anchor_price}원(VAT별도)으로 조정하는 대신, {customer_condition}을 함께 검토해 주실 것을 제안 드립니다.
당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다.', 당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다.',
'[{"type": "paragraph", "children": [{"text": "이번 거래의 가격을 "}, {"type": "variable", "name": "target_price", "label": "목표가격(고객사 지향가)", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로 조정하는 대신, "}, {"type": "variable", "name": "customer_condition", "label": "고객사 교환·요구 조건", "children": [{"text": ""}], "style": {"bold": true}}, {"text": "을 함께 검토해 주실 것을 제안 드립니다."}]}, {"type": "paragraph", "children": [{"text": "당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다."}]}]'::jsonb, '[{"type": "paragraph", "children": [{"text": "이번 거래의 가격을 "}, {"type": "variable", "name": "anchor_price", "label": "앵커가", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로 조정하는 대신, "}, {"type": "variable", "name": "customer_condition", "label": "고객사 교환·요구 조건", "children": [{"text": ""}], "style": {"bold": true}}, {"text": "을 함께 검토해 주실 것을 제안 드립니다."}]}, {"type": "paragraph", "children": [{"text": "당장의 단가 한 건만 보기보다 향후 이어질 거래까지 함께 고려한다면, 양사 모두에게 더 큰 가치를 만들 수 있습니다. 이번 합의를 장기적 관계의 출발점으로 삼아, 서로에게 이익이 되는 구조를 함께 설계하기를 바랍니다."}]}]'::jsonb,
1, 4, 4), 1, 4, 4),
-- 11. 양보 가치 강조 — tone 4(중립) · strategy 4(협력) -- 11. 양보 가치 강조 — tone 4(중립) · strategy 4(협력)
(NULL::uuid, '양보 가치 강조', 'NGC-011', (NULL::uuid, '양보 가치 강조', 'NGC-011',
'이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다. '이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다.
{target_price}원(VAT별도)으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다. {anchor_price}원(VAT별도)으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다.
당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다.', 당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다.',
'[{"type": "paragraph", "children": [{"text": "이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다."}]}, {"type": "paragraph", "children": [{"type": "variable", "name": "target_price", "label": "목표가격(고객사 지향가)", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정", "bold": true}, {"text": "이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다."}]}, {"type": "paragraph", "children": [{"text": "당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다."}]}]'::jsonb, '[{"type": "paragraph", "children": [{"text": "이번 조정은 당사에 결코 작은 일이 아님을 먼저 말씀드리고 싶습니다."}]}, {"type": "paragraph", "children": [{"type": "variable", "name": "anchor_price", "label": "앵커가", "children": [{"text": ""}], "suffix": "원(VAT별도)", "style": {"bold": true, "color": "red"}}, {"text": "으로의 조정은 당사 수익 구조상 상당한 부담을 감수한 결정", "bold": true}, {"text": "이며, 내부적으로도 쉽지 않은 승인 과정을 거쳤습니다. 이는 곧 귀사께서 그만큼 실질적인 혜택을 얻으시게 된다는 의미이기도 합니다."}]}, {"type": "paragraph", "children": [{"text": "당사가 감수한 만큼, 귀사께서도 이에 상응하는 조건으로 화답해 주시기를 정중히 요청 드립니다."}]}]'::jsonb,
1, 4, 4) 1, 4, 4)
) AS v(user_id, name, number, script, edit_script, usage_type, tone, strategy_type) ) AS v(user_id, name, number, script, edit_script, usage_type, tone, strategy_type)
WHERE NOT EXISTS (SELECT 1 FROM card.nego_cards WHERE user_id IS NULL AND deleted = FALSE); WHERE NOT EXISTS (SELECT 1 FROM card.nego_cards WHERE user_id IS NULL AND deleted = FALSE);
@ -196,11 +196,16 @@ WHERE NOT EXISTS (SELECT 1 FROM card.wild_cards WHERE user_id IS NULL AND delete
-- 와일드카드 전술 운영 규칙(tactic) — 제안가는 script 변수 파싱으로 결정되므로, -- 와일드카드 전술 운영 규칙(tactic) — 제안가는 script 변수 파싱으로 결정되므로,
-- 문장으로 알 수 없는 규칙(종결 전용·최소 라운드)만 여기 시드한다. 멱등(미설정 행만 갱신). -- 문장으로 알 수 없는 규칙(종결 전용·최소 라운드)만 여기 시드한다. 멱등(미설정 행만 갱신).
-- WC-03 최종 통보 · WC-05 중간값 절충 = 종결 국면 전용(마지막 한 방으로 예약) -- 목표가 제시 카드(WC-01·03·04)는 종결 전용 — 협상 중반에 목표가를 부르면 이후 올려줄 금액이
-- WC-04 단계적 인하 제안 = 2라운드부터("당초 적정가 → 한발 물러서" 서사) -- 없어져 남은 카드가 같은 값만 반복하게 된다. 제안은 앵커가 → 중간가 → 목표가로 수렴시킨다.
-- WC-05 중간값 절충 = 종결 전용 + 2라운드부터(간격이 좁혀진 뒤라야 절충이 성립)
-- WC-02 역제안가 제시 = 2라운드부터(상대 제안을 받아본 뒤 하는 것)
UPDATE card.wild_cards SET tactic = '{"closing": true}'::jsonb UPDATE card.wild_cards SET tactic = '{"closing": true}'::jsonb
WHERE number IN ('WC-03', 'WC-05') AND user_id IS NULL AND deleted = FALSE WHERE number IN ('WC-01', 'WC-03', 'WC-04') AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb);
UPDATE card.wild_cards SET tactic = '{"closing": true, "min_round": 2}'::jsonb
WHERE number = 'WC-05' AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb); AND (tactic IS NULL OR tactic = '{}'::jsonb);
UPDATE card.wild_cards SET tactic = '{"min_round": 2}'::jsonb UPDATE card.wild_cards SET tactic = '{"min_round": 2}'::jsonb
WHERE number = 'WC-04' AND user_id IS NULL AND deleted = FALSE WHERE number = 'WC-02' AND user_id IS NULL AND deleted = FALSE
AND (tactic IS NULL OR tactic = '{}'::jsonb); AND (tactic IS NULL OR tactic = '{}'::jsonb);