Commit Graph

59 Commits

Author SHA1 Message Date
민헌
82f091c419 docs: 공유 ENUM 코드값 계약 문서 추가 (SHARED_ENUMS.md)
backend·negodata·agent 가 공유하는 negosium_db 의 SMALLINT 코드값 단일 출처(SSOT).
backend/common/enums.py 를 기준으로 정리하고, negodata 와의 불일치(SessionStatus 등) 정렬 계획 명시.

- SessionStatus(1~5)·QuotationStatus·QtType·ChatSender/card_type·AccountStatus 등 정식 코드표
- DeliveryType/CardStatus(negodata 정의 채택), TBD 코드, 변경 절차
- 불일치: SessionStatus(🔴 정렬 필수)·ON_HOLD(🟡 합의)·ChatSender 명칭(🟢) / agent 는 learning.* 격리로 충돌 없음

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:54:18 +09:00
696fb24655 Merge pull request 'feat: 협상 채팅(chat) API + 프론트 연동 (agent 위임 · KST 표시)' (#3) from feature/backend into main
Reviewed-on: Negosium/o2o-negosium#3
2026-06-18 05:28:42 +00:00
민헌
16c5fde284 Merge remote-tracking branch 'origin/main' into feature/backend 2026-06-18 14:26:06 +09:00
민헌
ce536b43d6 feat(frontend): 채팅 페이지 API 연동 + KST 시각 표시
- apis/chat 모듈(api/queries/mutations/keys/type) + useChatController(append-only send 주입)
- useChatStore 재배선, list→chat session_id 라우팅 연결, mock 제거
- 마감/종료/권한 시 입력 잠금·목록 복귀, 가격범위 인라인 에러, CHAT_IN_PROGRESS 처리
- list 마감일 KST(Asia/Seoul) 고정 표시(lib/datetime formatKstDateTime)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:25:07 +09:00
민헌
dcce82a630 feat(backend): 협상 채팅(chat) API + agent 위임
- /v1/negotiation/sessions/{id}/chat/{init,messages,send} 추가
- agent(9500) 위임 어댑터(IAgentClient) + mock(use_mock) 격리 → agent 미연동 시 1402 graceful degrade
- negotiation.chats 메시지 영속화(meta JSONB) + 종료 시 세션 입찰/거부 확정(단일 트랜잭션)
- 동시전송 가드(유저 메시지 pre-claim/CHAT_IN_PROGRESS) + 실패 시 롤백, 마감/만료 분기, init 만료 정리
- ChatSender enum, chat 에러코드(1400~1403), chats ORM 모델, AgentConfig
- 테스트 10건(test_chat.py), AGENT_INTEGRATION.md 연동 규약 문서

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:24:57 +09:00
민헌
d199c1dec1 feat(backend): 협상 거부(reject) 기능
- POST /v1/negotiation/sessions/{session_id}/reject (Req_Reject/Res_Reject)
- 참여와 공통 검증(인증/소유/세션상태/견적마감/마감시간)을
  _load_actionable_session 헬퍼로 추출해 participate·reject 재사용
- 거부 불가 상태: 협상완료/미참여/협상거부 → NEGO_NOT_PARTICIPABLE
- 성공 시 세션을 협상거부(5)로 전이하고 reject_reason 저장(최대 255자)
- 빈 사유는 INVALID_REQUEST_DATA

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:20:29 +09:00
민헌
4762da080d chore(backend): 개발용 시드 데이터 스크립트 추가
- backend/scripts/dev_seed.sql: 재실행 안전(고정 UUID)
- 로그인 계정 test01/1234(공급사 1) + 상품6·견적6·세션6
- 비밀번호는 pgcrypto bcrypt(crypt+gen_salt bf) — 백엔드 검증과 호환
- 세션 status/qt_type 다양화, 참여 가능(협상생성+미래마감) 케이스 포함

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:12:42 +09:00
민헌
fab8e5aa53 feat(frontend): 협상 목록/참여/거부 연동
- 세션 목록을 useSessionListQuery 로 서버 조회(필터·정렬·페이지 위임),
  mock 제거. 정수 코드↔한국어 라벨 변환 어댑터(list/lib/adapter)
- 협상 참여: useParticipateMutation, 성공 시 채팅 진입·실패 토스트
- 거부: 사유 입력 팝업(RejectPopup) + useRejectMutation, 상태별 차단 안내
- 선택/상태 검증을 토스트로 일원화(ActionSection 은 버튼만 담당)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:12:31 +09:00
민헌
c0d224ef21 feat(frontend): 인증 연동 (로그인/로그아웃/내정보/라우트 가드)
- 로그인 실연동: 성공 시 access/refresh 토큰 저장, me 캐시 무효화
- SidebarFooter: useMeQuery 로 공급사명 표시, useLogoutMutation 로 로그아웃
- RequireAuth 가드로 /list·/chat 보호, 토큰 없으면 로그인으로
- 인증 만료/폐기 시 로그인 페이지로 이동(setUnauthorizedHandler)
- LoginPage: 이미 로그인 상태면 목록으로 리다이렉트

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:12:23 +09:00
민헌
7bdd10207a feat(frontend): 공통 토스트(sonner)·모달 컴포넌트 추가
- sonner 기반 토스트 래퍼(lib/toast): error/info/success/warning,
  프로젝트 디자인 토큰으로 스타일 통일. Toaster 를 provider 에 마운트
- 공통 Modal 컴포넌트: 반투명 배경 + 배경 클릭/ESC 닫기
- core/Provider import 케이싱 정리(provider)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:12:16 +09:00
민헌
a867daa98f feat(frontend): TanStack Query 기반 apis 레이어 추가
- 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>
2026-06-18 13:12:07 +09:00
민헌
2480a47efe feat(backend): 협상 세션 목록 + 참여 기능
- GET /v1/negotiation/sessions: 로그인 공급사의 세션 목록(필터/정렬/페이지네이션)
  · qt_end_time 은 견적(quotation.end_time) 기준, sessions⨝items⨝quotations 조인
  · status/qt_type 은 정수 코드로 응답(라벨 매핑은 프론트)
- POST /v1/negotiation/sessions/{session_id}/participate: 협상 참여
  · 검증: 소유(공급사 대조)→세션상태→견적마감→마감시간, 에러코드 1300~1304
  · 협상생성→협상중, 견적→견적진행중 (협상중/완료는 무변경 진입)
  · 마감초과 시 협상생성 세션만 미참여로 정리
- DBType.NEGOTIATION/QUOTATION, items/sessions/quotations 모델
- QtType/SessionStatus/QuotationStatus enum, AuthService.authenticate 공통화
- 협상 e2e 테스트(test_negotiation.py)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 12:32:32 +09:00
민헌
16848e9f63 update(front): front 폴더명 frontend로 변경 2026-06-18 11:30:26 +09:00
민헌
698d4e72d4 feat(backend): 로그아웃 + stateful 토큰 검증 (단일 세션 즉시 폐기)
- POST /v1/auth/logout: 저장된 access/refresh 토큰 행 삭제 → 즉시 로그아웃
- /me, refresh 에서 제시된 토큰을 저장된 토큰과 대조(불일치 시 TOKEN_REVOKED=1203)
  → 로그아웃/타기기 재로그인으로 교체된 토큰을 만료 전이라도 차단
- crud get_token 추가, ErrorType.TOKEN_REVOKED(1203) 추가, Res_Logout 프로토콜
- 로그아웃/단일세션 무효화 e2e 테스트 추가 (test_auth.py)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:26:08 +09:00
민헌
23cb8291bc chore(backend): 로컬 실행/부하테스트 스크립트 추가
- run_local_server.sh / run_local_locust.sh / run_local_pgwatch.sh (대화형, 메뉴 선택 방식)
- loadtest: self-register 방식 locustfile (가상 유저가 on_start 에서 계정 생성 → login/me/refresh)
- locust 스크립트가 부하용 공급사 보장·이전 부하계정/토큰 정리·LOAD_SUPPLIER_ID 주입을 자동 처리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:17:37 +09:00
민헌
2832162672 feat(backend): CORS 허용 오리진 설정 추가
- WebServerConfig.cors_origins(list) 추가, config 의 오리진이 있을 때만 CORSMiddleware 적용
- 명시적 오리진이라 allow_credentials=true (Authorization 헤더 허용)
- 로컬 기본값: http://localhost:5173, http://127.0.0.1:5173 (Vite)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:16:43 +09:00
민헌
5940f54d2b feat(backend): supplier_users 기반 인증 재구축 및 단일세션 토큰 저장
- tbl_account 예시 인증 제거, supplier_users 기반으로 일원화(generic 네이밍 재사용)
- DBType USER/PARTNER 분리, AccountStatus/UserRole/TokenType enum 추가
- 보호 요청 시 su_id DB 존재/활성 검증(stateless JWT 빈틈 보완), 공급사명(partner.suppliers) 응답 포함
- 로그인 시 단일 세션 access/refresh 토큰을 supplier_user_tokens 에 저장(재로그인 시 교체)
- greenlet 의존성 추가, 인증 e2e 테스트(test_auth.py) 재작성

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:16:33 +09:00
dd03c2aecd [feat] negodata/front: 상품·협력사 목록 서버 페이지네이션·검색 연동(재사용 useServerList) + 카드·견적 UI
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:03:11 +09:00
7c244bca27 [chore] negodata/front: orval 생성 클라이언트 재생성 (카드 도메인 + 상품 카테고리·협력사 priority 파라미터)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:03:11 +09:00
01e80281d1 [chore] negodata: 데모 시드 데이터 정비
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:00:15 +09:00
e7660b10ac [feat] negodata/backend: 카드 도메인 CRUD 추가 + 견적·auth 보강
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:00:15 +09:00
1fef405e88 [feat] negodata/backend: 상품·협력사 목록 서버 페이지네이션 + 검색/필터(카테고리·priority) + 상품 카테고리 distinct 엔드포인트
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:00:15 +09:00
4587be5844 [refactor] negodata/backend: 공용 PageParams(page/size/skip) + 상태 enum·모델 정비
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:00:15 +09:00
ece24f4067 [chore] negodata: CORS client_url 예시 + 시드 정비 + README DB 절차 갱신
- config.local.toml.example: client_url 추가(CORS 허용 origin), DB명 negosium_db 정정
- postgres-init: 03-seed.sql → 03-seed-negodata.sql (negodata 전용 시드)
- README: DB 준비 절차(스키마+learning+시드) 갱신
- docker-compose 정비

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 15:59:08 +09:00
2470183e0f [fix] negodata/front: 상품·협력사·견적 목록 연동 + 배송형태 서버 enum 코드 전송
- orval 실제 타입(ItemData/SupplierData/QuotationData/QuotationSettingData) 사용,
  응답 봉투 과중첩(.data.data) 제거 → 목록 정상 렌더
- 배송형태(delivery_type) 자유텍스트 → 서버 /v1/enums 코드 select 로 전환
- orval 클라이언트 재생성 (enums 훅, companyData 등)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 15:58:57 +09:00
1f778ab975 [feat] negodata/backend: 상품·협력사·견적 도메인 CRUD + delivery_type 코드화 + 공용 /v1/enums
- item/supplier/quotation/quotation_setting CRUD·service·router 추가
- item protocol delivery_type str→int (ERD/스키마 SMALLINT 일치)
- DeliveryType enum + 한글 라벨, 공용 GET /v1/enums (도메인 코드 메타데이터)
- CompanyBrief → CompanyData 로 *Data 네이밍 통일
- CORS: WebServerConfig.client_url(단일) 도입 (config_models/router)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 15:58:38 +09:00
7e2d5e5978 Merge pull request '프론트엔드: 구조 정비 + 협상 채팅 페이지 (mock UI)' (#2) from feature/chat into main
Reviewed-on: Negosium/o2o-negosium#2
2026-06-17 05:43:28 +00:00
민헌
147f9dd007 feat(front): 협상 채팅 페이지 (mock UI)
- KT-NEGOWIZ /chat 을 현재 아키텍처(Vite·React Router·feature 구조)로 이식
- 사이드 ItemSection(+이미지 확대), 헤더 잔여시간, 채팅(메시지/템플릿/입력), 메뉴 섹션
- 메시지 템플릿: 협상 성공률·협상요약·투찰요약·재협상/재견적 폼
- zustand 스토어 + mock 데이터(정적 쇼케이스, 제출 시 로컬 append)
- Next.js·KT 의존 제거(next/image·navigation, 로고·서비스명·연락처, 팝업 보류)
- ChatPage 배선: ChatContainer / ItemSection / RemainingTime + auth SidebarFooter 재사용

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:38:04 +09:00
민헌
54b44c0877 style(front): 디자인 토큰 정비 (채팅 타이포 + 브랜드 채도 인하)
- 타이포그래피 스케일 추가 (headline/title/body/reject 등) — 채팅에서 사용
- 채팅 영역 스크롤바 스타일(.chat-scroll) 추가
- 브랜드 스케일 채도 추가 인하, surface(콘텐츠 면) 톤 조정

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:37:48 +09:00
e583cd6311 config.local.toml 설정 단일화 . 2026-06-17 11:26:20 +09:00
951d6eab84 Agent 서버 구축: 멀티테넌트 협상 PoC (UCB Q-Table 학습 + /chat + 14 API + 학습검증 하네스), config 단일화(local.toml) + 빌드 경량화 2026-06-17 11:10:03 +09:00
민헌
4d1c6f97c0 refactor(front): 페이지/엔트리 import 경로 갱신
- SidebarFooter(auth)·Provider 이동에 따른 import 경로 반영
- 불필요한 주석 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:49:07 +09:00
민헌
a0f7a229fa style(front): 디자인 토큰 정비
- 브랜드 스케일 채도 약 20%↓ (색상·명도 유지)
- surface(콘텐츠 면 쿨 그레이)·table-header 토큰 추가
- 배너 주석 제거 및 최소화

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:48:38 +09:00
민헌
5eb83f9d54 refactor(front): list — 구조 분리 및 상태 색상 정비
- TableSection에서 컬럼 설정(tableColumns)·날짜 유틸(datetime) 분리
- PageSection → Pagination 개명, 인라인 SVG를 paginationIcons로 분리
- 상태 색상 정비: 협상중=강조(다크), 미참여=회색, 나머지 의미색 유지
- 활성 페이지·목데이터 격리(mocks), 페이지 크기 20 복구, 주석 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:47:47 +09:00
민헌
32db1300e0 refactor(front): auth — SidebarFooter 이동
- SidebarFooter(공급사명·로그아웃)를 list에서 auth로 이동 (도메인 일치)
- useLoginMutation 주석 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:47:38 +09:00
민헌
a56e225032 style(front): 레이아웃에 브랜드 톤 적용
- 헤더 바 bg를 brand(primary)로, 콘텐츠 면 bg를 브랜드 틴트 쿨 그레이(surface)로 변경
- 불필요한 주석 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:47:32 +09:00
민헌
1073888073 refactor(front): 공용 컴포넌트/유틸 구조 정비
- cn·interactive를 components에서 lib로 분리 (컴포넌트와 순수 유틸 경계 정리)
- core/provider.tsx → Provider.tsx 개명 (컴포넌트 파일 PascalCase 통일)
- 불필요한 주석 정리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:47:25 +09:00
212725e5f9 [chore] 추적된 .pyc 제거 + 루트 .gitignore 추가
backend/__pycache__ 등에 추적되던 .pyc 51개를 인덱스에서 제거하고,
루트 .gitignore(__pycache__/, *.py[cod], .venv/, openapi.json, CLAUDE.md)를 추가한다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 08:39:39 +09:00
87524bf6e8 [feat] negodata/front: 프론트 초기 구축 (Vite+React, orval API 클라이언트, 견적/상품/협력사 페이지)
- 라우팅 react-router v7, 서버상태 TanStack Query
- orval 자동 생성 API 클라이언트(src/api/generated)
- 견적/상품/협력사/견적설정 페이지, shadcn UI, 토큰(tokens.css)
- 실행: 루트 docker compose (front :3001), README 그에 맞게 정리
- AI Studio 스캐폴드 잔재 제거(metadata.json, 중복 DESIGN_TOKENS.md), 타이틀 NegoData, vite.config 죽은코드 제거

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 17:18:08 +09:00
민헌
6da8976a20 [feat] front: List/Chat 레이아웃 + 목록 필터 섹션 구현
- layouts: 공통 2분할 레이아웃 MainLayout(좌 사이드바/우 메인, 로고 헤더,
  헤더 아래 콘텐츠 면) + 다크 헤더 바 MainHeaderBar 분리
- pages: ListPage/ChatPage 를 MainLayout 기반으로 구성(견적 선택/협상 잔여 시간 헤더)
- features/list: 필터 섹션 추가 — ListFilter(요소)/FilterSection(컨테이너)/
  filterOptions(데이터)/useListFilterStore(상태), SidebarFooter 분리
- deps: lucide-react 추가(필터 화살표·목록 이동 아이콘)
- refactor: 모든 import 를 @ alias 로 통일
- fix: Button secondary variant hover(=accent 동일색) 및 필터 화살표 hover 색상 보정

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 16:19:57 +09:00
민헌
9de140abd6 [feat] front: 로그인 페이지 구현(로고·폼 조립, 반응형/접근성)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:33:23 +09:00
민헌
09643332f2 [feat] front: 인증(auth) 피처 추가 — 로그인 폼/훅/임시 mutation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:33:23 +09:00
민헌
245c287a9d [refactor] front: 공통 UI를 components 디렉터리로 정리 + Logo 컴포넌트/로고 에셋 추가
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:33:23 +09:00
민헌
7d47227141 [feat] front: Vite/환경변수 타입 선언(vite-env.d.ts) 추가
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:33:23 +09:00
a6731dcb07 quotation_settings에 user_id 컬럼·인덱스 추가
versions 테이블과 동일하게 quotation.quotation_settings 에 user_id (uuid NOT NULL)
컬럼을 추가하고, 조인/조회용 인덱스 idx_quotation_settings_user_id 를 생성한다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:55:59 +09:00
민헌
ba920dfcea [feat] front: react-router 연결 및 Vite 데모 화면 제거
- react-router v7 도입, App.tsx 에서 라우트 정의(/, /list, /chat)
- 기본 진입('/')은 로그인 페이지
- 사용하지 않는 Vite 데모 정리(App.css, assets 삭제)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:27:09 +09:00
민헌
6963f0bd40 [feat] front: 페이지 골격(Login/List/Chat) 추가
- 라우팅 대상 빈 화면 페이지 3종
- named + default export 동시 제공

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:26:57 +09:00
민헌
ec4ee78fcb [feat] front: 공통 UI 컴포넌트(Button/Input) 추가
- 네이티브 element props 상속 + className 병합(무의존 cn 헬퍼)
- Button: variant(primary/secondary/outline/ghost/destructive)/size, hover 톤다운(brand-700)
- React 19 기준 forwardRef 없이 ref 전달

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:26:18 +09:00
민헌
f5721afa21 [fix] front: Vite 8 에서 금지된 local 모드 제거
- Vite 8 은 'local' 을 모드 이름으로 허용하지 않음(.env.local 접미사 충돌)
- dev 스크립트를 'vite --mode local' → 'vite' 로 변경 (.env.local 은 자동 로드)
- README 환경 변수/실행 안내를 실제 동작에 맞게 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:17:35 +09:00
민헌
fbbe8b3427 [refactor] front: 미사용 sidebar 토큰 제거 및 design.md 삭제
- 프로젝트에 사이드바 없음 → --sidebar-* 토큰 및 @theme 매핑 제거
- 토큰 출처 문서(design.md) 삭제

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 11:42:21 +09:00