리뷰어 지적: docker-compose 가 NEXT_PUBLIC_API_BASE=http://localhost:8000 을
주입해서 클라이언트 번들에 localhost 가 inline 됨. 사금향 게임컴 (192.168.10.13)
브라우저에선 동작하지만, 같은 내부망의 다른 PC 또는 외부 검증자가
http://192.168.10.13:3000 에 접속하면 fetch 가 그 PC 의 localhost:8000 으로 가서
연결 실패. 백엔드는 정상인데도 '검색 결과 없음' 으로 보임.
해석 우선순위:
1) NEXT_PUBLIC_API_BASE 가 비 localhost 값 → 그대로 (프로덕션 도메인 케이스)
2) 브라우저 → window.location.hostname:8000 (LAN/localhost 자동 대응)
3) SSR 폴백 → localhost:8000
localhost/127.0.0.1 판별은 //(localhost|127.0.0.1)(?::|$) 정규식 — 'localhost.evil.com'
같은 서브도메인 우회는 매치 안 됨. node 로 7케이스 검증 완료.
web/app 코드만이라 사금향 PC 는 restart.bat 으로 반영 (next dev hot-reload).
`web/package.json` 의 next/eslint-config-next ^14.2.33 상향 (6c79230) 에
맞춰 lockfile 갱신. npm 이 resolve 한 실제 버전은 14.2.35 (14.2.x 최신
patched). 자동 생성되는 next-env.d.ts 의 문서 URL 한 줄도 함께 동기화.
검증:
- `npm install --package-lock-only` 통과
- `npm run typecheck` 통과
- `npm run build` 통과 (Next.js 14.2.35, 4 페이지 정상 생성)
- ensemble.predict() 가 chronos_raw / lgbm_raw 를 함께 반환
- predict_and_store() 가 매 호출마다 3종 행 적재:
model='ensemble' (user_triggered=인자)
model='chronos' (user_triggered=FALSE, shadow)
model='lgbm' (user_triggered=FALSE, shadow)
- retrain_weekly.adjust_weights(): 최근 30일 prediction_outcomes 의
chronos vs lgbm hit_rate 로 ensemble_weights upsert
w_chronos = clamp(0.1, hr_c/(hr_c+hr_l), 0.9), w_lgbm = 1 - w_chronos
모델별 표본 < 10 이면 기본값(0.6/0.4) 유지
- API 응답에 saved_shadow_ids 추가 (TS 타입도 동기화)
- README: 동작 모델 메모 섹션을 실제 구현과 일치하도록 갱신
리뷰어 지적 3번 (ensemble_weights 가 영원히 갱신 안됨, upsert_weights 미호출) 해결.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>