o2o-negosium-original/schedules/anchoring/TODO.md
민헌 a2c299aa14 refactor(anchoring): 도메인 이름 전면 개편 — adjustments·anchoring_value/price·price_range·sample 용어 통일
용어 체계: 값=anchoring_value(정수‰)·가격=anchoring_price·조정=adjustment·구간=price_range·표본=sample

- DB: rate_adjustments→anchoring.adjustments (id→adjustment_id, price_bracket_index→price_range_index,
  nego_count→sample_count, anchor_rate_before/after→anchoring_value_before/after,
  consumed_session_ids→used_session_ids)
- sessions: target_anchoring_price→anchoring_price, anchor_rate_permille→anchoring_value,
  last_offered_price→last_offer_price, anchoring_adjustment_id→used_by_adjustment_id
- 뷰: rate_history/current_rates→value_history/current_values, delta_permille→value_change
- 코드: calc_price_range_index·calc_anchoring_price·evaluate_samples·get_current_value·
  get_latest_adjusted_value·get_current_anchoring_value·fetch_current_values·get_base_anchoring_value·
  Adjustment(ORM)·update_last_offer_price, 상수 ANCHORING_VALUE_MIN/MAX·ADJUSTMENT_STEP·
  PRICE_RANGE_COUNT/INDEX_MAX, 배치 로그 키 bracket=→price_range=
- API: negodata protocol 필드 target_anchoring_price→anchoring_price (front 생성 모델·컴포넌트 동반)
- 기존 DB 마이그레이션 신설: schedules/anchoring/migrations/20260706_rename_anchoring.sql
  (멱등 DO 블록 — 테이블·컬럼·뷰·인덱스·PK 제약. 코드 배포와 동시 적용 필요)
- postgres-init 01·04, 문서 6종 동기화
- 실배포 전 수정 포함: main.py argparse 화(--dry-run 단독·오타 플래그 기동 전 차단),
  박제 정합식 calc_anchoring_price 재사용, clamped 지표가 실제 포화만 집계(경계값 유지 제외)

주의: sessions.anchoring_value(정수‰)와 quotation_settings.anchoring_value(구 float 비율)는
같은 이름·다른 단위 — 구 컬럼은 미변경.

검증: 모듈 20·negodata 50·backend 57 테스트 통과, front tsc·vite build 통과,
로컬 DB 마이그레이션 적용 후 배치 dry-run·상주 기동·양 서버 부팅 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:17:01 +09:00

3.6 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)

신규 테이블 없이 조회용 뷰 2개로 해결. 요구(회사별 값 업데이트 리스트업 + 이전 값 판별)는 adjustments 한 행에 before→after 가 박제되어 있어 이미 충족 — 테이블 추가는 사본만 만든다고 판단해 기각하고, 조회를 제품화하는 뷰를 추가했다:

  • anchoring.value_history — 회사별 값 변경 이력(이전→새 값, 변화폭, 성공률, 시각)
  • anchoring.current_values — 칸별 현재값(없는 칸 = 시작값 10‰)

상세: docs/개발용.md §6.3, 사용법: docs/운영및유지보수.md §8. 추후 대시보드에서 "전체 칸 나열(무조정 칸 포함)·페이징" 요구가 생기면 그때 스냅샷 테이블로 승격을 재검토한다.


백로그 (저우선 — 리뷰에서 식별, 착수 조건 명시)

  • 전환기 점프 정책 결정 (negodata 적용 직전 필수): backend 배포~negodata 적용 사이에 학습된 rate 가 적용 순간 한 번에 반영된다("한 계단" 원칙의 1회 예외). 적용 직전 SELECT max(anchoring_value_after) FROM anchoring.current_values 로 폭 확인 후 점프 감수 vs 이력 아카이브·리셋을 결정할 것 — 절차는 docs/인수인계.md 적용 순서 ③.

  • 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_value 범위 검증) 케이스를 자동화.

  • config 오류 메시지: config.toml 의 오타 키가 TypeError 로 죽는다 — 파일/섹션명을 알려주는 검증 메시지로 개선.

  • 운영 Redis 인증: compose 는 127.0.0.1 바인딩으로 방어했지만, 운영 네트워크에서 negodata 가 원격 접속하는 구성이면 requirepass + REDIS_PASSWORD 설정을 적용할 것.