Skip to content

docs(config): 발주 주기가 월 단위 정기 발주임을 근거로 기록 (이슈 #54 요청 1번) - #64

Open
choigod1023 wants to merge 2 commits into
devfrom
feat/review-cadence-rationale
Open

docs(config): 발주 주기가 월 단위 정기 발주임을 근거로 기록 (이슈 #54 요청 1번)#64
choigod1023 wants to merge 2 commits into
devfrom
feat/review-cadence-rationale

Conversation

@choigod1023

@choigod1023 choigod1023 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

#54에서 reo-23 님이 요청하신 1번입니다.

src/config.pyDEFAULT_REVIEW_PERIOD_DAYS = 30은 실무와 일치합니다. 다만 지금은 코드에 상수로만 있고 근거 기록이 없으니, 이 확인 내용을 주석이나 정책 파일에 근거로 남겨주시면 좋겠습니다.

⚠️ 이 PR은 #54를 닫는 PR이 아닙니다

"검토주기 = 정기검토 30일"이라는 결정 자체는 확정(ai#54 요청1, 2026-07-30 reo-23 확인)이지만, 그 결정을 실제 DB 재계산에 반영하는 건 이 PR 범위 밖입니다. apply_inventory_policy.py는 여전히 ss/rop/target/status/order_recommendation을 쓰지 않고, inventory_policy.pyinventory_policy_method 라벨도 아직 module_c_continuous_target_stock로 남아있습니다(라벨 정정은 sehyeon03 님 리뷰 권고대로 DB 마이그레이션 반영하는 후속 PR에서 함께 처리).

#54는 계속 열어둡니다.

변경

src/config.pyDEFAULT_REVIEW_PERIOD_DAYS 위에 주석만 추가했습니다. 상수 값은 30 그대로이고 동작 변경은 없습니다.

추가로 apply_inventory_policy.py 모듈 docstring과 실행 로그 문구를, "#54가 미결"이라는 stale한 표현에서 "cadence 결정은 됐고 DB 반영만 별도 PR 대기"로 정정했습니다(sehyeon03 리뷰 지적).

남긴 내용:

  • 보건기관은 월 단위 정기 발주 (확인: 2026-07-30 reo-23, #54)
  • 그래서 연속검토가 아니라 정기검토를 쓰고, 보호기간 = 검토주기 + 리드타임
  • backend가 연속검토 식(SS = z·σ·√L, ROP = μ·L + SS)으로 운영 DB를 채워 온 사실과, 두 모형 공존이 #54였으며 실무 확인으로 정기검토가 정본이 된 경위
  • 운영 DB 재산정은 별도 PR이고, 그때까지 apply_inventory_policy.pyss/rop/target/status/order_recommendation을 쓰지 않는다는 현재 상태

정책 파일이 아니라 주석으로 한 이유

data/mapping/inventory_status_policy.json은 재고 판정(zero_stock_reason·urgent_shortage·ledger_rule) 정책이라 발주 주기를 넣을 자리가 아니라고 봤습니다. 새 정책 파일을 만드는 것도 읽는 코드가 없어 과해 보였습니다.

발주 주기 전용 정책 파일이 필요하다고 보시면 알려주세요 — 그렇게 옮기겠습니다.

검증

ast.parse 통과, 상수 값 30 유지 확인, 관련 테스트 9건 통과. 주석/로그 문구만 변경이라 동작 영향 없습니다.

Type

  • 새로운 기능
  • 버그 수정
  • 리팩토링
  • 문서/주석
  • 의존성 추가/수정

PR Checklist

  • Commit Message Convention을 준수했습니다.
  • Code Convention을 준수했습니다.
  • 변경한 기능이 잘 동작하는지 테스트했습니다.

#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) <noreply@anthropic.com>
@sehyeon03

Copy link
Copy Markdown
Contributor

2026-08-10 전체 재검토

결론: 비기능 문서 변경으로는 병합 가능하지만, #54를 해결하거나 닫는 PR은 아닙니다.

head 05af509의 관련 테스트 8개와 전체 회귀 테스트를 확인했고, 전체 232개 통과·로컬 TCP 제한 1개 skip이었습니다. 변경은 src/config.py 주석뿐이라 실행 결과는 바뀌지 않습니다.

현재 남은 불일치:

권장:

  1. 이 PR 본문에 "30일 정기검토 근거 기록만 수행하며 [정합성] 안전재고 모형이 ai/backend 에 두 개 공존 — 어느 쪽이 정본인지 확인 요청 #54 완료가 아님"을 명시
  2. 후속 PR에서 review_mode=periodic, review_period_days=30, 정책 버전·결정 근거를 산출물 metadata로 고정
  3. method 이름과 stale 안내문을 정정하되, DB migration 전 SS/ROP 보호 쓰기는 그대로 유지
  4. wide 데이터 재고가용량 수식과 DB backfill 검증까지 끝난 뒤 [정합성] 안전재고 모형이 ai/backend 에 두 개 공존 — 어느 쪽이 정본인지 확인 요청 #54 종료

따라서 이 PR은 부분 문서화로 병합 가능, #54는 계속 열어두는 판단입니다.

@choigod1023

Copy link
Copy Markdown
Contributor Author

이 PR 이 기록하려는 근거가 실측과 어긋납니다 — 병합 전 확인 부탁드립니다

이 PR 은 DEFAULT_REVIEW_PERIOD_DAYS = 30 에 "월 단위 정기 발주" 근거를 주석으로 남깁니다. 같은 항목을 정책 산출물에도 고정하려다 실측에 반증되어 철회했습니다(#54, #79).

무엇을 쟀나

조달청 나라장터 납품요구 27,653건(보건기관 300곳)에서 기관×세부품목 발주 간격을 재면 중앙값은 31일로 R=30 과 맞습니다. 그런데 분포가 평평합니다.

구간 비율
주 이내 18.9%
8~20일 19.2%
21~40일 (월 단위) 18.8%
41~90일 19.6%
분기 초과 23.5%

중앙값 31일은 30일 근처에 몰려서가 아니라 양쪽으로 넓게 퍼진 것의 한가운데입니다.

원장 입고 간격 423,573건으로 품목별 R 을 내면 이렇습니다.

p10 31   p50 91   p90 141일     범위 1~434일
21~40일 구간에 드는 품목:  7.6%
주력 의약품(페니라민정·리나치올캅셀·삐콤정 등):  93~140일

품목간 차이는 우연이 아닙니다 — Kruskal-Wallis H=1741.1, p<1e-300.

왜 문제인가

보호기간이 R + L 이고 두 항 모두 고정값인데 둘 다 실측과 어긋납니다.

현행   R=30 + L=15  =  45일
실측   R=90 + L=30  = 129일       (2.87배)

L=30 은 이번에 조달청 24개월 전수 30,815건으로 재확인했고 분위수가 20개월 때와 소수점까지 동일합니다(#20).

R 을 상수로 두면 회전 빠른 품목은 과다발주, 분기 조달 품목은 재고 소진입니다. 방향이 반대라 평균으로 상쇄되지 않습니다.

제안

이 PR 을 막을 생각은 없습니다. 다만 주석 문구만 조정하면 좋겠습니다.

현재:  "DEFAULT_REVIEW_PERIOD_DAYS = 30 은 실무와 일치한다"
제안:  "30 은 폴백 기본값이다. 실측 품목별 R 은 1~434일(p50 91)이고
        30일 부근은 7.6% 뿐이다. 품목별 값은
        data/mapping/review_period_by_item.csv 에 있으며
        review_period_days_col 로 행 단위 주입한다."

add_inventory_recommendations 는 이미 행 단위 review_period_days 를 받으므로 코드 변경 없이 조인만으로 적용됩니다. 배선은 목표재고 예산이 걸린 사안이라 #54 결정 대기 중입니다.

관련: #79 · #54 · #20

@sehyeon03

Copy link
Copy Markdown
Contributor

2026-08-16 현재 dev 기준 검토

이 PR의 핵심인 “월 단위 정기검토 R=30 근거 기록”은 이후 병합된 #79와 #90의 문서·코드에서 이미 다뤄졌습니다. 현재 브랜치는 최신 dev보다 뒤처져 있어 그대로 병합하면 중복 설명이나 오래된 상태 문구가 들어갈 가능성이 큽니다.

또한 #54는 R 값만의 문제가 아니라 AI/backend 계산식 정본, DB migration 버전, #39 리드타임과 #52 바닥값 입력까지 포함하는 문제로 확장됐습니다. 주석 한 곳보다 versioned policy와 parity test가 필요합니다.

따라서 이 PR은 병합하지 않고 superseded로 닫는 것을 권합니다. 보존할 근거 문구가 있다면 최신 dev의 정책 문서에 최소 변경으로 옮기고 #54 완료 PR에서 함께 검증하는 편이 안전합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants