# QA 검수 로그 — HepatoLipidClear-Kor

검수일: 2026-06-02
검수 환경: Python 3.9.6 / numpy 2.0.2 / pandas 2.3.3 / scipy 1.13.1 / pyyaml 사용 가능 / streamlit 1.50.0
(주의: requirements.txt 는 배포용 pinned 버전이며, 검수는 로컬 설치 버전으로 수행. 핵심 로직은 버전 비의존)

## 1. 구문 검사 (AST parse) — 전부 PASS
```
OK auc.py
OK oftt.py
OK breath.py
OK units.py
OK demo_data.py
OK app.py
```

## 2. 계산 로직 단위 테스트 (`_qa_test.py`, 27개 체크) — 전부 PASS, NaN/에러 없음

손계산 비교 핵심:
- `total_auc([0,2,4],[100,200,100])` = **600.0** (손계산: 300+300) ✔
- `incremental_auc` (baseline=100) = **200.0** (delta [0,100,0] 적분) ✔
- `peak_and_tmax([0,2,4,6],[100,180,150,110])` = peak 180, Tmax 2 ✔
- `cumulative_auc_to([0,2,4],[0,100,0], 3.0)` = **175.0** (보간점 3→50 포함: 100+75) ✔
- `return_to_baseline_time` (baseline 100, tol10%) = **5.333h** (150→90 사이 110 교차 선형보간) ✔
- `delta_to_pdr` DOB=10‰, VCO₂=1000, dose=4 → PDR = **2.8093 %/h** (손계산 0.01×1000×0.0112372/4×100) ✔
- `du_bois_bsa(70,175)` ≈ **1.848 m²** ✔; VCO₂ = 300×BSA ✔
- 데모 정상 산화 kel(0.974/h) > 저하 산화 kel(0.032/h) — 생리적 방향성 일치 ✔
- TG / δ¹³C 단위 왕복 변환 오차 < 1e-6 ✔

기능 검증:
- 데모 정상 OFTT 분석: peak/Tmax/AUC/iAUC/iAUC-per-g-fat 모두 유한값, NaN 없음 ✔
  (참고: 정상 곡선 일부 피험자 `return_to_baseline_h`=NaN — 8h 내 기저 미복귀로 정상적 NaN. 코어 지표는 모두 유한)
- 데모 호기 분석: cPDR40/cPDR120/반감기 모두 유한, fit method=nonlinear_monoexp ✔
- 비선형 fit 강제 폴백(`use_nonlinear=False`): loglinear kel 양수 산출 ✔
- QC 플래그: 시점 누락("누락시점 6h/8h") + 음수 농도값 동시 검출 ✔
- `app.run_oftt_table`/`run_breath_table`: 피험자 수만큼 행 생성, group 컬럼 보존 ✔

## 3. 합성 데모 CSV 로드 테스트 (pandas.read_csv) — PASS
```
oftt_normal.csv     (30, 5)  [subject_id, time_h, tg, apob48, retinyl]
oftt_delayed.csv    (30, 5)  [subject_id, time_h, tg, apob48, retinyl]
breath_delta13c.csv (66, 7)  [subject_id, group, time_min, delta13c, weight_kg, height_cm, dose_mmol_13c]
```

## 4. Streamlit 구문/구조 검사 — PASS
- `app.py` AST parse 통과.
- `import app` 성공 (streamlit/matplotlib는 `main()` 내부에서 import → import-safe).
- 계산 헬퍼(`run_oftt_table`, `run_breath_table`)는 Streamlit 없이 직접 호출 가능 구조 확인.
- UI 자체(`main()`)는 요구사항대로 구문 검사만 수행(서버 미기동).

## 5. 재시도/실패 기록
- 재시도 없이 1차 통과. **FAILED 항목 없음.**

## 종합 판정: PASS (경고 0건의 치명 이슈)
- 주의(비치명): 정상 OFTT 데모에서 8h 내 기저 미복귀 피험자의 `return_to_baseline_h`는
  의도된 NaN(미복귀 표현). 지연청소군과 구분하기 위한 정상 동작이며 에러 아님.
- δ¹³C→PDR 변환식·CO₂ 가정(300 mmol/m²/h)은 `breath.py` docstring 및 `reference.yaml`에 명시.
- 비선형 fit은 scipy.optimize.curve_fit 사용, 예외 시 로그-선형 자동 폴백(코드·테스트 확인).

## 재현 방법
```bash
cd projects/2026-06-02-3-hepatolipidclear-kor
python3 demo_data.py        # data/ CSV 재생성
python3 _qa_test.py         # 27개 단위 검수(종료코드 0 = 전부 통과)
for f in auc.py oftt.py breath.py units.py demo_data.py app.py; do \
  python3 -c "import ast; ast.parse(open('$f').read()); print('OK', '$f')"; done
streamlit run app.py        # UI 실행(선택)
```
