add habit goal-period difficulty and habit formation research notes
Ground the 21-day habit myth in actual research (Lally et al. 2010) and let users pick a target period (21/66/254 days or unlimited) matching that study's easy/median/hard automaticity timelines when creating a habit, with progress shown on the habits list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+29
-1
@@ -1,8 +1,17 @@
|
||||
from app.models.habit import ALL_WEEKDAYS_MASK
|
||||
from datetime import date
|
||||
|
||||
from app.models.habit import ALL_WEEKDAYS_MASK, HABIT_DIFFICULTY_TARGET_DAYS, Habit, HabitDifficulty
|
||||
from app.services.log_service import MILESTONE_STREAKS
|
||||
|
||||
_DAY_LABELS = ["월", "화", "수", "목", "금", "토", "일"]
|
||||
|
||||
_DIFFICULTY_LABELS: dict[HabitDifficulty, str] = {
|
||||
HabitDifficulty.EASY: "하 (21일)",
|
||||
HabitDifficulty.MEDIUM: "중 (66일)",
|
||||
HabitDifficulty.HARD: "상 (254일)",
|
||||
HabitDifficulty.UNLIMITED: "기간 무제한",
|
||||
}
|
||||
|
||||
|
||||
def is_milestone_streak(streak: int) -> bool:
|
||||
return streak in MILESTONE_STREAKS
|
||||
@@ -15,6 +24,25 @@ def weekday_label(mask: int) -> str:
|
||||
return ", ".join(days) if days else "선택된 요일 없음"
|
||||
|
||||
|
||||
def difficulty_label(difficulty: HabitDifficulty) -> str:
|
||||
return _DIFFICULTY_LABELS[difficulty]
|
||||
|
||||
|
||||
def goal_progress(habit: Habit) -> dict | None:
|
||||
"""습관의 목표 기간 진행 상황. 기간 무제한(UNLIMITED)이면 None."""
|
||||
target_days = HABIT_DIFFICULTY_TARGET_DAYS[habit.difficulty]
|
||||
if target_days is None:
|
||||
return None
|
||||
elapsed = (date.today() - habit.created_at.date()).days + 1 # 시작일을 1일차로 계산
|
||||
elapsed = max(elapsed, 1)
|
||||
return {
|
||||
"elapsed": min(elapsed, target_days),
|
||||
"target": target_days,
|
||||
"remaining": max(target_days - elapsed, 0),
|
||||
"reached": elapsed >= target_days,
|
||||
}
|
||||
|
||||
|
||||
def heatmap_opacity(checked_count: int, scheduled_count: int) -> float:
|
||||
"""월별 캘린더 히트맵 셀의 배경 투명도(0~0.9)를 계산한다."""
|
||||
if not scheduled_count:
|
||||
|
||||
Reference in New Issue
Block a user