- 회사 설정 hidden_fields 신설: 상품 목록·등록폼·엑셀 양식에서 감추고 목표가 후보에서도 제외
- 용어 카탈로그 9→37개(상품·협력사·견적 그룹), 목록·폼·엑셀 헤더 배선
- 엑셀 '최저한도' → '인터넷 최저가' 표기 정정(구양식 헤더는 alias 유지), 공급사 컬럼 검증 유지
- 목표가 산정내역에 적용 모드·숨김 필드 반영, 목표가 상한 라벨에 산식(상품단가×2) 표기
- 공급사 포털: 초청 링크 session_id 로 로그인 전 회사 브랜딩 조회(무인증 엔드포인트), 기본 브랜드 negotium 워드마크, negotium·AI O2O 크레딧 표기
- 목록 테이블 뷰포트 기준 전환·툴바 줄바꿈·협상현황 카드뷰로 모바일/태블릿 대응
- 이용안내 FAQ 탭 추가, 이용안내·회사설정 탭 URL 쿼리 동기화 및 빠른이동 등록
프론트 QtType 이 재협상·재견적(1·2)만 정의해, 신규협상(3)/신규견적(4)
세션은 목록 '구분'이 '-' 로 깨지고 필터로도 걸러지지 않았다.
backend·negodata enum 과 동일하게 4종으로 맞춘다.
- QtType/QT_TYPE_LABEL 에 NEW_NEGO(3)·NEW_QUOTE(4) 추가 → 목록 표시 정상화.
- filterOptions '구분' 에 신규견적·신규협상 노출 → 필터 선택 가능.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
목록 진입 시 "지금 할 일"이 먼저 보이도록 기본 정렬을 개선하고,
사용자가 마감일로 직접 훑어볼 수 있는 전체 정렬 모드를 추가한다.
- 기본(order 미지정): 협상생성·협상중을 상단 그룹으로 마감 임박순,
종료(완료·미참여·거부)는 하단 그룹으로 최근 마감순. 동일 마감은
session_id 로 tie-break 하여 페이지네이션 안정화.
- order=asc/desc: 그룹 구분 없이 전체를 마감(qt_end_time) 기준으로 정렬.
- router: order 기본값을 "asc" → None(Optional) 로 변경해 "그룹 기본"과
"명시적 전체 정렬"을 구분.
- frontend: SessionListParams.order 주석을 새 계약에 맞게 갱신(타입 무변경).
- tests: 기본=그룹 / 파라미터=전체 정렬 검증으로 분리(21 passed).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- init 에서 미참여/거부(4·5) 세션 진입을 NEGO_NOT_PARTICIPABLE 로 차단
(participate/reject 와 동일 규칙). 프론트는 목록으로 복귀 처리.
- init 을 '진입 스냅샷'으로 격리: 화면 도중·포커스 재조회 제거, 언마운트 시
캐시 비움 → 정상 종료 후 튕김 방지 + 재진입 시 진입 게이트 재적용.
- 인디케이터를 session_status 직접 비교 → wasInProgress sticky 플래그로 전환:
진행 화면에서 실시간 완료돼도 유지, 완료/거부 결과 열람 재진입 시엔 숨김.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
KT-NEGOWIZ fe_v2 의 서비스 안내 팝업을 우리 구조로 이식.
- frontend: GuideContent(공용 본문, VAT/배송비는 chat init 메타로 동적 표시)
+ ServiceInfoPopup(채팅 진입 시 자동 — 안내 보지 않기/오늘 하루 보지 않기)
+ ServiceGuidePopup(메뉴 유의사항·이용 가이드 버튼 수동 — X/배경/ESC 닫기)
+ useServiceInfoPopup 훅(서버 상태 + localStorage 오늘 하루)
+ apis/auth 에 popupStatus 쿼리·hidePopup 뮤테이션, 헬프데스크 연락처 반영,
한국어 단어 잘림 방지(break-keep)
- backend: GET /v1/auth/popup/status, POST /v1/auth/popup/hide
(authenticate 공통 인증 + supplier_users.hide_service_info 영구 저장), 테스트 4건
- db: supplier_users.hide_service_info 컬럼 — 00-init 테이블 정의 갱신,
기존 DB 보정은 alters/2026-07-07-supplier-users-hide-service-info.sql 별도 파일
(기준선 이후 보정 ALTER 는 alters/ 파일로 관리하도록 규칙 변경)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 반응형: 최소 폭 1350→1024px, max-[1350px]/max-[1180px] 2단계 축소
- 사이드바 350→310→280, 우측 메뉴 360→320→280, 채팅 거터 140/126→80/72→48/40 (헤더 패딩 동기)
- 가격·할인율 입력 min-w 480→420→320, 가운데 버튼 패딩·최소폭 축소, 상품목록 버튼 1180px 미만 아이콘만
- 상품 이미지 220→200, 사이드바 정보 행 값 영역 고정 150px → flex-1
- 리드타임: formatLeadTime 헬퍼 신설 — 좌측 상품정보·협상 결과 요약 카드에 "일" 접미 표시
- 인디케이터: init 의 session_status 를 스토어에 적재, 협상중(IN_PROGRESS) 세션에서만 표시
- 사이드바 정보 영역 의미 없는 가로 스크롤 제거 (shrink 금지 컬럼 + overflow-x 자동 계산이 원인)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
다른 공급사 소유(또는 없는) session_id 로 /chat 진입 시 일반 에러+재시도 대신
'잘못된 접근입니다.' 토스트를 띄우고 협상 목록(/list)으로 돌려보낸다.
로그인은 유효하므로 로그아웃하지 않는다(인증≠인가 — 로그아웃은 401/403/43x 토큰
오류에서만, 기존 인터셉터 동작 유지).
- useChatController: 진입 로드(init/messages) 에러가 NEGO_FORBIDDEN(1300)/
NEGO_NOT_FOUND(1304) 이면 토스트 후 /list 로 replace 이동(ref 가드로 1회).
리다이렉트 동안 스피너 유지(ErrorPage 깜빡임 방지), 그 외 서버/네트워크 에러는
기존 ErrorPage(재시도) 유지.
- chat.queries: init/messages 쿼리에 retry 추가 — 1300/1304 는 재시도해도 안 바뀌어
즉시 실패시켜 목록 복귀 지연 제거(그 외 에러는 기존 재시도 유지).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ErrorPage 컴포넌트 추가: init/messages 로드 실패(서버/네트워크) 시 ChatContainer 가 에러 화면+재시도(refetch) 렌더 (기존엔 빈 채팅처럼 보임)
- 대기 표시: 채팅 영역 '협상 중' 타이핑 버블 + 입력 버튼 자리 '...' 점 애니메이션
- desync 에러코드(CHAT_INPUT_MODE_MISMATCH 1404 / CHAT_AGENT_TIMEOUT 1405) 추가 및 메시지
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- auth/negotiation 도메인별 api/keys/queries/mutations/type 5파일 구조
- axios 인스턴스: access token 주입, 434 만료 시 refresh 자동 재발급(단일 비행)
후 원요청 재시도, 433/435/1203(TOKEN_REVOKED) 시 세션 종료 처리
- HTTP 200 + result.success=false 비즈니스 에러를 ApiError 로 변환,
에러코드별 한국어 메시지 맵(getApiErrorMessage) 제공
- 토큰 localStorage 저장소(tokenStorage)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>