Commit Graph

86 Commits

Author SHA1 Message Date
0c6a002e29 [fix] negodata/backend: 시각 컬럼 timestamptz 전환 + naive 변환 제거
- models.py: created_at/updated_at/last_accessed_at/start_time/end_time/bid_at
  DateTime → DateTime(timezone=True)
- quotation_service: tz-aware 입력을 naive 로 깎던 _naive_utc 제거(컬럼이 tz-aware라 불필요),
  start_time/end_time 직접 사용. negosium_db 는 UTC 고정.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 15:30:33 +09:00
aed8364b40 Merge remote-tracking branch 'origin/main' into feature/negodata 2026-06-26 14:30:29 +09:00
7e0f88ca03 [fix] 견적 자동마감 동시성·정합성 + 프론트 안정화 (코드리뷰 후속)
백엔드 close_and_decide 경로:
- 동시 이중 마감 가드: 마감 판정 전 원자적 CLOSED 선점(claim)으로 두 크론 잡·수동마감 경합 직렬화
- 재생성 실패 표면화: regenerate_next_round 결과 검사 → 실패 시 REGEN_FAILED 반환(체인 끊김 은폐 방지)
- 차수 충돌 방지: 다음 라운드 = 체인 최신 round+1(chain_max_round 기준)
- 재생성 사유 집계 정밀화: 미참여/동가를 양성 표식으로 구분(단독낙찰·거부 오집계 제거)
- 재생성 라운드 최소 협상기간 하한(즉시 재마감 캐스케이드 방지)
- 잡 루프 per-item 예외 격리(한 건 실패가 배치 전체를 멈추지 않음)

프론트:
- useChatController: 무권한 가드를 sessionId 별로 추적해 세션 변경 시 자연 해제
- useScrollLock: 마지막 해제를 rAF 로 지연해 재마운트 사이 일시적 잠금 해제 방지
- quotation 상세 쿼리 placeholderData 로 라운드 전환 중 시트 유지

테스트:
- 신규 test_close_and_decide_fixes.py(동시성·차수·집계·기간 하한 검증)
- conftest 결함 수정(존재하지 않는 tbl_account TRUNCATE 제거, companies.status 명시)
- stale 테스트 갱신(test_quotation_create 를 타입드 Req/신규 응답 형식에 맞게 재작성)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 17:22:21 +09:00
05fe0de5ce [feat] negodata/front: 협상 채팅·견적 리스트 개선 및 404 페이지 추가
- 협상 채팅 말풍선에서 협력사 제시가 마스킹 + 챗버블 컴포넌트 분리
- 견적 리스트에 재생성된 다음 차수 표시
- 매칭 없는 경로용 404 폴백 페이지 추가
- 견적 재생성 모달 너비 확대

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:50:36 +09:00
9f947e4823 [feat] negodata/front: 견적 재생성·차수 체인 UI + 담당자/메모 + 스크롤·목업 정비
- 견적 재생성(다음 견적) 엔드포인트 연동 모달: 연결 공급사+협상단계 표시, 마지막 차수에서만
- 차수 체인 타임라인/견적번호 클릭 필터, 생성 응답 슬림(qt_id/session_count) 반영
- 상세 시트 스크롤 수정(min-h-0)·배경 스크롤 락(useScrollLock)·헤더2:탭1 비율
- 담당자=로그인 유저(store) 자동 전송 + 생성 모달 메모 입력 추가
- 목업/가짜 폴백 제거(담당자·견적명·번호·메모 → '-'), 시드 회사 placeholder UUID→실 UUID
- 견적상태 CREATED 칩 pulse 제거

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:57:29 +09:00
7f948075e5 [feat] negodata/backend: 견적 자동마감 스케줄러 + 다음 라운드 재생성(자동/수동)
- APScheduler 크론(KST 5분): 마감일 지난 견적 / 모든 세션 종결 견적 → close_and_decide
- 마감 판정: 단독 최저가 낙찰 확정 / 동가·전원미참여 다음 라운드 재생성 / 거부·한도 마감
- 재생성: 같은 견적번호 체인(round+1, 이름 '(N차)'), 공급사 수로 재협상·재견적, 사유별 한도(미참여1+동가1)
- 수동 재생성 POST /regenerate/{qt_id} (마지막 차수만 허용)
- CloseOutcome enum + 잡 결과별 로그

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:36:22 +09:00
d47476dc04 [refactor] negodata/backend: 서비스 계층 입력을 dict→타입드 Req 패킷으로 통일
라우터가 req.model_dump(exclude_unset=True)로 dict를 만들어 넘기던 것을
req(Req_*) 객체 그대로 전달하도록 변경. 서비스 시그니처를 전부 타입드로 통일.

- create 5개(quotation/card/item/supplier/quotation_setting): ORM은 명시 kwargs
  조립(item만 컬럼 16개라 model_dump 펼침). 경계 검증·타입 유지, **data 결합 제거.
- update 4개: 서비스가 req 받아 내부에서 model_dump(exclude_unset=True) 생성 후
  CRUD(dict)로 전달 — 공식 PATCH 메커니즘 유지.
- 서비스 계층 data: dict 시그니처 0개. CRUD는 dict 유지(의도).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 09:27:04 +09:00
5406094ea1 [wip] negodata/backend: 견적 마감 스케줄러
- scheduler/(__init__·jobs): 마감 처리·낙찰자 선정 잡
- quotation_crud·service: 스케줄러 연동 조회/마감 로직
- web_main·requirements·docker-compose·config: 스케줄러 기동 설정

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:38:02 +09:00
ae103fd0f1 [refactor] negodata/front: 전역 타입 정리 — 공유(2+) 타입만 글로벌, 중복 제거
- src/types.ts: DB 미러 중복 제거, generated DTO 기반 별칭만(Product/Partner/NegotiationCard/PageType)
- products/partners 의 로컬 Product/Partner 중복 → 글로벌 단일 정본 재수출

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:06:37 +09:00
eb6612af1c [refactor] negodata: 도메인 코드값 enum 정비 — 백엔드 정본 + 프론트 생성타입 사용
- 백엔드: 도메인 enum CodeEnum 상속(x-enum-varnames) → orval이 이름 있는 enum 생성. 응답 필드 enum 타입 지정(요청은 int 유지). ENUM_LABELS/DOMAIN_ENUMS·/v1/enums 제거
- 프론트: 생성 enum + 라벨맵으로 교체(매직넘버·발명 어휘 제거), 견적·세션 상태 코드화, role/delivery 라벨 프론트 소유
- 동반 정리: unwrap 캐스트·목업(buildSessions·데모)·死코드 제거, mapItem toMinPrice dedupe

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:06:26 +09:00
6fa024137f [feat] negodata: 견적·카드 검색/필터 서버사이드 전환 + 견적 상세 Sheet 리팩터
- 백엔드: quotation 목록 search 파라미터(name/number ILIKE) 추가; card 목록 is_wildcard 탭 필터 + total_nego/total_wild 탭 카운트 추가; status/type 코드 int 비교 보정
- 프론트: cards/quotation 검색·상태·유형 필터·페이지네이션을 useServerList 기반 서버사이드로 전환; 엔터 즉시검색 + 디바운스 500ms·최소 2글자; 죽은 client 필터 훅(useCardFilters/useQuotationFilters) 제거
- generated 파라미터/응답 타입 손보강(listCardsParams.is_wildcard, listQuotationsParams.search, resCardList.total_nego/total_wild) — orval 재생성 시 동일
- 견적 상세 Drawer→Sheet 분리, useOverlayParams→useOverlayRouter, CreateQuotationWizard→QuotationCreateModal

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 17:03:53 +09:00
b65de5a5f2 Merge branch 'main' of https://gitea.o2o.kr/Negosium/o2o-negosium 2026-06-18 18:59:08 +09:00
cb3adf6d2e 버그 수정중 . 2026-06-18 18:59:06 +09:00
b45889ec0a [feat] negodata: chats.meta 컬럼 추가 + 견적생성 에러 응답패킷 규약대로 표기
- negotiation.chats 에 meta(JSONB) 추가 — 말풍선 표현 데이터(script/step/input_mode 등)
- 견적생성 실패 토스트를 result.code/desc + msg 규약대로 표시(HTTP 200·success=false 포함)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:45:17 +09:00
06c2481fe7 [fix] negodata/front: 세션상태 라벨을 SHARED_ENUMS.md 5-state로 정렬
- SESSION_STATUS_LABEL 옛 3-state(1협상중·2협상종료·3협상거부) → 정본 5-state
  (1협상생성·2협상중·3협상완료·4미참여·5협상거부, 서버 /v1/enums·백엔드 SessionStatus 미러)
- 코드→라벨 단일 진입점 sessionStatusLabel() 추가, 드로어 인라인 매핑 제거
- '협상종료' 표기 → '협상완료'(DONE) 통일, ChatSession status 유니온 정렬

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:43:20 +09:00
088c57f415 Merge branch 'main' of https://gitea.o2o.kr/Negosium/o2o-negosium
# Conflicts:
#	postgres-init/03-seed-negodata.sql
2026-06-18 17:53:03 +09:00
4f0e4c29ce [feat] negodata: 견적목록 상품조인 + 견적/카드 페이지네이션 + 견적중단 서버연동 + 발의→등록
- 견적 목록에 대표 상품(세션 item) 조인 노출 → '대상 상품 확인 불가' 해소
  (backend protocol/crud/service + orval 재생성 + front mapQuotation 매핑)
- 견적·협상카드 목록 클라이언트 페이지네이션 추가 (useClientPagination)
- 견적중단을 서버 stop_quotation 호출로 영속 처리(상태=견적마감)
- 신규 협상견적 라벨 발의→등록 통일
- 발의 위저드 카드선택에 협상/와일드 구분 뱃지 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 17:46:18 +09:00
f924c0aa59 Merge branch 'main' of https://gitea.o2o.kr/Negosium/o2o-negosium 2026-06-18 17:05:24 +09:00
b0b787a8ce cors 문제 해결 . 2026-06-18 16:30:03 +09:00
7186446068 [feat] negodata/front: 협상대화 카드내용 렌더 + 견적상세 헤더·테이블 UI 정리
- 협상대화: 사용 카드 번호/멘트(Slate 서식본)/와일드 조건·메모 표시, SlateRenderer
  밑줄·헥스색·{변수} 치환 보정, 말풍선 우측정렬·발신자 아바타 제거
- 견적상세 헤더: DB 컬럼명 라벨 제거, 견적정보/(진행상태+세팅)/상품(이미지) 2열 재배치,
  협상카드 탭에 사용 카드 수 표시
- DataTable 행 패딩 축소, 협력사명 아바타 제거, 카드관리 본인 카드 안내문
- orval 재생성(QuotationCardData 신규 필드)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:21:58 +09:00
df68609c49 [feat] negodata/backend: 견적 협상대화에 사용 협상카드 내용 노출
QuotationCardData 에 number/edit_script/condition/memo 추가, card 카탈로그(nego/wild)
라이브 조인으로 채움. DB 컬럼 변경 없음(기존 카드 테이블 조인만 확장).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:21:58 +09:00
3280cab088 [feat] negodata/backend: 상품 이미지 업로드(Azure Blob) 엔드포인트 추가
POST /v1/item/image — SAS 토큰을 URL에 붙여 httpx PUT 으로 Azure Blob 업로드.
이미지 타입/용량 검증 + IMAGE_* 에러코드. config 에 azure_blob_base_url/sas/root 추가.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:21:58 +09:00
92047c2b79 [chore] negodata/backend: 미구현 엑셀 일괄등록(upload-excel) 스텁 엔드포인트 제거
item/supplier 의 POST upload-excel 스텁 라우트와 Res_ExcelUpload 프로토콜 제거.
프론트 엑셀 모달은 클라이언트 CSV 파싱+check-codes/create 로 도는 독립 기능이라 영향 없음.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:49:20 +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
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
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
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
ebfa7a15bb requirement.dev.txt 삭제 . 2026-06-15 15:58:06 +09:00