fix: 일정 위치·반복 매핑·수면 UX·추천 pass 연동 - #83
Conversation
There was a problem hiding this comment.
Code Review
Summary\n본 풀 리퀘스트는 일정 생성 및 수정 시 위치 상세 정보(locationDetail)와 반복 일정(recurrence) 필드를 추가하고, 수면 측정 화면에 주간 날짜 스와이프 이동 기능 및 컨디션 기록의 겹친 마커 선택 기능을 도입하는 등 전반적인 상태 관리와 API 연동을 개선합니다. 또한, 현재 시간 동기화 훅의 타이밍을 보완하고 불필요한 장소 최근 검색어 로직을 제거하여 코드를 단순화했습니다.\n\n### Must Fix\n- [medium] src/components/features/sleep/sleep-week-picker.tsx:53\n 문제: 스와이프 제스처의 방향과 이동하는 주간 날짜(이전/다음)의 방향이 반대로 매핑되어 있습니다.\n 왜 문제인지: 사용자가 왼쪽으로 스와이프할 때는 미래(다음 날짜)를 보고자 하는 것이 일반적인 UX 직관인데, 현재 코드에서는 'previous'(과거)로 이동하게 되어 반대로 동작합니다.\n 수정 방향: translationX가 0보다 작을 때 'next'를, 0보다 클 때 'previous'를 호출하도록 변경합니다.\n 예상 영향: 사용자의 스와이프 방향 직관에 맞게 자연스럽게 주간 날짜가 이동합니다.\n- [medium] src/domains/schedule/api/mapper.ts:206-222\n 문제: 종료일(endDate)에 시간(endTime)이 지정되지 않았을 때 기본값으로 '00:00'이 사용되어 종료일 당일의 일정이 검색 결과에서 제외될 수 있습니다.\n 왜 문제인지: 사용자가 종료일을 선택하고 시간을 지정하지 않으면, 검색 범위의 종료 일시가 당일 00:00이 되어 당일 일정이 누락됩니다.\n 수정 방향: 시작일은 '00:00', 종료일은 '23:59'를 기본값으로 사용하도록 개선합니다.\n 예상 영향: 종료일 당일에 해당하는 일정도 누락 없이 정확하게 검색 결과에 포함됩니다.\n\n### Questions\n없음\n\n### Recommendations\n없음\n\n### Good Points\n없음
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (hasMovedDate.value || Math.abs(event.translationX) < DATE_CHANGE_THRESHOLD) return; | ||
|
|
||
| hasMovedDate.value = true; | ||
| runOnJS(onMoveWeek)(event.translationX < 0 ? 'previous' : 'next'); |
There was a problem hiding this comment.
[medium] src/components/features/sleep/sleep-week-picker.tsx:53
문제: 스와이프 제스처의 방향과 이동하는 주간 날짜(이전/다음)의 방향이 반대로 매핑되어 있습니다.
왜 문제인지: 사용자가 왼쪽으로 스와이프(translationX < 0)할 때는 미래(다음 날짜)를 보고자 하는 것이 일반적인 UX 직관인데, 현재 코드에서는 'previous'(과거)로 이동하게 되어 반대로 동작합니다. 반대로 오른쪽으로 스와이프할 때는 'next'(미래)로 이동하게 됩니다.
수정 방향: translationX가 0보다 작을 때 'next'를, 0보다 클 때 'previous'를 호출하도록 변경합니다.
예상 영향: 사용자의 스와이프 방향 직관에 맞게 자연스럽게 주간 날짜가 이동합니다.
| runOnJS(onMoveWeek)(event.translationX < 0 ? 'previous' : 'next'); | |
| runOnJS(onMoveWeek)(event.translationX < 0 ? 'next' : 'previous'); |
References
- 모든 리뷰 코멘트와 설명은 한국어로 간결하고 실행 가능한 형태로 작성해야 합니다. (link)
| startDate: toSearchDateTime(input.startDate, input.startTime), | ||
| endDate: toSearchDateTime(input.endDate, input.endTime), | ||
| page: input.page, | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * 스웨거 응답이 갱신되기 전까지 검색 기간 파라미터를 API 경계에서 보완합니다. | ||
| * 서버는 camelCase 쿼리 키(`startDate`, `endDate`)를 받습니다. | ||
| */ | ||
| type ScheduleSearchDateRangeParams = { | ||
| startDate?: string; | ||
| endDate?: string; | ||
| }; | ||
| function toSearchDateTime(date?: string, time?: string) { | ||
| const normalizedDate = normalizeDateForRequest(date); | ||
|
|
||
| if (!normalizedDate) return undefined; | ||
|
|
||
| return `${normalizedDate}T${normalizeSearchTime(time)}`; | ||
| } | ||
|
|
||
| function normalizeSearchTime(time?: string) { | ||
| return /^([01]\d|2[0-3]):[0-5]\d$/.test(time ?? '') ? time : '00:00'; | ||
| } |
There was a problem hiding this comment.
[medium] src/domains/schedule/api/mapper.ts:206-222
문제: 종료일(endDate)에 시간(endTime)이 지정되지 않았을 때 기본값으로 '00:00'이 사용되어 종료일 당일의 일정이 검색 결과에서 제외될 수 있습니다.
왜 문제인지: 사용자가 종료일을 '2026-07-01'로 선택하고 시간을 지정하지 않으면, 검색 범위의 종료 일시가 '2026-07-01T00:00'이 됩니다. 이로 인해 2026년 7월 1일 당일에 진행되는 대부분의 일정(예: 오전 10시 일정)이 검색 기간을 벗어나 결과에서 누락되는 현상이 발생합니다.
수정 방향: toSearchDateTime 함수에 기본 시간 매개변수(defaultTime)를 추가하여, 시작일(startDate)은 '00:00', 종료일(endDate)은 '23:59'를 기본값으로 사용하도록 개선합니다.
예상 영향: 종료일 당일에 해당하는 일정도 누락 없이 정확하게 검색 결과에 포함됩니다.
| startDate: toSearchDateTime(input.startDate, input.startTime), | |
| endDate: toSearchDateTime(input.endDate, input.endTime), | |
| page: input.page, | |
| }; | |
| } | |
| /** | |
| * 스웨거 응답이 갱신되기 전까지 검색 기간 파라미터를 API 경계에서 보완합니다. | |
| * 서버는 camelCase 쿼리 키(`startDate`, `endDate`)를 받습니다. | |
| */ | |
| type ScheduleSearchDateRangeParams = { | |
| startDate?: string; | |
| endDate?: string; | |
| }; | |
| function toSearchDateTime(date?: string, time?: string) { | |
| const normalizedDate = normalizeDateForRequest(date); | |
| if (!normalizedDate) return undefined; | |
| return `${normalizedDate}T${normalizeSearchTime(time)}`; | |
| } | |
| function normalizeSearchTime(time?: string) { | |
| return /^([01]\d|2[0-3]):[0-5]\d$/.test(time ?? '') ? time : '00:00'; | |
| } | |
| startDate: toSearchDateTime(input.startDate, input.startTime, '00:00'), | |
| endDate: toSearchDateTime(input.endDate, input.endTime, '23:59'), | |
| page: input.page, | |
| }; | |
| } | |
| function toSearchDateTime(date?: string, time?: string, defaultTime = '00:00') { | |
| const normalizedDate = normalizeDateForRequest(date); | |
| if (!normalizedDate) return undefined; | |
| return `${normalizedDate}T${normalizeSearchTime(time, defaultTime)}`; | |
| } | |
| function normalizeSearchTime(time?: string, defaultTime = '00:00') { | |
| return /^([01]\d|2[0-3]):[0-5]\d$/.test(time ?? '') ? time : defaultTime; | |
| } |
References
- 모든 리뷰 코멘트와 설명은 한국어로 간결하고 실행 가능한 형태로 작성해야 합니다. (link)
작업 개요
location_detail을 전송변경 유형
UI 변경 사항
startTime/endTime포함(ISO 일시)rest) 추천은 패스 버튼 비노출, pass API Orval 연동useCurrentTime분 경계 동기화테스트
npm run type-checknpm run lint환경변수/설정
.env.example업데이트 완료필요한 값:
참고 사항