1. [Feat] CALC-001 체내 잔류 카페인 산출 모듈
📌 개요
1구획 지수감쇠 PK 모델로 임의 시점의 체내 잔류 카페인량을 계산하는 core/pharmacokinetics.py 구현.
🎯 배경 / 목적
CALC-002~006이 전부 이 모듈의 C(t)를 호출한다. 계산 도메인의 최하단 레이어이자
공통 상수(θ_pop, D_max, W_ref, n₀, 반감기)의 단일 출처가 된다.
메인피드 그래프 렌더링용 JSON 페이로드도 여기서 생성한다.
✅ 작업 내용
core/ 패키지 생성 (__init__.py)
공통 상수 정의: POP_HALF_LIFE_H=5.0, THETA_POP_MG=80, DAILY_LIMIT_MG=400, W_REF_KG=65, DEFAULT_N0=5, SERVICE_DAY_START_HOUR=5
half_life_to_ke / ke_to_half_life 변환
Dose 데이터클래스 (amount_mg, taken_at, log_id, drink_name, is_all_nighter)
concentration_at(doses, at, ke) — Σ D_i·exp(-kₑ(t-t_i)), t < t_i 는 0 처리
concentration_series / time_to_index / build_curve_payload 그래프 페이로드
시각 유틸: resolve_next_occurrence, service_date(05:00 경계), hours_between
단위 테스트: 0건 → 0.0, 미래 기록 → 0, 반감기 1주기 후 정확히 1/2, 다중 도즈 중첩
🔍 완료 조건
📎 참고
2. [Feat] CALC-005 개인화 임계치 θ 산출 모듈
📌 개요
누적된 수면설문으로 개인 카페인 임계치 θ̂_ind를 추정하고, 기록 수에 따라 집단 기본값과
가중 혼합해 최종 θ를 산출하는 core/personalization.py 구현.
🎯 배경 / 목적
CALC-002·003이 θ를 입력으로 받으므로 마감시각/허용량보다 먼저 필요하다.
"일반적인 카페인 권고는 개인차 때문에 신뢰할 수 없다"는 서비스 핵심 가치가 이 모듈에 걸려 있다.
✅ 작업 내용
🔍 완료 조건
📎 참고
3. [Feat] CALC-002 마감시각 산출 모듈
📌 개요
"지금 이후 언제까지 한 잔을 더 마셔도 목표 취침시각의 잔류량이 θ를 넘지 않는가"를
절대시각으로 반환하는 core/cutoff.py 구현.
🎯 배경 / 목적
메인피드(FEED-001/002)의 대표 지표. 서비스 3대 기능 중 "커피 마감시간 계산" 그 자체다.
✅ 작업 내용
🔍 완료 조건
📎 참고
4. [Feat] CALC-003 남은 허용량 산출 모듈
📌 개요
목표 취침시각 기준으로 오늘 더 섭취 가능한 카페인량 R(mg)과 환산 잔 수 n_cup을
산출하는 core/allowance.py 구현.
🎯 배경 / 목적
마감시각(CALC-002)이 "언제까지"라면 이건 "얼마나". 메인피드에서 같이 노출된다.
✅ 작업 내용
🔍 완료 조건
📎 참고
5. [Feat] CALC-006 한계효용 판정 모듈
📌 개요
추가 섭취가 실제로 각성 개선을 주는지 Hill 방정식 기반으로 판정하는
core/marginal_utility.py 구현. "이 이상은 효과 없이 부작용만 늘어남"을 알린다.
🎯 배경 / 목적
메인피드와 밤샘모드 피드 양쪽에서 표시. 절대 각성도 예측(P₀)은 스코프 밖이므로
상대적 한계 개선폭 Δg만 다룬다.
✅ 작업 내용
🔍 완료 조건
📎 참고
6. [Feat] CALC-004 밤샘 섭취 스케줄 생성 모듈
📌 개요
목표 시각 T_w까지 혈중 카페인 농도를 [C_min, C_max] 밴드 안에 유지하는
톱니파 섭취 스케줄을 산출하는 core/night_schedule.py 구현.
🎯 배경 / 목적
밤샘모드의 계산 엔진. 3대 기능 중 난이도가 가장 높고, 컷 우선순위 1순위이기도 하다.
D15가 드롭 결정 시점 이므로 그 전까지 완료 여부를 판단한다.
✅ 작업 내용
🔍 완료 조건
📎 참고
1. [Feat] CALC-001 체내 잔류 카페인 산출 모듈
📌 개요
1구획 지수감쇠 PK 모델로 임의 시점의 체내 잔류 카페인량을 계산하는
core/pharmacokinetics.py구현.🎯 배경 / 목적
CALC-002~006이 전부 이 모듈의
C(t)를 호출한다. 계산 도메인의 최하단 레이어이자공통 상수(θ_pop, D_max, W_ref, n₀, 반감기)의 단일 출처가 된다.
메인피드 그래프 렌더링용 JSON 페이로드도 여기서 생성한다.
✅ 작업 내용
core/패키지 생성 (__init__.py)POP_HALF_LIFE_H=5.0,THETA_POP_MG=80,DAILY_LIMIT_MG=400,W_REF_KG=65,DEFAULT_N0=5,SERVICE_DAY_START_HOUR=5half_life_to_ke/ke_to_half_life변환Dose데이터클래스 (amount_mg, taken_at, log_id, drink_name, is_all_nighter)concentration_at(doses, at, ke)— Σ D_i·exp(-kₑ(t-t_i)), t < t_i 는 0 처리concentration_series/time_to_index/build_curve_payload그래프 페이로드resolve_next_occurrence,service_date(05:00 경계),hours_between🔍 완료 조건
python -c "from core.pharmacokinetics import *"동작📎 참고
2. [Feat] CALC-005 개인화 임계치 θ 산출 모듈
📌 개요
누적된 수면설문으로 개인 카페인 임계치 θ̂_ind를 추정하고, 기록 수에 따라 집단 기본값과
가중 혼합해 최종 θ를 산출하는
core/personalization.py구현.🎯 배경 / 목적
CALC-002·003이 θ를 입력으로 받으므로 마감시각/허용량보다 먼저 필요하다.
"일반적인 카페인 권고는 개인차 때문에 신뢰할 수 없다"는 서비스 핵심 가치가 이 모듈에 걸려 있다.
✅ 작업 내용
SleepRecord데이터클래스 (sleep_quality, residual_mg_at_sleep, slept_at)compute_residual_at_sleep()— 실제 수면시각 S_d 기준 R_d, CALC-001 재사용is_all_nighter=True)는 학습에서 제외estimate_theta()— θ̂_ind = mean(R_d | Q_d ≤ 2), |B|=0 이면 θ_pop 폴백theta_cached컬럼 두지 않는다)🔍 완료 조건
ThetaResult에 θ, θ̂_ind, w, n 전부 노출 (디버깅/피드 표시용)📎 참고
3. [Feat] CALC-002 마감시각 산출 모듈
📌 개요
"지금 이후 언제까지 한 잔을 더 마셔도 목표 취침시각의 잔류량이 θ를 넘지 않는가"를
절대시각으로 반환하는
core/cutoff.py구현.🎯 배경 / 목적
메인피드(FEED-001/002)의 대표 지표. 서비스 3대 기능 중 "커피 마감시간 계산" 그 자체다.
✅ 작업 내용
residual_at_bedtime()— E = Σ D_i·exp(-kₑ(t_b - t_i))calc_cutoff()— B = θ - E, r = B/D_p, t_cut = t_b + (1/kₑ)·ln rCutoffStatusenum으로 예외 4종 분기BEDTIME_PASSED, cutoff_at=NoneOVER_THRESHOLD, cutoff_at=NoneNO_PLANNED_DOSE, t_b 반환CUTOFF_PASSED, t_cut 반환(경고)resolve_next_occurrence로 target_bedtime(TIME) → 절대 datetime 변환 연계🔍 완료 조건
📎 참고
4. [Feat] CALC-003 남은 허용량 산출 모듈
📌 개요
목표 취침시각 기준으로 오늘 더 섭취 가능한 카페인량 R(mg)과 환산 잔 수 n_cup을
산출하는
core/allowance.py구현.🎯 배경 / 목적
마감시각(CALC-002)이 "언제까지"라면 이건 "얼마나". 메인피드에서 같이 노출된다.
✅ 작업 내용
calc_allowance()— R = max(0, θ - C(t_b)), n_cup = floor(R / D_ref)over_threshold(θ - C(t_b) < 0),under_one_cup(R < D_ref)over_daily_limit플래그 — 400mg 초과는 경고만, 기능 차단 없음🔍 완료 조건
📎 참고
R / exp(-kₑ(t_b - t₀))로 보정5. [Feat] CALC-006 한계효용 판정 모듈
📌 개요
추가 섭취가 실제로 각성 개선을 주는지 Hill 방정식 기반으로 판정하는
core/marginal_utility.py구현. "이 이상은 효과 없이 부작용만 늘어남"을 알린다.🎯 배경 / 목적
메인피드와 밤샘모드 피드 양쪽에서 표시. 절대 각성도 예측(P₀)은 스코프 밖이므로
상대적 한계 개선폭 Δg만 다룬다.
✅ 작업 내용
clamp_weight()— 미설정 시 W_ref=65 폴백, [30, 200]kg 클램프m0_for_weight()— M₀(W) = 9.86 × 65/Wg_pd_min()— 1/(1 + M₀·D), mg → g 환산 필수 (M₀ 단위가 g⁻¹)calc_marginal_utility()— Δg = g(D_cum) - g(D_cum + D_p), ε=0.02 미만이면 경고🔍 완료 조건
📎 참고
6. [Feat] CALC-004 밤샘 섭취 스케줄 생성 모듈
📌 개요
목표 시각 T_w까지 혈중 카페인 농도를 [C_min, C_max] 밴드 안에 유지하는
톱니파 섭취 스케줄을 산출하는
core/night_schedule.py구현.🎯 배경 / 목적
밤샘모드의 계산 엔진. 3대 기능 중 난이도가 가장 높고, 컷 우선순위 1순위이기도 하다.
D15가 드롭 결정 시점이므로 그 전까지 완료 여부를 판단한다.
✅ 작업 내용
calc_night_schedule()— m = C_max/C_min, D_k = C_max - C_min, Δs = (1/kₑ)·ln mnext_dose()— NIGHT-002 피드용 다음 섭취 시점🔍 완료 조건
📎 참고
core/pharmacokinetics.py상수로 승격