feat(schema): 발주권고 NULL 허용 + 감사 컬럼 · 미사용 인덱스 2개 제거(36MB 회수) - #72
Merged
Conversation
ai 정책(inventory-status-v1.1)은 판단 불가 건에 권고량 NULL 을 요구한다. DATA_MISSING(재고 기재 누락 의심) · STALE(관측이 오래됨) → 산출 불가 = NULL DORMANT / NOT_OPERATED → 발주 대상 아님 = 0 지금은 order_recommendation 이 NOT NULL 이라 둘을 0 으로 뭉갠다. 그러면 화면에서 "발주 안 함"과 "모르겠음"이 같아진다. 담당자가 0 을 보고 발주를 넘기는데, 실제로는 재고 기재가 누락돼 판단을 못 한 건일 수 있다. 스키마 - order_recommendation 을 nullable 로 - raw_order_recommendation · order_suppress_reason 추가 — ai 정책이 "원시 권고량과 억제 여부·사유를 감사용으로 보존"하도록 요구한다. 결과만 덮어쓰면 왜 0/NULL 인지 되짚을 수 없다 - mu_is_floored · sigma_is_floored 추가 — 같은 정책이 이 플래그를 판정·예측·API 에 노출하도록 한다. 운영 DB 는 지금 mu<=0.5 가 296,537/409,459행(72.4%)인데 그게 실측값인지 바닥값인지 구분할 수단이 없다 - 기존 DB 용 멱등 DDL 을 파일 끝에 추가 (CREATE TABLE IF NOT EXISTS 는 기존 테이블을 바꾸지 않으므로 ALTER 를 따로 둔다) 깨지는 곳을 함께 고쳤다 - db/queries.py: sum(1 for r in inv if r["orderRecommendation"] > 0) 은 파이썬에서 None > 0 → TypeError 다. (r[...] or 0) 으로 바꿨다 - routers/graphql_schema.py: order_recommendation: int 는 strawberry 가 Int! 로 노출해 NULL 반환 시 스키마 위반이다. Optional[int] 로 3곳 변경 NULL 안전한 것은 그대로 뒀다 - count(*) FILTER (WHERE order_recommendation > 0) → NULL 은 미집계. "모르겠음"을 발주 필요로 세지 않는 게 맞다 - order_recommendations() 의 > 0 필터·ORDER BY → NULL 제외가 의도된 동작 응답에 orderSuppressReason / rawOrderRecommendation / muIsFloored / sigmaIsFloored 를 노출한다. 프론트가 0 과 NULL 을 구분해 표기할 근거가 필요하다. 검증: 운영 DB 에 트랜잭션으로 DDL 적용 후 롤백 — 멱등성(2회 실행) 통과, NULL 삽입 21행 성공, FILTER 집계 157,456 정상, 롤백 후 is_nullable=NO 원복 확인. db/queries.py · routers/graphql_schema.py 문법 검사 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
7 tasks
Neon 무료 한도 512MB 중 354MB 를 쓰고 있었고, 그 122MB 가 inventory 인덱스 6개였다. 실측 스캔 횟수를 보니 둘은 사실상 놀고 있었다. idx_inventory_is_medical 19MB 스캔 6회 ← boolean, 값 2종 idx_inventory_demand_class 16MB 스캔 10회 ← text, 값 3종 ─ 비교 ─ inventory_institution_id_standard_code_key 34MB 스캔 192,131회 idx_inventory_institution 12MB 스캔 4,183회 둘 다 저카디널리티 컬럼이라 인덱스 이득이 거의 없고, db/queries.py 에서 WHERE 절로 쓰이는 곳이 하나도 없다(전수 확인). 운영 DB 에서 DROP INDEX CONCURRENTLY 로 제거했다. DB 크기 354MB → 318MB (36MB 회수) inventory 인덱스 122MB → 87MB 남은 여유 193.6MB idx_inventory_is_medical 은 커밋된 코드에 생성문이 없어(수동 생성분) DB 에서만 지웠다. idx_inventory_demand_class 는 이 파일에 있었으므로 함께 제거한다 — 안 그러면 seed_db.py 가 schema.sql 을 적용할 때 되살아난다. 되살리는 문장은 주석으로 남겼다. 롤백 스크립트도 함께 보관했다. 검증: 삭제 후 운영 API 3개 확인 — /inventory-policy(500행) · /dashboard/central · /order-recommendations 모두 HTTP 200, 응답 정상. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
커밋 추가 — 미사용 인덱스 2개 제거 (이미 운영 DB 반영됨)Neon 무료 한도 512MB 중 354MB 를 쓰고 있었고, 그 중 122MB 가
둘 다 저카디널리티 컬럼(
되살리는 문장은 주석으로 남겼습니다. 검증: 삭제 후 운영 API 3개 — |
…endation nullable) 공존
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
ai정책(inventory-status-v1.1)은 판단 불가 건에 권고량NULL을 요구합니다.DATA_MISSING(재고 기재 누락 의심)STALE(관측이 오래됨)DORMANT/NOT_OPERATED지금은
order_recommendation이NOT NULL이라 이 둘을 모두 0으로 뭉갭니다. 화면에서 "발주 안 함"과 "모르겠음"이 같아집니다. 담당자가 0을 보고 넘기는데 실제로는 재고 기재가 누락돼 판단을 못 한 건일 수 있습니다.DGU-TeamLex/ai#53이 이 제약 때문에 정책을 지키지 못하고 0으로 내보내고 있습니다.스키마 변경
raw_order_recommendation·order_suppress_reason— ai 정책이 "원시 권고량과 억제 여부·사유를 감사용으로 보존"하도록 요구합니다. 결과만 덮어쓰면 왜 0/NULL 인지 되짚을 수 없습니다.mu_is_floored·sigma_is_floored— 같은 정책이 이 플래그를 판정·예측·API 에 노출하도록 합니다. 운영 DB 는 지금mu<=0.5가 296,537 / 409,459행(72.4%) 인데, 그게 실측값인지 바닥값인지 구분할 수단이 없습니다.CREATE TABLE IF NOT EXISTS는 기존 테이블을 바꾸지 않으므로 멱등ALTER를schema.sql끝에 따로 뒀습니다(seed_db.py가 파일을 그대로 실행).함께 고친 것 — 이대로 두면 깨집니다
①
db/queries.py— 파이썬에서None > 0은TypeError입니다.②
routers/graphql_schema.py—order_recommendation: int는 strawberry 가Int!로 노출해 NULL 반환 시 스키마 위반입니다.Optional[int]로 3곳 변경.그대로 둔 것 — NULL 안전 확인
count(*) FILTER (WHERE order_recommendation > 0)order_recommendations()의> 0필터ORDER BY order_recommendation DESC> 0필터가 있어 NULL 없음응답 노출
orderSuppressReason·rawOrderRecommendation·muIsFloored·sigmaIsFloored를 재고정책 응답에 추가했습니다. 프론트가 0 과 NULL 을 구분해 표기할 근거가 필요합니다.To Reviewer
운영 DB 에 트랜잭션으로 DDL 을 적용하고 롤백해 검증했습니다.
db/queries.py·routers/graphql_schema.py문법 검사 통과.후속으로 프론트 수정이 필요합니다.
frontend/app/inventory/page.tsx가r.orderRecommendation > 0으로 분기하는데, JS 에서null > 0은false라 예외는 안 나지만 회색 "0" 으로 표시됩니다. 지금 고치려는 "발주 안 함 vs 모르겠음" 혼동이 화면에 그대로 남습니다. 이 PR 머지 후 별도로 올리겠습니다.Type
PR Checklist