용어 체계: 값=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>
34 lines
2.0 KiB
Python
34 lines
2.0 KiB
Python
"""앵커링 도메인 상수 — 읽기 경로에 필요한 부분만 원본에서 발췌 이식.
|
|
|
|
원본: schedules/anchoring/src/anchoring/constants.py (규범: 같은 폴더 docs/개발용.md §3).
|
|
조정폭(δ)·배치 주기 등 배치 전용 상수는 이식하지 않았다.
|
|
상수 변경은 정책 재확정 사안 — 코드에서 임의 조정 금지, 변경 시 원본과 동시 반영.
|
|
"""
|
|
|
|
# ── 앵커링 값(정수 천분율 ‰) ──────────────────────────────
|
|
ANCHORING_VALUE_MIN = 10 # 하한 1%
|
|
ANCHORING_VALUE_MAX = 200 # 상한 20%
|
|
# 시작값은 상수가 아니라 정적 테이블(base_table)에서 로드 — 0.01/10 하드코딩 금지
|
|
|
|
# ── 가격구간 (자릿수 계단식 사다리 — 폭 = 구간 상한의 10% = 선행 자릿수 밴드) ──
|
|
# 예: 1,000~1만 은 1,000원 폭(1천 원대·2천 원대…), 1만~10만 은 1만 폭(1만 원대·2만 원대…).
|
|
# 최하단(0~1,000원)은 한 칸으로 통일. 1억 초과는 마지막 칸으로 클램프.
|
|
PRICE_MAX = 100_000_000 # 정적 테이블 상한(1억)
|
|
_DECADE_STARTS = (1_000, 10_000, 100_000, 1_000_000, 10_000_000)
|
|
|
|
|
|
def _build_upper_bounds() -> tuple:
|
|
bounds = [1_000] # idx 0: [0, 1,000) 통일 칸
|
|
for start in _DECADE_STARTS: # 각 자릿수: 폭 = start (상한의 10%)
|
|
bounds.extend(start + start * i for i in range(1, 10))
|
|
return tuple(bounds) # 마지막 = 100,000,000
|
|
|
|
|
|
UPPER_BOUNDS = _build_upper_bounds() # 46개 — 구간 = [이전 upper_bound, upper_bound) 좌폐우개
|
|
PRICE_RANGE_COUNT = len(UPPER_BOUNDS) # 46
|
|
PRICE_RANGE_INDEX_MAX = PRICE_RANGE_COUNT - 1 # 45
|
|
|
|
# 칸을 구성할 수 있는 협력사 유형 코드 — common.enums.SupplierType 의 유통(1)/제조(2)/총판(3).
|
|
# 이 외(NONE=0/NULL)는 칸 해석 불가 → 정적 테이블 시작값 사용(배치 집계에서도 자동 제외).
|
|
SAMPLEABLE_SUPPLIER_TYPES = (1, 2, 3)
|