add day-detail view to monthly history calendar
날짜 셀 클릭 시 그 날 예정된 습관별 완료/실패/미완료 상태를 htmx로 불러와 보여준다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.habit import Habit, HabitStatus, HabitType
|
||||
from app.models.habit_log import HabitLog, HabitLogStatus
|
||||
from app.schemas.habit_log import HabitStats, MonthlySummaryDay, TodayItem, WeeklyMatrixRow
|
||||
from app.schemas.habit_log import DayDetailItem, HabitStats, MonthlySummaryDay, TodayItem, WeeklyMatrixRow
|
||||
from app.schemas.level import LevelInfo
|
||||
from app.services import habit_service, level_service, push_service
|
||||
|
||||
@@ -182,6 +182,51 @@ def get_monthly_summary(db: Session, user_id: int, year: int, month: int) -> lis
|
||||
return summaries
|
||||
|
||||
|
||||
def get_day_detail(db: Session, user_id: int, target_date: date) -> list[DayDetailItem]:
|
||||
"""월별 캘린더에서 특정 날짜를 선택했을 때, 그 날 예정되어 있던 습관별 체크/실패/미결정 상태를 반환한다.
|
||||
|
||||
get_monthly_summary와 같은 규칙(현재 active 습관 기준, 습관 생성일 이전 제외, 과거 요일 변경
|
||||
이력 미추적)을 그대로 따른다.
|
||||
"""
|
||||
active_habits = habit_service.list_habits(db, user_id, status=HabitStatus.ACTIVE)
|
||||
scheduled = [
|
||||
h for h in active_habits if h.created_at.date() <= target_date and h.is_scheduled_on(target_date.weekday())
|
||||
]
|
||||
|
||||
habit_ids = [h.id for h in scheduled]
|
||||
logs_by_habit: dict[int, HabitLogStatus] = {}
|
||||
if habit_ids:
|
||||
rows = db.execute(
|
||||
select(HabitLog.habit_id, HabitLog.status).where(
|
||||
HabitLog.habit_id.in_(habit_ids), HabitLog.log_date == target_date
|
||||
)
|
||||
).all()
|
||||
logs_by_habit = {r[0]: r[1] for r in rows}
|
||||
|
||||
today = date.today()
|
||||
items = []
|
||||
for h in scheduled:
|
||||
log_status = logs_by_habit.get(h.id)
|
||||
if log_status == HabitLogStatus.DONE:
|
||||
status = "checked"
|
||||
elif log_status == HabitLogStatus.FAILED:
|
||||
status = "failed"
|
||||
elif target_date < today:
|
||||
status = "missed"
|
||||
else:
|
||||
status = "pending"
|
||||
items.append(
|
||||
DayDetailItem(
|
||||
habit_id=h.id,
|
||||
name=h.name,
|
||||
habit_type=h.habit_type.value,
|
||||
condition_text=h.condition_text,
|
||||
status=status,
|
||||
)
|
||||
)
|
||||
return items
|
||||
|
||||
|
||||
def summarize_completion_rate(summaries: list[MonthlySummaryDay], up_to: date) -> float:
|
||||
"""월별 요약에서 up_to(보통 오늘)까지 지난 날짜만 모아 전체 완료율(%)을 계산한다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user