---
title: "📓 작업일지 — 달력 복수기록일 클릭 시 기록 선택 UI 신설 (데스크탑 팝오버 / 모바일 하단시트)"
category: "worklog"
parent: "Claude Code 작업일지"
updated: "2026-07-03"
priority: "Medium"
purpose: "History 달력에서 하루에 기록이 2개 이상 있을 때, 기존처럼 바로 싱글카드가 열리는 대신 먼저 어떤 기록을 볼지 선택하는 UI를 신설한 기록. Codex 검수로 시간정렬 유효성·팝오버 오버플로 문제를 잡고, CF 빌드를 막던 타입에러까지 수정해 실제 배포까지 이어졌다."
read_when: ["CalendarRecordPicker", "달력 복수기록 선택", "미니 팝오버", "하단 dim 시트", "CF 빌드 실패 tsc 에러"]
document_type: "개발일지"
source_status: "generated"
knowledge_group: "03_history"
work_timestamp: "20260703_220630"
source_of_truth: "https://dallog-tools.hansbridge.co.kr/knowledge/"
context: "달록 본레포(ccy-hansbridge/dallog), 커밋 15fb5d6(feat) → 66b33c4(Codex 검수반영) → d10e5d0(빌드실패 원인수정), 2026-07-03 21:14~22:06. 거버넌스 §0.6 컨펌 후 착수."
---

# 작업일지 — 달력 복수기록일 클릭 시 기록 선택 UI 신설

> History 달력에서 하루에 기록이 2개 이상 있는 날짜를 클릭했을 때 어느 기록을 볼지 먼저 선택하는 UI를 새로 만든 스레드. 기능 구현(feat) → Codex 검수 반영(fix) → 실은 CF 빌드를 막고 있던 타입에러 수정(fix), 세 커밋으로 이어졌다.

## 1. 무엇을 했나

### 기능 신설 (`15fb5d6`, 21:14)
- 달력 날짜 클릭 시: 기록이 1개면 기존처럼 바로 싱글카드가 열리고, 2개 이상이면 선택 UI가 먼저 뜨고 선택 시 해당 싱글카드가 열림.
- 데스크탑 = 날짜 칸 옆에 뜨는 미니 팝오버(기본은 오른쪽, 공간이 부족하면 왼쪽/위로 보정하며 뷰포트 안에 클램프). 모바일 = dim 배경 + 하단 풀폭 시트.
- 목록 정렬: 러닝은 `run_time`이 전부 있으면 시간순, 없으면 배열 순서. 근력은 `label` 우선, 없으면 `detectParts` fallback. 표기는 러닝 "러닝·Xkm" / 근력 "근력·루틴명".
- 닫힘 조건: 바깥 클릭·다른 날짜 클릭·ESC·싱글카드 오픈. 달력 칸 표시·큰 썸네일·셀모드는 무변경.
- 신규 컴포넌트 `CalendarRecordPicker` 신설, 기존 토큰만 사용(토큰맵 체제 규율 §0.6 컨펌 후 착수).

### Codex 검수 반영 (`66b33c4`, 21:23)
- **[blocking]** 러닝 시간정렬이 `run_time_hour`만 검사하고 있었는데, `hour`와 `period`가 둘 다 non-null일 때만 유효한 시간으로 봐야 한다는 스펙(안정적 시간 없으면 배열순서 유지)을 놓쳐 `period` 누락 러닝이 정렬에 섞여 들어가던 결함을 수정.
- **[minor]** `.calpick--pop`/`.calpick--sheet`에 `max-height`(70vh/80vh) + `overflow-y:auto` 추가 — 기록이 많은 날 팝오버/시트가 화면 밖으로 넘치던 클램프 무력화 문제 방지.
- **[cosmetic]** GAP/PAD JS 상수가 뷰포트 위치계산용(CSS 아님·§3-1 토큰화 대상 아님)임을 명확히 하는 주석 추가.

### CF 빌드 실패 원인 수정 (`d10e5d0`, 22:06)
- `handleDayClick(e, agg, c.iso)` 호출에서 `c.iso`가 `string | null` 타입인데 파라미터는 `string` 타입이라, onClick 클로저 안에서 TypeScript의 타입 좁히기가 실패해 tsc 에러 2건이 발생 — 이로 인해 CF Pages의 `tsc && vite build`가 실패해 이 기능이 실제로는 배포되지 않고 있었음(가드 위치 1056에서 non-null이 보장되므로 `c.iso!` non-null 단언으로 해결).
- 검증 방법의 실수도 함께 기록: 이전 검증이 `npx vite build`만 실행해 tsc를 생략했던 것이 원인 → 이후 `npm run build`(tsc 포함)로 검증하도록 교정.

## 2. 주요 변경 파일

| 파일 | 내용 |
|---|---|
| `src/components/CalendarRecordPicker.tsx` | 신규 컴포넌트(84줄) + Codex 반영 수정 |
| `src/pages/History.tsx` | 달력 클릭 핸들러 연결(31줄) + non-null 단언 수정 |
| `src/index.css` | 팝오버/시트 스타일(14줄) + max-height 오버플로 방지 |

## 3. 관련 커밋

- `15fb5d6` feat(history): 달력 복수기록일 클릭 시 기록 선택 UI — 데스크탑 미니 팝오버 / 모바일 dim 하단시트 (2026-07-03 21:14)
- `66b33c4` fix(history): 달력 선택 UI Codex 검수 반영 — 시간정렬 유효성·팝오버 오버플로·상수 주석 (2026-07-03 21:23)
- `d10e5d0` fix(history): 달력 선택 UI 타입에러 수정 — c.iso non-null 단언(CF 빌드 실패로 미배포였던 원인) (2026-07-03 22:06)

## 4. 남은 이슈

커밋 기준 별도로 언급된 남은 이슈는 없음. 다만 이 스레드는 "코드가 tsc·리뷰상 정상이어도 CF 빌드·실배포까지 확인해야 한다"는 교훈의 실제 사례로 남아있다.
