모듈·backend·문서 3개 관점의 적대 리뷰에서 확인된 결함 일괄 수정: [모듈] - 배치에 company_ids 스코프 옵션 추가 — 통합 테스트가 공유 dev DB 의 실세션을 소비/마킹하던 문제 해소(테스트는 시드 회사로 한정), 표적 수동 실행 옵션 겸용 - Redis 방어: compose 포트를 127.0.0.1 바인딩(무인증 공개 차단), get_rate 에 범위([10,200]) 검증 — 오염 캐시값은 미스 취급 후 자가 교정, 미스 백필은 SET NX (배치가 방금 쓴 새 값을 구값으로 덮는 write-after-read 경합 방지) - 배치: Redis ping 후 re-SET(다운 시 셀×timeout 지연 없이 즉시 스킵), 스캔 조인 ON 절에 quotations/items deleted 필터(철회 거래를 학습에서 배제), 제외 마킹을 청크별 커밋(레거시 대량 첫 실행의 장시간 단일 트랜잭션 방지) - main: SIGTERM/SIGINT 핸들러(docker stop 시 정리 로직 보장), --once 부분 실패 시 종료코드 1(런북/cron 감지 가능) [backend] - finalize_session·update_last_offered_price 에 status=IN_PROGRESS 가드 — negodata 일괄마감/중복 전송 경합이 종료된 세션을 되살리거나 가격 흔적을 사후 변경하는 것 차단(파생 판정 결정성 보호) - 신규 DB 부트스트랩: sessions 3컬럼을 postgres-init/01-schema·04-alter 에도 반영(backend 가 모듈 DDL 없이 기동) — anchoring 스키마 자체는 모듈 소유 유지 - 낡은 주석 정리(agent_client·quotation_settings 의 구 앵커 산출 서술) [테스트·문서] - 신규 테스트: 격주 게이트 골든(ISO 주차), supplier_type NULL, 가격 제시율 0% WARN — 모듈 18개·backend 57개 통과 - 문서 정합 감사 20건 반영: 잔존 33,334/노출 문구 제거, §10 SQL 을 실제 코드 (LEFT JOIN+deleted)와 일치, §11 자동/수동 검증 구분, FastAPI 오기 제거, 인수인계 reader 시그니처(db 인자), TODO 백로그 5건 기록 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
TODO — 앵커링 모듈 후속 과제
남은 과제는 정책 재확정 + 스펙(v1.3) 개정 사안이다. 현재 규범(
docs/개발용.md§12)은 정적 테이블 변경·파라미터 조정을 봉인하고 있으므로, 착수 전 정책 확정 → 문서 개정 → 구현 순서를 지킨다. 운영 데이터(조정 이력)가 쌓이기 전에 확정하는 것이 가장 저렴하다 — negodata 적용 전이 적기.
1. 정적 기본 테이블의 가격구간을 계단식으로 재설계 ✅ 완료 (2026-07-02)
자릿수 계단식 사다리(46칸)로 확정·구현 완료. 폭 = 구간 상한의 10%(선행 자릿수 밴드):
[0, 1,000) 통일 1칸 + 자릿수(1천~1억, 5개)당 9칸 — "1천 원대·2천 원대 … 9천만 원대".
1억 초과는 마지막 인덱스(45) 클램프. 사다리 단일 소스 = constants.UPPER_BOUNDS,
산식 = bisect_right. 조정 이력 0건 시점에 적용해 마이그레이션 없음.
상세: docs/개발용.md §2·§4.1.
2. anchoring_records — 회사별 앵커링 값 전체 조회 테이블 ✅ 뷰로 종결 (2026-07-02)
anchoring_records — 회사별 앵커링 값 전체 조회 테이블신규 테이블 없이 조회용 뷰 2개로 해결. 요구(회사별 값 업데이트 리스트업 + 이전 값 판별)는
rate_adjustments 한 행에 before→after 가 박제되어 있어 이미 충족 — 테이블 추가는 사본만 만든다고
판단해 기각하고, 조회를 제품화하는 뷰를 추가했다:
anchoring.rate_history— 회사별 값 변경 이력(이전→새 값, 변화폭, 성공률, 시각)anchoring.current_rates— 칸별 현재값(없는 칸 = 시작값 10‰)
상세: docs/개발용.md §6.3, 사용법: docs/운영및유지보수.md §8.
추후 대시보드에서 "전체 칸 나열(무조정 칸 포함)·페이징" 요구가 생기면 그때 스냅샷 테이블로 승격을 재검토한다.
백로그 (저우선 — 리뷰에서 식별, 착수 조건 명시)
- percent 입력 모드 대비:
chat_service.send는user_input_type == "price"만 가격으로 파싱한다. agent 에 percent 스크립트가 도입되면 percent 턴이 가격 흔적 없이 지나가 학습에서 조용히 빠진다(현재 agent 스크립트에 percent 없음 — 잠복). 도입 시 percent→price 변환(target*(100-pct)//100) 후 동일 경로로 태울 것. - 스캔 스트리밍: 배치 스캔이 pending 전량을 메모리에 올린다. 레거시 수백만 행 규모 DB 에 첫 적용할 때는 keyset 페이지네이션으로 전환 검토(제외 마킹은 이미 청크 커밋이라 트랜잭션 장기화 없음).
- Redis 통합 테스트: 자동 스위트는 무Redis(폴백 경로)로 돈다. CI 에 redis 컨테이너가 생기면 §11.5 의 re-SET 회복·TTL·오염 값 방어(get_rate 범위 검증) 케이스를 자동화.
- config 오류 메시지: config.toml 의 오타 키가 TypeError 로 죽는다 — 파일/섹션명을 알려주는 검증 메시지로 개선.
- 운영 Redis 인증: compose 는 127.0.0.1 바인딩으로 방어했지만, 운영 네트워크에서
negodata 가 원격 접속하는 구성이면
requirepass+REDIS_PASSWORD설정을 적용할 것.