From 05af509a966c217a3a63bb7d4873055895e2cb02 Mon Sep 17 00:00:00 2001 From: choigod1023 Date: Mon, 10 Aug 2026 09:27:04 +0900 Subject: [PATCH 1/2] =?UTF-8?q?docs(config):=20=EB=B0=9C=EC=A3=BC=20?= =?UTF-8?q?=EC=A3=BC=EA=B8=B0=EA=B0=80=20=EC=9B=94=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=EC=A0=95=EA=B8=B0=20=EB=B0=9C=EC=A3=BC=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=98=86=EC=97=90=20=EA=B7=BC=EA=B1=B0?= =?UTF-8?q?=EB=A1=9C=20=EA=B8=B0=EB=A1=9D=20(=EC=9D=B4=EC=8A=88=20#54)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #54 에서 reo-23 님이 조달 실무를 확인해 주셨다 — 보건기관은 재고 소진 시 수시 발주가 아니라 **월 단위로 정기 발주**한다. 따라서 정기검토 모형(보호기간 = 검토주기 + 리드타임)이 실무에 부합하고, DEFAULT_REVIEW_PERIOD_DAYS = 30 은 실무와 일치한다. 그동안 이 값은 코드에 상수로만 있고 근거가 없었다. 다음에 보는 사람이 "30일은 어디서 나온 값인가"를 다시 묻지 않도록 확인 경위와 날짜, 이슈 번호를 남긴다. reo-23 님 요청 1번이다. 함께 적어 둔 것 - 왜 연속검토가 아니라 정기검토인지 (실무가 정기 발주이므로) - backend 가 연속검토 식(SS = z·σ·√L, ROP = μ·L + SS)으로 운영 DB 를 채워 온 사실과, 두 모형 공존이 #54 의 내용이며 실무 확인으로 정기검토가 정본이 된 경위 - 운영 DB 재산정은 별도 PR 이고, 그때까지 apply_inventory_policy.py 가 ss/rop/target/status/order_recommendation 을 쓰지 않는다는 현재 상태 상수 값은 바꾸지 않았다(30 유지). 주석만 추가한다. Co-Authored-By: Claude Opus 5 (1M context) --- src/config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/config.py b/src/config.py index 17413e5..d308f62 100644 --- a/src/config.py +++ b/src/config.py @@ -396,6 +396,16 @@ def _bulk_approval_is_active() -> bool: DEMAND_RISK_BUFFER_RATE = 0.20 SUPPLY_RISK_BUFFER_RATE = 0.20 MATERIAL_RISK_BUFFER_RATE = 0.10 + +# 발주 주기 — 보건기관은 재고 소진 시 수시 발주가 아니라 월 단위로 정기 발주한다. +# 확인: 2026-07-30 reo-23, 이슈 #54 (조달 실무 확인 결과) +# 그래서 재고 모형은 연속검토(ROP 도달 시 발주)가 아니라 정기검토를 쓴다. +# 보호기간 = 검토주기 + 리드타임 이며 src/modeling/inventory_policy.py 가 이를 따른다. +# +# ⚠️ backend 는 연속검토 식(SS = z·σ·√L, ROP = μ·L + SS)으로 운영 DB 를 채워 왔다. +# 두 모형이 공존하던 문제가 #54 이고, 실무 확인으로 정기검토가 정본임이 확정됐다. +# 운영 DB 재산정은 별도 PR 로 다룬다 — src/loading/apply_inventory_policy.py 는 +# 그때까지 ss/rop/target/status/order_recommendation 을 쓰지 않는다. DEFAULT_REVIEW_PERIOD_DAYS = 30 DEFAULT_LEAD_TIME_DAYS = 15 From 743537f3416527bd9308972aaf26cc1216bd9d62 Mon Sep 17 00:00:00 2001 From: choigod1023 Date: Thu, 13 Aug 2026 10:04:01 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=EC=A0=95=EA=B8=B0=EA=B2=80?= =?UTF-8?q?=ED=86=A0=20=ED=99=95=EC=A0=95=20=EC=83=81=ED=83=9C=20=EB=B0=98?= =?UTF-8?q?=EC=98=81,=20DB=20=EC=9E=AC=EA=B3=84=EC=82=B0=EC=9D=80=20?= =?UTF-8?q?=EB=B3=84=EB=8F=84=20PR=EC=9E=84=EC=9D=84=20=EB=AA=85=EC=8B=9C?= =?UTF-8?q?=20(ai#64=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/loading/apply_inventory_policy.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/loading/apply_inventory_policy.py b/src/loading/apply_inventory_policy.py index 613e57c..2736fc0 100644 --- a/src/loading/apply_inventory_policy.py +++ b/src/loading/apply_inventory_policy.py @@ -1,13 +1,17 @@ """Apply AI demand statistics to DB inventory without choosing an SS/ROP model. -Issue #54 records an unresolved policy conflict: +Issue #54 recorded a policy conflict between two models: * backend: continuous review, ``SS=z*sigma*sqrt(L)``, ``ROP=mu*L+SS`` * AI: periodic review plus lead time, fixed/risk-adjusted target stock -Until the ordering cadence and one canonical policy are approved, this loader -updates only demand statistics and classification fields. It deliberately does -not write ``ss``, ``rop``, ``target``, ``status`` or ``order_recommendation``. +The cadence question is resolved (ai#54 request 1, 2026-07-30 confirmation from +reo-23): institutions place orders on a monthly cadence, so periodic review is +the canonical model. What is NOT yet done is applying that decision to the DB — +the SS/ROP recalculation itself is a separate, still-pending PR. Until that PR +lands, this loader updates only demand statistics and classification fields. It +deliberately does not write ``ss``, ``rop``, ``target``, ``status`` or +``order_recommendation``. Run with ``DRY_RUN=1`` first. ``DRY_RUN=0`` commits the restricted update. """ @@ -121,7 +125,7 @@ def main() -> None: ) print( "보호 범위: SS/ROP/target/status/order_recommendation " - "(ai#54 결정 전 미변경)" + "(정기검토 모형 확정됨(ai#54 요청1) — DB 재계산은 별도 PR 대기, 이 로더는 미변경)" ) with psycopg.connect(os.environ["DATABASE_URL"]) as conn: