9.6 KiB
9.6 KiB
협상 QA 체크리스트 (260727 요청 검증)
대상: negodata 어드민(:3000) + negosium 공급사 포털(:3300). 두 앱을 함께 돌려야 하는 플로우라 루트
docs/에 둔다. 형식: 케이스별~하면 → ~나와야 한다. 근거는 코드 검증(2026-07-30) 기준. ⚠=현재 알려진 이슈. 런타임 주의: negosium front/backend는 이미지 빌드라 코드 수정은 재빌드해야 반영된다.
0. 요청사항 반영 현황 (코드 검증 결과, Excel 상태열 아님)
| # | 요청 | 판정 | 비고 |
|---|---|---|---|
| 2 | 견적관리 리스트+히스토리·상세 | ✅ | /quotation + ?detail= 시트(협상현황/대화/카드, 라운드 타임라인) |
| 3 | 재협상 리스트·심사 | ✅ | /renegotiation 대기/승인/반려 |
| 4 | MD→구매담당자·판매가 미노출·위치 | ✅ | |
| 5/23 | 목표가=매입가×(1−네고율) 자동 | ✅ | 재/재견적 한정, 네고율=견적세팅 목표마진 |
| 6 | 공급가=매입가 일원화 | ⚙ 설정 | 코드 지원됨(hideCls). IMK hidden_fields에 "price" 추가하면 매입가만 남음 |
| 7 | 최저가 크롤 + VAT산식 | ⚠ 인프라 / 논이슈 | VAT는 설정·아이템별 처리(논이슈). 단 dev의 lps-worker 크래시+수집테이블 0행 → 수집 파이프라인 확인 필요 |
| 8 | 신규 상품 공급사 입력칸 | ✅ | |
| 9 | SG명/유통레벨 콤보·취급상품 삭제 | ❌ 미구현 | §9 참조 |
| 10 | 리드타임→표준납기 | ✅ 수정 | Summary.tsx 하드코딩 라벨 회사설정 반영으로 수정(2026-07-30) |
| 11 | 단가 VAT별도 | ✅ | 회사설정 item_vat_yn 동적(IMK는 vat_yn hidden) |
| 12 | 앵커 10원 반올림 | ✅ | calc_anchoring_price + 카드 카운터(compute_counter) + 와일드카드 1%(2026-07-31 수정) 모두 10원 반올림 |
| 13 | 절충안 계산식 | ✅ | compute_counter 점검, 버그 없음 |
| 14/17 | 결렬 희망가 입력란 통일 | ✅ | 단일 RejectForm |
| 15 | 마무리 배송 콤보/기타의견/투찰요약 | ✅ | ExtraInfoBar가 session_fields select 렌더 → 콤보 [직납/IMK배송/IMK집배송] |
| 16 | 제안가 갭·반올림 | ✅ | 갭은 정상(목표가=후보 min×수수료). 봇 제안가(카운터·와일드카드 1%)도 10원 반올림 반영(2026-07-31) |
| 18/22 | 성공률 기준·결렬 무관 | ✅ | 게이지는 참고용, 판정과 무관(§D). 타결=목표가 아래로/봇 카운터 수락, 결렬=카드3+최종제안 소진까지 목표가 위 |
| 19/25 | 종료 의견 단계 | ✅ | 타결 ExtraInfoBar(custom.opinion)+결렬 RejectForm 의견 |
| 20 | 결렬사유 상시노출·필수 | ✅ 검증 | 결렬 세션 9/9 사유 존재. §20 참조 |
| 21 | 카드 3회 초과 | ✅ 정상 | 3회=협상카드 한도. 와일드카드·최종제안은 별도로 붙는 구조라 보이는 카드가 3장을 넘을 수 있음(§21) |
| 24 | 목표가 필드 1→3.낙찰기준 이동 | ✅ |
A. 견적 생성 (어드민)
- A1 재/재견적에서 매입가 10,000·네고율(견적세팅 목표마진) 2% 입력 → 목표가(구매담당자 제시가) 필드에 9,800 자동 채움(10원 반올림)
- A2 목표가 직접 안 건드리고 생성 →
md_price=null로 전송, 서버가 후보 최솟값으로 재산정 - A3 신규협상/신규견적 → 매입가 후보 빠지고 인터넷최저가만 사용 → 자동 목표가가 매입가 기반이 아님(A1과 다른 게 정상)
- A4 1.기본정보엔 목표가 없어야 / 3.낙찰기준 스텝에 목표가+산정후보 나와야
- A5 판매가 입력칸 없어야 / 라벨 "구매담당자 제시가"
B. 앵커·제안가
- B1 협상 시작 → 세션 앵커가 = 목표가×(1−1%), 끝자리 0 (예 목표 7,650 → 앵커 7,570)
- B2 봇 재제안가 전부 끝자리 0 — 카드 카운터(절충가·목표가 제시)와 와일드카드 1% 인하가 포함 (예 제시 15,555 → 1% 인하가 15,400). 1원 단위가 보이면 불량
C. 협상 진행 (실시간 챗, 공급사 포털)
- C1 제시가 ≤ 앵커가 → 즉시 협상완료(투찰 확정), 성공률 99
- C2 앵커가 < 제시가 ≤ 앵커×1.02 → 와일드카드 1% 인하 요청(세션 1회), 성공률 99~80
- C3 앵커×1.02 초과 → 일반 협상카드로 재제안(최대 3번), 성공률 표시(제시가 낮을수록↑)
- C4 카드 소진 또는 재제안 3번 후에도 앵커 밑 못 내림 → 협상 실패(결렬, 투찰 없음)
- C5 카드 사용한도 3은 협상카드에만 적용. 와일드카드·최종제안은 별도로 붙어 공급사가 보는 카드가 3장을 넘을 수 있음(정상, §21)
- C6 단가는 VAT별도 표기(IMK는 VAT 라벨 자체 숨김)
D. 타결/결렬 판정 & 성공률 게이지
- 판정 규칙: 유저가 목표가 아래로 내리거나 봇이 되받은 제시가(카운터)를 수락하면 타결. 카드(3장)+최종제안까지 다 소진될 때까지 목표가 위에서 버티면 결렬.
- D1 성공률 게이지는 참고용일 뿐 판정과 무관 — 제시가 낮을수록 게이지↑(상한 99, 100% 도달 안 함).
- D2 성공률 낮아도 무조건 결렬 아님. 최종 마감(낙찰/개찰)은 별도 기준(§G).
E. 협상 타결(완료) 마무리
- E1 협상완료 → 부가정보 입력 단계 등장 (표준납기·최소주문수량·발주배수·배송유형·의견)
- E2 배송유형 → **콤보 [직납/IMK배송/IMK집배송]**로 떠야 (자유입력·다른 라벨이면 불량)
- E3 의견(선택) 작성 →
custom.opinion저장돼야 - E4 입력 완료 → 투찰결과 요약 갱신 후 최종 안내, 요약에 부가정보·의견 반영
- E5 어드민 상세(협상현황/요약)에서 부가정보 표시+잠금(읽기전용)
F. 협상 결렬(실패)
- F1 결렬 → 결렬 사유 입력 단계 항상 노출 + 필수(견적/유형 무관 동일 폼)
- F2 사유 프리셋(단가인상/수량/단종/품절)+기타, 기타 선택 시 사유 텍스트 필수
- F3 희망가격 입력 = 단일 폼(RSP/CM 동일)
- F4 의견(선택) 작성 가능
- F5 검증: 결렬(협상거부) 세션은 100% 사유가 기록돼야 (사유 없는 결렬 세션 = 불량). §20
G. 마감 · 낙찰/개찰
- G1 투찰가 ≤ 앵커가 → 낙찰
- G2 앵커~목표가 → 1:1은 사용자 지정(mid_action), 1:N은 낙찰
- G3 목표가 초과 → 1:1 사용자 지정(over_action, 관례 개찰), 1:N 낙찰
- G4 동가(최저 2곳+)·전원 미응찰·협상거부 → 개찰(낙찰자 미정, 결렬 아님) / 마감사유 라벨 정확히
H. 재협상 요청·심사 (공급사→어드민)
- H1 개찰 마감 + 본인 마지막 라운드 → 재협상 요청 가능(사유+희망가), 담당자 알림 1건
- H2 낙찰건/남의 세션 요청 → 거부
- H3 같은 세션 2회 요청 → 2번째 거부; 철회 후 재요청 가능
- H4 어드민 /renegotiation 대기 탭 접수 → 승인 시 다음 차수 견적 생성, 반려 시 사유 필수
알려진 이슈 상세
§9. 협력사 SG명/유통레벨 콤보·취급상품 삭제 — 미구현
요청 4가지 모두 현재 구조와 다르다:
- 분류카테고리 → SG명: 지금 '분류카테고리'는 입력 필드가 아니라 취급상품에서 파생 집계되는 읽기전용 값(
SupplierItemsManager.tsx). 회사 라벨(labels.category)로 "SG명" 표기만 되지, 직접 고르는 필드가 아님. - 선택콤보(취급 SG명): 등록된 SG명 중 선택하는 콤보 없음.
- 유통레벨 콤보(제조/총판/대리점/일반유통): 없음. 유사한 건 취급상품별 공급유형 콤보인데 값이 다름(유통/제조/총판/없음). '대리점'·'일반유통' 값 자체가 코드에 없음. IMK 설정의
supplier_fields.distribution_level은 콤보가 아니라 텍스트 커스텀 필드. - 취급상품 칸 삭제: 삭제 안 됨(등록/수정폼·엑셀업로드에 그대로).
- 근본: IMK는 SG명·유통레벨을 **협력사 레벨 속성(콤보)**으로 두고 취급상품 목록은 없애길 원함. 현재는 반대로 취급상품(supplier_items)에서 카테고리·공급유형을 파생하는 모델. → 데이터 모델 전환이 필요한 작업.
§20. 결렬 사유 상시 노출·필수 — 검증 완료
- agent의 모든 실패 경로가 단일 step
"협상실패"(chat_end)로 수렴 → backend가 rejectRSP/CM로 무조건 매핑 → 프론트 통일 RejectForm(사유 필수). 세션 상태 분기 없음. - 실데이터: 협상거부(status=5) 9건 전부 reject_reason 존재, 사유 없는 결렬 0건.
- 원 버그의 "견적마다 상이"는 대화 중 결렬(사유 있음) vs 미참여/마감 자동종료(대화 자체 없음 → 사유 없음)의 구분이었을 뿐, 결렬 플로우는 일관됨.
§21. 카드 3회 초과 — 정상 동작(버그 아님)
card_count=3은 협상카드 사용 한도다. 와일드카드와 최종제안(종결)은 이 한도와 별개로 각각 붙는 구조라, 공급사가 보는 카드가 3장을 넘을 수 있다.
- 와일드카드 1장(1% 인하/동적 카운터) — 협상카드 카운트와 별개.
- 최종제안 1장(중간값 절충/최후통첩) — 카드 소진 후 마지막 국면에 별도로 붙음. → 협상카드 3 + 와일드 1 + 최종제안 1 = 최대 5장 노출(예: EST-202607-4DB5).
- 참고(엣지): 세션에 견적세팅(card_count)이 연결 안 되면 한도가 안 걸릴 수 있으니, 설정이 항상 세션에 물리는지만 확인.