Skip to content

fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)#394

Merged
dydals3440 merged 2 commits into
developfrom
fix/inquiry-keyboard-ux
Mar 15, 2026
Merged

fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)#394
dydals3440 merged 2 commits into
developfrom
fix/inquiry-keyboard-ux

Conversation

@dydals3440
Copy link
Copy Markdown
Member

@dydals3440 dydals3440 commented Mar 15, 2026

📋 개요

문의하기 화면에서 TextArea 포커스 시 키보드가 올라올 때 jittering 없이 자연스럽게 스크롤되도록 키보드 UX를 개선합니다.

🏷️ 변경 유형

  • 🐛 fix - 버그 수정

📦 영향 범위

  • apps/mobile - Expo 모바일 앱

📝 변경 내용

  • KeyboardAwareScrollView를 제거하고 ScrollView + automaticallyAdjustKeyboardInsets로 대체
  • useKeyboardHandleronMove 이벤트로 키보드 움직임 시작 즉시 scrollToEnd 트리거
  • Reanimated scrollTo를 사용해 UI 스레드에서 직접 스크롤 (JS 브릿지 오버헤드 제거)
  • useSharedValue 플래그로 onMove 매 프레임 호출 시 중복 스크롤 방지

KeyboardAwareScrollView를 사용하지 않는가

현재 react-native-keyboard-controller 1.20.7에서 iOS의 scrollRectToVisibleKeyboardAwareScrollViewcontentInset 조정과 충돌하여 jittering이 발생합니다 (#856). 이 문제는 PR #1336에서 수정되었으나 아직 릴리스되지 않았습니다.

🧪 테스트

테스트 방법

  1. 설정 > 문의하기 화면 진입
  2. 문의 내용 TextArea 터치 → jittering 없이 부드러운 스크롤 확인
  3. 글자 수 카운터 보이는지 확인
  4. 키보드 닫힌 상태에서 Radio 선택 정상 동작 확인
  5. "문의 보내기" 버튼 클릭 정상 동작 확인

✅ 체크리스트

작성자 확인

  • 코드가 프로젝트의 코딩 컨벤션을 따릅니다
  • pnpm check (Biome) 검사를 통과했습니다
  • 커밋 메시지가 Conventional Commits 규칙을 따릅니다

🔗 관련 이슈

Closes #393

📸 스크린샷 (UI 변경 시)

Before After
https://github.com/user-attachments/assets/8d850655-50a9-437e-929b-2d891ad5cbae https://github.com/user-attachments/assets/587e5fc7-da64-4a6d-94f0-494ba1af01b9

@dydals3440 dydals3440 added type: fix 🐛 버그 수정 - 사용자 이탈을 방지하고 시스템 안정성을 확보하는 작업 scope: mobile 📱 모바일 - Expo 기반 모바일 앱 UI/UX 및 클라이언트 로직 관련 labels Mar 15, 2026
@dydals3440 dydals3440 self-assigned this Mar 15, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

문의하기 화면에서 키보드가 나타날 때 발생하는 스크롤 UX 문제를 해결하기 위해 전반적인 키보드 처리 로직을 개선했습니다. 기존 KeyboardAwareScrollView의 한계를 극복하고, react-native-keyboard-controller와 Reanimated를 활용하여 키보드 등장 시 화면이 부드럽게 스크롤되도록 하여 사용자 경험을 향상시켰습니다.

Highlights

  • KeyboardAwareScrollView 대체: 기존의 KeyboardAwareScrollView를 제거하고 ScrollViewautomaticallyAdjustKeyboardInsets를 사용하여 키보드 동작을 개선했습니다.
  • 키보드 이벤트 처리 개선: useKeyboardHandleronMove 이벤트를 활용하여 키보드가 올라올 때 즉시 scrollToEnd를 트리거하도록 구현했습니다.
  • 성능 최적화: Reanimated의 scrollTo를 사용하여 UI 스레드에서 직접 스크롤을 처리함으로써 JS 브릿지 오버헤드를 줄였습니다.
  • 중복 스크롤 방지: useSharedValue 플래그를 도입하여 onMove 이벤트가 매 프레임 호출될 때 발생하는 중복 스크롤을 방지했습니다.
Changelog
  • apps/mobile/app/(app)/settings/inquiry.tsx
    • react-native-keyboard-controllerreact-native-reanimated 관련 모듈을 임포트했습니다.
    • AnimatedScrollView 컴포넌트를 생성하고 useAnimatedRef, useSharedValue 훅을 추가했습니다.
    • useKeyboardHandler 훅을 사용하여 키보드 움직임에 따라 스크롤을 제어하는 로직을 구현했습니다.
    • 기존 ScrollViewAnimatedScrollView로 변경하고 automaticallyAdjustKeyboardInsets 속성을 추가했습니다.
Activity
  • 이 PR에는 아직 사람의 활동(댓글, 리뷰 등)이 없습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dydals3440 dydals3440 requested a review from hijjoy March 15, 2026 13:31
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

문의하기 화면의 키보드 UX를 개선하기 위해 KeyboardAwareScrollViewScrollViewuseKeyboardHandler 조합으로 대체한 변경 내용을 확인했습니다. 이 과정에서 reanimatedscrollTo를 사용하여 UI 스레드에서 스크롤을 직접 제어하도록 구현되었는데, 스크롤 위치를 지정할 때 사용된 매직 넘버에 대한 개선 제안을 리뷰 코멘트로 남겼습니다. 해당 부분을 동적으로 계산된 값으로 대체하면 코드의 안정성과 명확성을 높일 수 있을 것입니다.

Comment thread apps/mobile/app/(app)/settings/inquiry.tsx Outdated
onContentSizeChange로 콘텐츠 높이를 추적하여 scrollTo의
하드코딩된 9999 값을 제거하고 정확한 스크롤 위치를 사용
@dydals3440 dydals3440 merged commit c5c4a1a into develop Mar 15, 2026
3 checks passed
@dydals3440 dydals3440 deleted the fix/inquiry-keyboard-ux branch March 15, 2026 13:37
@dydals3440 dydals3440 mentioned this pull request Mar 15, 2026
dydals3440 added a commit that referenced this pull request Mar 15, 2026
* feat(mobile): 태블릿 지원 true 설정

* feat(mobile): 소셜 로그인 버튼 UI 통일 및 Apple HIG 준수 (#356)

- 모든 소셜 로그인 버튼을 동일한 SocialLoginButton(풀 버튼) 형태로 통일
- Apple 버튼 다크모드 대응: 전용 색상 토큰(apple-button/apple-button-dark) 추가
- Apple 로고 SVG fill을 currentColor로 변경하여 colorClassName 지원
- 미사용 SocialLoginIconButton 컴포넌트 및 "또는" 구분선 제거

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): Firebase 자동 screen_view 중복 수집 비활성화

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정 (#359)

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정

- gray 5~10 L값 교정 (반올림으로 인한 어둡게 렌더링 수정)
- gray-10 보라빛 틴트 제거 (C=0.005 H=285 → 0)
- main/secondary/error 브랜드 색상 스펙 hex 정밀 매칭
- dark white 따뜻한 틴트 제거 (H=29 → 무채색)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 다크 모드 background/surface 색상 틴트 제거

- --background: 따뜻한 틴트(C=0.0056, H=29) 제거 → 무채색
- --surface: 보라빛 틴트(C=0.005, H=285) 제거 → 무채색

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 목표 달성 배지 기능 추가 (#360)

* feat(mobile): 주간 달성 배지 기능 추가

- 주간 완료율 기반 배지 시스템 (perfect/almost/completed)
- 상장 스타일 요약 카드 및 배지 목록 UI
- Achievement 모델, 서비스, 매퍼, 쿼리, 뷰모델 구현
- DI 컨테이너 등록 및 마이페이지 내비게이션 연결

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 패턴 아키텍처 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 긴 텍스트 잘림 방지를 위한 레이아웃 수정

- 리포트 헤더 날짜 범위 flex-wrap 적용
- 프리미엄 배너, 제안 목록 텍스트 정렬 및 줄바꿈 전략 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(mobile): 달성 배지 UI 가이드 문서 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 달성 배지 연도를 현재 연도 자동 계산으로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): weekly-badge 관련 로깅 추가

* refactor(mobile): 배지 이미지를 webp 포맷으로 변환

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 예외 케이스 가이드 추가

단순 변환은 select에서 인라인 처리 가능하다는 예외 케이스 문서화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 상세 페이지 추가

- detail API 연결 (service + query key + query options)
- achievements/[year]/[week] 상장 카드 상세 화면
- 리스트 아이템 탭 → 상세 네비게이션 + ListRow 리팩토링

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): CertificateBorder 공용 컴포넌트 분리

AchievementSummaryCard에서 CertificateBorder를 별도 파일로 추출하여
상세 페이지와 리스트 요약 카드에서 공유

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가 (#365)

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가

- ITimezoneStrategy 인터페이스 추출, 모든 strategy에 implements 적용
- handleHourlySweep → handleMinuteSweep 메서드명 정정
- pushEnabled 유저 없는 타임존의 WeeklyAchievement catch-up 로직 추가
- wrapAllTimezones 캐시 메서드 및 allTimezones 캐시 키 추가
- subtractMonths 날짜 유틸리티 추가
- jobs barrel export 추가

* refactor(api): WeeklyAchievement catch-up 중복 dayjs 계산 제거 및 테스트 데이터 보정

* feat(mobile): 반복 설정 UX 개선 및 시스템 글꼴 스케일 대응 (#363)

* feat(mobile): 반복 설정 날짜 선택 UX 개선

- 반복 기간 설정 라벨 변경 및 날짜 범위 표시 개선
- 선택된 반복 요일 요약 텍스트 추가
- 반복 모드에서 오늘 날짜 배경 하이라이트 비활성화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 피드 프로필 이름 최대 너비 제한 및 InfoIcon 텍스트 전환

- 긴 이름(최대 20자)이 레이아웃을 깨지 않도록 max-w + numberOfLines 적용
- InfoIcon SVG를 ⓘ 텍스트로 변경하여 폰트 스케일 대응

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 시스템 글꼴 크기 비례 스케일링 유틸 함수 추가

fontScaledSize(size, ratio) — PixelRatio.getFontScale() 기반으로
아이콘/버튼 크기를 시스템 글꼴에 비례하여 스케일링한다.
ratio 파라미터로 반영 비율 조절 가능 (기본 0.5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 아이콘/버튼 시스템 글꼴 스케일 적용 및 바텀시트 레이아웃 개선

- TodoFormContent: chips flex-wrap 레이아웃으로 변경, 버튼/아이콘 fontScaledSize 적용
- PickerHeader: CloseIcon fontScaledSize 적용
- TodoList: 카테고리 PlusIcon fontScaledSize 적용
- ProfileCard: CopyIcon fontScaledSize 적용
- KeyboardBottomSheet: 하단 패딩 여유 추가
- testing-guide: 유틸 함수 테스트 가이드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): fontScaledSize JSDoc 기본값 수정 (0.3 → 0.5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): fontScaledSize 호출을 인라인으로 변경

- PickerHeader의 HEADER_ICON_SIZE 상수 제거
- TodoFormContent의 scaledButtonSize/scaledIconSize/scaledMicIconSize 변수 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 테스트 설명에서 Given/When/Then 장황한 형식 제거

- testing-guide.md: it 설명은 간결하게 작성하도록 가이드 수정
- scale.test.ts: 7개 테스트 설명을 간결한 한국어로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(docs): 약관 업데이트

* feat(mobile): 24시간제 시간 형식 설정 및 앱 전체 적용 (#369)

* chore(mobile): 알림 설정 설명 문구를 ~해요 체로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 24시간제 설정을 앱 전체 시간 표시에 반영

- 알림 설정 화면에 24시간제 토글 추가
- 할일 목록, 친구 할일, AI 리포트 시간 표시에 timeFormat 반영
- iOS DateTimePicker locale 동적 전환 (en_GB/ko)
- formatTime, formatHour, formatReminderTime에 timeFormat 파라미터 추가
- formatTimeDisplay 유틸 함수 및 테스트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): TodoTimePickerContent에 Suspense boundary 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): formatTimeDisplay 기본값을 TWELVE_HOUR로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 공유 기능 추가 ⭐️  (#367)

* feat(mobile): 주간 배지 공유 기능 추가

- useShareView 훅으로 ViewShot 캡처 + expo-sharing 공유 로직 분리
- 배지 상세/요약 화면에 공유 버튼 추가
- badge_share_attempted 애널리틱스 이벤트 추가
- ShareIcon 아이콘 추가 및 fontScaledSize 적용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 공유 캡처 실패 시 에러 토스트 추가

- isAvailableAsync 체크를 캡처 전으로 이동
- 캡처 실패 시 에러 토스트 표시
- trackEvent를 shareCapture 전으로 이동

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 배지 목록 빈 상태 UI를 상장 스타일로 개선

- 기본 Result 컴포넌트 대신 CertificateBorder 활용한 empty state
- 기록 영역에 Result 컴포넌트로 안내 표시
- badge_empty 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 콕 찌르기 쿨다운 에러 메시지 수정

- 오늘 할 일 기반이므로 시간 안내 대신 상태 안내로 변경

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#371)

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#370)

* feat(mobile): 카테고리 id를 기준으로 바로 선택할 수 있게 UX 변경

* refactor(api): Gemini 코드 리뷰 반영 — jobId 타임존 버그 수정

* feat(api): 투두 파싱 프롬프트에 요일 약어 및 월+요일 복합 규칙 추가

- DayAbbr 규칙: 한글 요일 약어 매핑(월=MON, 화=TUE, ...) 및 조합 패턴(월수금→MON+WED+FRI)
- Compound 확장: N월+요일약어→isRecurring:true, startDate=N월1일, endDate=N월말일
- "4월 월수금 출근" 같은 월+요일 복합 표현의 endDate가 해당 월 말일로 정확히 설정됨

* feat(mobile): v1.0.1 update

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장 (#376)

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장

closes #375

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV persist 함수 네이밍 통일

- useState setter는 관례적 네이밍(setX) 유지
- MMKV 저장 포함 함수는 persistX로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 캘린더 뷰 모드 읽기에서 타입 단언 제거

- VALID_VIEW_MODES 배열 + as CalendarViewMode 대신 직접 문자열 비교로 변경
- TypeScript 자동 narrowing 활용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV 저장소에 DIP 적용 및 preference 순수 함수 분리

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#378)

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#377)

* refactor(mobile): 탭 바 오버레이 패딩 상수 추출 (#377)

하드코딩된 paddingBottom: 120을 LAYOUT.tabBarOverlayPadding 상수로 분리

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 (#379)

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 추가

- todo_created 이벤트에 source, is_recurring, has_scheduled_time, is_all_day, visibility 속성 추가
- 반복 할 일 생성(createRecurringTodo) 추적 추가
- category_created에 color 속성, category_updated 이벤트 신규 추가
- AI 파싱 source를 react-hook-form 상태로 관리 (props 없이)
- friend_request_accepted, friend_request_rejected 이벤트 추가
- onSuccess 내 trackEvent 호출 순서 통일 (invalidate → toast → trackEvent)

* fix(mobile): onSuccess 내 trackEvent 호출 순서 통일 (Gemini review)

카테고리 생성/수정 mutation에서 trackEvent를 invalidateQueries, toast 뒤로 이동하여
전체 코드베이스의 onSuccess 패턴(invalidate → toast → trackEvent)과 일관성 유지

* feat(mobile): 문의하기 기능 추가 (#381)

* feat(mobile): 문의하기 기능 추가 (#380)

* refactor(mobile): CONTENT_PLACEHOLDER를 멀티라인 템플릿 리터럴로 변환 (#380)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#383)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#382)

* refactor(mobile): SettingNavigation Compound Component 패턴 전환 (#382)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#385)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#384)

* test(api): 카카오 토큰 검증 시 secure_resource 파라미터 검증 추가 (#384)

* refactor(api): secure_resource 파라미터를 URL 상수에 직접 포함 (#384)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386) (#387)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386)

* refactor(api): countTodayTodos 쿼리 가독성 개선 (#386)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#389)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#388)

* refactor(mobile): ThemedAppleIcon 제거, dark: modifier로 통일 (#388)

* chore(mobile): v1.0.2 버전 업데이트

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#392)

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#391)

* fix(mobile): 카테고리 바텀시트 stale state 및 방어 코드 개선 (#391)

- CategorySelectBottomSheet: {isOpen && (...)} 패턴으로 재오픈 시 선택 상태 초기화
- SuggestionCategoryBottomSheet: ?? 0 제거, early return null로 방어 코드 개선

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#394)

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)

* refactor(mobile): scrollTo 매직 넘버를 실제 콘텐츠 높이로 대체

onContentSizeChange로 콘텐츠 높이를 추적하여 scrollTo의
하드코딩된 9999 값을 제거하고 정확한 스크롤 위치를 사용

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가 (#395)

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가

Follow 모델에 sortOrder 필드를 추가하고, 친구 목록에서 꾹 눌러
드래그로 순서를 변경할 수 있는 기능을 구현한다.

API:
- Prisma 스키마에 sortOrder 필드 및 인덱스 추가
- PATCH /follows/friends/:followId/reorder 엔드포인트 추가
- 상대 위치 기반 reorder + shift 알고리즘 구현
- 친구 수락 시 sortOrder 자동 할당 (maxSortOrder + 1)
- 기존 데이터 하위 호환 SQL 마이그레이션

Mobile:
- DraggableFlatList 기반 드래그 앤 드롭 UI
- 낙관적 업데이트 훅 (useDraggableFriendReorderList)
- reorderFriend 서비스 메서드 및 mutation options

* fix: 코드 리뷰 반영 및 친구 목록 레이아웃 수정

- reorder 시 followRequestNotFound → friendReorderTargetNotFound로 변경하여
  순서 변경 맥락에 맞는 에러 메시지 사용
- DraggableFlatList에 containerStyle flex:1 추가하여 전체 높이 채우도록 수정

* refactor: 코드 스타일 개선 및 analytics 이벤트 추가

- 단일 라인 if/return을 멀티 라인 브레이스로 변환 (가독성)
- API 로그 메시지 영문 → 한국어 전환 (로깅 가이드 준수)
- friend_reordered analytics 이벤트 추가

* chore(mobile): v1.0.3 버전 업데이트

---------

Co-authored-by: hyewon <hijjoy@naver.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dydals3440 added a commit that referenced this pull request Mar 17, 2026
* feat(mobile): 태블릿 지원 true 설정

* feat(mobile): 소셜 로그인 버튼 UI 통일 및 Apple HIG 준수 (#356)

- 모든 소셜 로그인 버튼을 동일한 SocialLoginButton(풀 버튼) 형태로 통일
- Apple 버튼 다크모드 대응: 전용 색상 토큰(apple-button/apple-button-dark) 추가
- Apple 로고 SVG fill을 currentColor로 변경하여 colorClassName 지원
- 미사용 SocialLoginIconButton 컴포넌트 및 "또는" 구분선 제거

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): Firebase 자동 screen_view 중복 수집 비활성화

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정 (#359)

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정

- gray 5~10 L값 교정 (반올림으로 인한 어둡게 렌더링 수정)
- gray-10 보라빛 틴트 제거 (C=0.005 H=285 → 0)
- main/secondary/error 브랜드 색상 스펙 hex 정밀 매칭
- dark white 따뜻한 틴트 제거 (H=29 → 무채색)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 다크 모드 background/surface 색상 틴트 제거

- --background: 따뜻한 틴트(C=0.0056, H=29) 제거 → 무채색
- --surface: 보라빛 틴트(C=0.005, H=285) 제거 → 무채색

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 목표 달성 배지 기능 추가 (#360)

* feat(mobile): 주간 달성 배지 기능 추가

- 주간 완료율 기반 배지 시스템 (perfect/almost/completed)
- 상장 스타일 요약 카드 및 배지 목록 UI
- Achievement 모델, 서비스, 매퍼, 쿼리, 뷰모델 구현
- DI 컨테이너 등록 및 마이페이지 내비게이션 연결

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 패턴 아키텍처 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 긴 텍스트 잘림 방지를 위한 레이아웃 수정

- 리포트 헤더 날짜 범위 flex-wrap 적용
- 프리미엄 배너, 제안 목록 텍스트 정렬 및 줄바꿈 전략 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(mobile): 달성 배지 UI 가이드 문서 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 달성 배지 연도를 현재 연도 자동 계산으로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): weekly-badge 관련 로깅 추가

* refactor(mobile): 배지 이미지를 webp 포맷으로 변환

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 예외 케이스 가이드 추가

단순 변환은 select에서 인라인 처리 가능하다는 예외 케이스 문서화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 상세 페이지 추가

- detail API 연결 (service + query key + query options)
- achievements/[year]/[week] 상장 카드 상세 화면
- 리스트 아이템 탭 → 상세 네비게이션 + ListRow 리팩토링

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): CertificateBorder 공용 컴포넌트 분리

AchievementSummaryCard에서 CertificateBorder를 별도 파일로 추출하여
상세 페이지와 리스트 요약 카드에서 공유

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가 (#365)

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가

- ITimezoneStrategy 인터페이스 추출, 모든 strategy에 implements 적용
- handleHourlySweep → handleMinuteSweep 메서드명 정정
- pushEnabled 유저 없는 타임존의 WeeklyAchievement catch-up 로직 추가
- wrapAllTimezones 캐시 메서드 및 allTimezones 캐시 키 추가
- subtractMonths 날짜 유틸리티 추가
- jobs barrel export 추가

* refactor(api): WeeklyAchievement catch-up 중복 dayjs 계산 제거 및 테스트 데이터 보정

* feat(mobile): 반복 설정 UX 개선 및 시스템 글꼴 스케일 대응 (#363)

* feat(mobile): 반복 설정 날짜 선택 UX 개선

- 반복 기간 설정 라벨 변경 및 날짜 범위 표시 개선
- 선택된 반복 요일 요약 텍스트 추가
- 반복 모드에서 오늘 날짜 배경 하이라이트 비활성화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 피드 프로필 이름 최대 너비 제한 및 InfoIcon 텍스트 전환

- 긴 이름(최대 20자)이 레이아웃을 깨지 않도록 max-w + numberOfLines 적용
- InfoIcon SVG를 ⓘ 텍스트로 변경하여 폰트 스케일 대응

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 시스템 글꼴 크기 비례 스케일링 유틸 함수 추가

fontScaledSize(size, ratio) — PixelRatio.getFontScale() 기반으로
아이콘/버튼 크기를 시스템 글꼴에 비례하여 스케일링한다.
ratio 파라미터로 반영 비율 조절 가능 (기본 0.5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 아이콘/버튼 시스템 글꼴 스케일 적용 및 바텀시트 레이아웃 개선

- TodoFormContent: chips flex-wrap 레이아웃으로 변경, 버튼/아이콘 fontScaledSize 적용
- PickerHeader: CloseIcon fontScaledSize 적용
- TodoList: 카테고리 PlusIcon fontScaledSize 적용
- ProfileCard: CopyIcon fontScaledSize 적용
- KeyboardBottomSheet: 하단 패딩 여유 추가
- testing-guide: 유틸 함수 테스트 가이드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): fontScaledSize JSDoc 기본값 수정 (0.3 → 0.5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): fontScaledSize 호출을 인라인으로 변경

- PickerHeader의 HEADER_ICON_SIZE 상수 제거
- TodoFormContent의 scaledButtonSize/scaledIconSize/scaledMicIconSize 변수 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 테스트 설명에서 Given/When/Then 장황한 형식 제거

- testing-guide.md: it 설명은 간결하게 작성하도록 가이드 수정
- scale.test.ts: 7개 테스트 설명을 간결한 한국어로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(docs): 약관 업데이트

* feat(mobile): 24시간제 시간 형식 설정 및 앱 전체 적용 (#369)

* chore(mobile): 알림 설정 설명 문구를 ~해요 체로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 24시간제 설정을 앱 전체 시간 표시에 반영

- 알림 설정 화면에 24시간제 토글 추가
- 할일 목록, 친구 할일, AI 리포트 시간 표시에 timeFormat 반영
- iOS DateTimePicker locale 동적 전환 (en_GB/ko)
- formatTime, formatHour, formatReminderTime에 timeFormat 파라미터 추가
- formatTimeDisplay 유틸 함수 및 테스트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): TodoTimePickerContent에 Suspense boundary 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): formatTimeDisplay 기본값을 TWELVE_HOUR로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 공유 기능 추가 ⭐️  (#367)

* feat(mobile): 주간 배지 공유 기능 추가

- useShareView 훅으로 ViewShot 캡처 + expo-sharing 공유 로직 분리
- 배지 상세/요약 화면에 공유 버튼 추가
- badge_share_attempted 애널리틱스 이벤트 추가
- ShareIcon 아이콘 추가 및 fontScaledSize 적용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 공유 캡처 실패 시 에러 토스트 추가

- isAvailableAsync 체크를 캡처 전으로 이동
- 캡처 실패 시 에러 토스트 표시
- trackEvent를 shareCapture 전으로 이동

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 배지 목록 빈 상태 UI를 상장 스타일로 개선

- 기본 Result 컴포넌트 대신 CertificateBorder 활용한 empty state
- 기록 영역에 Result 컴포넌트로 안내 표시
- badge_empty 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 콕 찌르기 쿨다운 에러 메시지 수정

- 오늘 할 일 기반이므로 시간 안내 대신 상태 안내로 변경

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#371)

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#370)

* feat(mobile): 카테고리 id를 기준으로 바로 선택할 수 있게 UX 변경

* refactor(api): Gemini 코드 리뷰 반영 — jobId 타임존 버그 수정

* feat(api): 투두 파싱 프롬프트에 요일 약어 및 월+요일 복합 규칙 추가

- DayAbbr 규칙: 한글 요일 약어 매핑(월=MON, 화=TUE, ...) 및 조합 패턴(월수금→MON+WED+FRI)
- Compound 확장: N월+요일약어→isRecurring:true, startDate=N월1일, endDate=N월말일
- "4월 월수금 출근" 같은 월+요일 복합 표현의 endDate가 해당 월 말일로 정확히 설정됨

* feat(mobile): v1.0.1 update

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장 (#376)

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장

closes #375

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV persist 함수 네이밍 통일

- useState setter는 관례적 네이밍(setX) 유지
- MMKV 저장 포함 함수는 persistX로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 캘린더 뷰 모드 읽기에서 타입 단언 제거

- VALID_VIEW_MODES 배열 + as CalendarViewMode 대신 직접 문자열 비교로 변경
- TypeScript 자동 narrowing 활용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV 저장소에 DIP 적용 및 preference 순수 함수 분리

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#378)

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#377)

* refactor(mobile): 탭 바 오버레이 패딩 상수 추출 (#377)

하드코딩된 paddingBottom: 120을 LAYOUT.tabBarOverlayPadding 상수로 분리

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 (#379)

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 추가

- todo_created 이벤트에 source, is_recurring, has_scheduled_time, is_all_day, visibility 속성 추가
- 반복 할 일 생성(createRecurringTodo) 추적 추가
- category_created에 color 속성, category_updated 이벤트 신규 추가
- AI 파싱 source를 react-hook-form 상태로 관리 (props 없이)
- friend_request_accepted, friend_request_rejected 이벤트 추가
- onSuccess 내 trackEvent 호출 순서 통일 (invalidate → toast → trackEvent)

* fix(mobile): onSuccess 내 trackEvent 호출 순서 통일 (Gemini review)

카테고리 생성/수정 mutation에서 trackEvent를 invalidateQueries, toast 뒤로 이동하여
전체 코드베이스의 onSuccess 패턴(invalidate → toast → trackEvent)과 일관성 유지

* feat(mobile): 문의하기 기능 추가 (#381)

* feat(mobile): 문의하기 기능 추가 (#380)

* refactor(mobile): CONTENT_PLACEHOLDER를 멀티라인 템플릿 리터럴로 변환 (#380)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#383)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#382)

* refactor(mobile): SettingNavigation Compound Component 패턴 전환 (#382)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#385)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#384)

* test(api): 카카오 토큰 검증 시 secure_resource 파라미터 검증 추가 (#384)

* refactor(api): secure_resource 파라미터를 URL 상수에 직접 포함 (#384)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386) (#387)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386)

* refactor(api): countTodayTodos 쿼리 가독성 개선 (#386)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#389)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#388)

* refactor(mobile): ThemedAppleIcon 제거, dark: modifier로 통일 (#388)

* chore(mobile): v1.0.2 버전 업데이트

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#392)

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#391)

* fix(mobile): 카테고리 바텀시트 stale state 및 방어 코드 개선 (#391)

- CategorySelectBottomSheet: {isOpen && (...)} 패턴으로 재오픈 시 선택 상태 초기화
- SuggestionCategoryBottomSheet: ?? 0 제거, early return null로 방어 코드 개선

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#394)

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)

* refactor(mobile): scrollTo 매직 넘버를 실제 콘텐츠 높이로 대체

onContentSizeChange로 콘텐츠 높이를 추적하여 scrollTo의
하드코딩된 9999 값을 제거하고 정확한 스크롤 위치를 사용

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가 (#395)

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가

Follow 모델에 sortOrder 필드를 추가하고, 친구 목록에서 꾹 눌러
드래그로 순서를 변경할 수 있는 기능을 구현한다.

API:
- Prisma 스키마에 sortOrder 필드 및 인덱스 추가
- PATCH /follows/friends/:followId/reorder 엔드포인트 추가
- 상대 위치 기반 reorder + shift 알고리즘 구현
- 친구 수락 시 sortOrder 자동 할당 (maxSortOrder + 1)
- 기존 데이터 하위 호환 SQL 마이그레이션

Mobile:
- DraggableFlatList 기반 드래그 앤 드롭 UI
- 낙관적 업데이트 훅 (useDraggableFriendReorderList)
- reorderFriend 서비스 메서드 및 mutation options

* fix: 코드 리뷰 반영 및 친구 목록 레이아웃 수정

- reorder 시 followRequestNotFound → friendReorderTargetNotFound로 변경하여
  순서 변경 맥락에 맞는 에러 메시지 사용
- DraggableFlatList에 containerStyle flex:1 추가하여 전체 높이 채우도록 수정

* refactor: 코드 스타일 개선 및 analytics 이벤트 추가

- 단일 라인 if/return을 멀티 라인 브레이스로 변환 (가독성)
- API 로그 메시지 영문 → 한국어 전환 (로깅 가이드 준수)
- friend_reordered analytics 이벤트 추가

* chore(mobile): v1.0.3 버전 업데이트

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#399)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#398)

* refactor(mobile): notification 모델 아키텍처 준수 리팩토링

- 서버 DTO 스키마를 model에서 제거, @aido/validators에서 import
- Policy에서 비-Policy 함수(isUnread, getExternalUrl) 제거
- 순수 함수 getCategoryLabel, getInternalRoute export
- *Result → *Response 네이밍 통일 (validators 기준)

* fix(api): ai 모듈 import 경로를 상대 경로로 수정

Gemini 코드 리뷰 반영 - @/modules/ 절대 경로를 상대 경로로 변경하여
api-conventions.md 규칙 준수

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#404)

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#403)

* refactor(api): Gemini 코드 리뷰 반영 - colorMap 루프 간결화

* feat(api): AI 제안 패턴 유형 확장 - 순차/발전 패턴 감지 추가 (#406)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#408)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#407)

* refactor(api): Gemini 코드 리뷰 반영 - buildReportPrompt 분기 구조 개선

type 기준으로 먼저 분기한 뒤 hasActivity를 확인하는 구조로 변경하여
중복 조건 제거 및 가독성 향상.

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#410)

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#409)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 가드 강화 (#409)

---------

Co-authored-by: hyewon <hijjoy@naver.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
dydals3440 added a commit that referenced this pull request Mar 19, 2026
* feat(mobile): 태블릿 지원 true 설정

* feat(mobile): 소셜 로그인 버튼 UI 통일 및 Apple HIG 준수 (#356)

- 모든 소셜 로그인 버튼을 동일한 SocialLoginButton(풀 버튼) 형태로 통일
- Apple 버튼 다크모드 대응: 전용 색상 토큰(apple-button/apple-button-dark) 추가
- Apple 로고 SVG fill을 currentColor로 변경하여 colorClassName 지원
- 미사용 SocialLoginIconButton 컴포넌트 및 "또는" 구분선 제거

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): Firebase 자동 screen_view 중복 수집 비활성화

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정 (#359)

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정

- gray 5~10 L값 교정 (반올림으로 인한 어둡게 렌더링 수정)
- gray-10 보라빛 틴트 제거 (C=0.005 H=285 → 0)
- main/secondary/error 브랜드 색상 스펙 hex 정밀 매칭
- dark white 따뜻한 틴트 제거 (H=29 → 무채색)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 다크 모드 background/surface 색상 틴트 제거

- --background: 따뜻한 틴트(C=0.0056, H=29) 제거 → 무채색
- --surface: 보라빛 틴트(C=0.005, H=285) 제거 → 무채색

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 목표 달성 배지 기능 추가 (#360)

* feat(mobile): 주간 달성 배지 기능 추가

- 주간 완료율 기반 배지 시스템 (perfect/almost/completed)
- 상장 스타일 요약 카드 및 배지 목록 UI
- Achievement 모델, 서비스, 매퍼, 쿼리, 뷰모델 구현
- DI 컨테이너 등록 및 마이페이지 내비게이션 연결

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 패턴 아키텍처 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 긴 텍스트 잘림 방지를 위한 레이아웃 수정

- 리포트 헤더 날짜 범위 flex-wrap 적용
- 프리미엄 배너, 제안 목록 텍스트 정렬 및 줄바꿈 전략 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(mobile): 달성 배지 UI 가이드 문서 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 달성 배지 연도를 현재 연도 자동 계산으로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): weekly-badge 관련 로깅 추가

* refactor(mobile): 배지 이미지를 webp 포맷으로 변환

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 예외 케이스 가이드 추가

단순 변환은 select에서 인라인 처리 가능하다는 예외 케이스 문서화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 상세 페이지 추가

- detail API 연결 (service + query key + query options)
- achievements/[year]/[week] 상장 카드 상세 화면
- 리스트 아이템 탭 → 상세 네비게이션 + ListRow 리팩토링

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): CertificateBorder 공용 컴포넌트 분리

AchievementSummaryCard에서 CertificateBorder를 별도 파일로 추출하여
상세 페이지와 리스트 요약 카드에서 공유

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가 (#365)

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가

- ITimezoneStrategy 인터페이스 추출, 모든 strategy에 implements 적용
- handleHourlySweep → handleMinuteSweep 메서드명 정정
- pushEnabled 유저 없는 타임존의 WeeklyAchievement catch-up 로직 추가
- wrapAllTimezones 캐시 메서드 및 allTimezones 캐시 키 추가
- subtractMonths 날짜 유틸리티 추가
- jobs barrel export 추가

* refactor(api): WeeklyAchievement catch-up 중복 dayjs 계산 제거 및 테스트 데이터 보정

* feat(mobile): 반복 설정 UX 개선 및 시스템 글꼴 스케일 대응 (#363)

* feat(mobile): 반복 설정 날짜 선택 UX 개선

- 반복 기간 설정 라벨 변경 및 날짜 범위 표시 개선
- 선택된 반복 요일 요약 텍스트 추가
- 반복 모드에서 오늘 날짜 배경 하이라이트 비활성화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 피드 프로필 이름 최대 너비 제한 및 InfoIcon 텍스트 전환

- 긴 이름(최대 20자)이 레이아웃을 깨지 않도록 max-w + numberOfLines 적용
- InfoIcon SVG를 ⓘ 텍스트로 변경하여 폰트 스케일 대응

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 시스템 글꼴 크기 비례 스케일링 유틸 함수 추가

fontScaledSize(size, ratio) — PixelRatio.getFontScale() 기반으로
아이콘/버튼 크기를 시스템 글꼴에 비례하여 스케일링한다.
ratio 파라미터로 반영 비율 조절 가능 (기본 0.5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 아이콘/버튼 시스템 글꼴 스케일 적용 및 바텀시트 레이아웃 개선

- TodoFormContent: chips flex-wrap 레이아웃으로 변경, 버튼/아이콘 fontScaledSize 적용
- PickerHeader: CloseIcon fontScaledSize 적용
- TodoList: 카테고리 PlusIcon fontScaledSize 적용
- ProfileCard: CopyIcon fontScaledSize 적용
- KeyboardBottomSheet: 하단 패딩 여유 추가
- testing-guide: 유틸 함수 테스트 가이드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): fontScaledSize JSDoc 기본값 수정 (0.3 → 0.5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): fontScaledSize 호출을 인라인으로 변경

- PickerHeader의 HEADER_ICON_SIZE 상수 제거
- TodoFormContent의 scaledButtonSize/scaledIconSize/scaledMicIconSize 변수 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 테스트 설명에서 Given/When/Then 장황한 형식 제거

- testing-guide.md: it 설명은 간결하게 작성하도록 가이드 수정
- scale.test.ts: 7개 테스트 설명을 간결한 한국어로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(docs): 약관 업데이트

* feat(mobile): 24시간제 시간 형식 설정 및 앱 전체 적용 (#369)

* chore(mobile): 알림 설정 설명 문구를 ~해요 체로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 24시간제 설정을 앱 전체 시간 표시에 반영

- 알림 설정 화면에 24시간제 토글 추가
- 할일 목록, 친구 할일, AI 리포트 시간 표시에 timeFormat 반영
- iOS DateTimePicker locale 동적 전환 (en_GB/ko)
- formatTime, formatHour, formatReminderTime에 timeFormat 파라미터 추가
- formatTimeDisplay 유틸 함수 및 테스트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): TodoTimePickerContent에 Suspense boundary 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): formatTimeDisplay 기본값을 TWELVE_HOUR로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 공유 기능 추가 ⭐️  (#367)

* feat(mobile): 주간 배지 공유 기능 추가

- useShareView 훅으로 ViewShot 캡처 + expo-sharing 공유 로직 분리
- 배지 상세/요약 화면에 공유 버튼 추가
- badge_share_attempted 애널리틱스 이벤트 추가
- ShareIcon 아이콘 추가 및 fontScaledSize 적용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 공유 캡처 실패 시 에러 토스트 추가

- isAvailableAsync 체크를 캡처 전으로 이동
- 캡처 실패 시 에러 토스트 표시
- trackEvent를 shareCapture 전으로 이동

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 배지 목록 빈 상태 UI를 상장 스타일로 개선

- 기본 Result 컴포넌트 대신 CertificateBorder 활용한 empty state
- 기록 영역에 Result 컴포넌트로 안내 표시
- badge_empty 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 콕 찌르기 쿨다운 에러 메시지 수정

- 오늘 할 일 기반이므로 시간 안내 대신 상태 안내로 변경

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#371)

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#370)

* feat(mobile): 카테고리 id를 기준으로 바로 선택할 수 있게 UX 변경

* refactor(api): Gemini 코드 리뷰 반영 — jobId 타임존 버그 수정

* feat(api): 투두 파싱 프롬프트에 요일 약어 및 월+요일 복합 규칙 추가

- DayAbbr 규칙: 한글 요일 약어 매핑(월=MON, 화=TUE, ...) 및 조합 패턴(월수금→MON+WED+FRI)
- Compound 확장: N월+요일약어→isRecurring:true, startDate=N월1일, endDate=N월말일
- "4월 월수금 출근" 같은 월+요일 복합 표현의 endDate가 해당 월 말일로 정확히 설정됨

* feat(mobile): v1.0.1 update

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장 (#376)

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장

closes #375

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV persist 함수 네이밍 통일

- useState setter는 관례적 네이밍(setX) 유지
- MMKV 저장 포함 함수는 persistX로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 캘린더 뷰 모드 읽기에서 타입 단언 제거

- VALID_VIEW_MODES 배열 + as CalendarViewMode 대신 직접 문자열 비교로 변경
- TypeScript 자동 narrowing 활용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV 저장소에 DIP 적용 및 preference 순수 함수 분리

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#378)

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#377)

* refactor(mobile): 탭 바 오버레이 패딩 상수 추출 (#377)

하드코딩된 paddingBottom: 120을 LAYOUT.tabBarOverlayPadding 상수로 분리

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 (#379)

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 추가

- todo_created 이벤트에 source, is_recurring, has_scheduled_time, is_all_day, visibility 속성 추가
- 반복 할 일 생성(createRecurringTodo) 추적 추가
- category_created에 color 속성, category_updated 이벤트 신규 추가
- AI 파싱 source를 react-hook-form 상태로 관리 (props 없이)
- friend_request_accepted, friend_request_rejected 이벤트 추가
- onSuccess 내 trackEvent 호출 순서 통일 (invalidate → toast → trackEvent)

* fix(mobile): onSuccess 내 trackEvent 호출 순서 통일 (Gemini review)

카테고리 생성/수정 mutation에서 trackEvent를 invalidateQueries, toast 뒤로 이동하여
전체 코드베이스의 onSuccess 패턴(invalidate → toast → trackEvent)과 일관성 유지

* feat(mobile): 문의하기 기능 추가 (#381)

* feat(mobile): 문의하기 기능 추가 (#380)

* refactor(mobile): CONTENT_PLACEHOLDER를 멀티라인 템플릿 리터럴로 변환 (#380)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#383)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#382)

* refactor(mobile): SettingNavigation Compound Component 패턴 전환 (#382)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#385)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#384)

* test(api): 카카오 토큰 검증 시 secure_resource 파라미터 검증 추가 (#384)

* refactor(api): secure_resource 파라미터를 URL 상수에 직접 포함 (#384)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386) (#387)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386)

* refactor(api): countTodayTodos 쿼리 가독성 개선 (#386)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#389)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#388)

* refactor(mobile): ThemedAppleIcon 제거, dark: modifier로 통일 (#388)

* chore(mobile): v1.0.2 버전 업데이트

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#392)

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#391)

* fix(mobile): 카테고리 바텀시트 stale state 및 방어 코드 개선 (#391)

- CategorySelectBottomSheet: {isOpen && (...)} 패턴으로 재오픈 시 선택 상태 초기화
- SuggestionCategoryBottomSheet: ?? 0 제거, early return null로 방어 코드 개선

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#394)

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)

* refactor(mobile): scrollTo 매직 넘버를 실제 콘텐츠 높이로 대체

onContentSizeChange로 콘텐츠 높이를 추적하여 scrollTo의
하드코딩된 9999 값을 제거하고 정확한 스크롤 위치를 사용

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가 (#395)

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가

Follow 모델에 sortOrder 필드를 추가하고, 친구 목록에서 꾹 눌러
드래그로 순서를 변경할 수 있는 기능을 구현한다.

API:
- Prisma 스키마에 sortOrder 필드 및 인덱스 추가
- PATCH /follows/friends/:followId/reorder 엔드포인트 추가
- 상대 위치 기반 reorder + shift 알고리즘 구현
- 친구 수락 시 sortOrder 자동 할당 (maxSortOrder + 1)
- 기존 데이터 하위 호환 SQL 마이그레이션

Mobile:
- DraggableFlatList 기반 드래그 앤 드롭 UI
- 낙관적 업데이트 훅 (useDraggableFriendReorderList)
- reorderFriend 서비스 메서드 및 mutation options

* fix: 코드 리뷰 반영 및 친구 목록 레이아웃 수정

- reorder 시 followRequestNotFound → friendReorderTargetNotFound로 변경하여
  순서 변경 맥락에 맞는 에러 메시지 사용
- DraggableFlatList에 containerStyle flex:1 추가하여 전체 높이 채우도록 수정

* refactor: 코드 스타일 개선 및 analytics 이벤트 추가

- 단일 라인 if/return을 멀티 라인 브레이스로 변환 (가독성)
- API 로그 메시지 영문 → 한국어 전환 (로깅 가이드 준수)
- friend_reordered analytics 이벤트 추가

* chore(mobile): v1.0.3 버전 업데이트

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#399)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#398)

* refactor(mobile): notification 모델 아키텍처 준수 리팩토링

- 서버 DTO 스키마를 model에서 제거, @aido/validators에서 import
- Policy에서 비-Policy 함수(isUnread, getExternalUrl) 제거
- 순수 함수 getCategoryLabel, getInternalRoute export
- *Result → *Response 네이밍 통일 (validators 기준)

* fix(api): ai 모듈 import 경로를 상대 경로로 수정

Gemini 코드 리뷰 반영 - @/modules/ 절대 경로를 상대 경로로 변경하여
api-conventions.md 규칙 준수

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#404)

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#403)

* refactor(api): Gemini 코드 리뷰 반영 - colorMap 루프 간결화

* feat(api): AI 제안 패턴 유형 확장 - 순차/발전 패턴 감지 추가 (#406)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#408)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#407)

* refactor(api): Gemini 코드 리뷰 반영 - buildReportPrompt 분기 구조 개선

type 기준으로 먼저 분기한 뒤 hasActivity를 확인하는 구조로 변경하여
중복 조건 제거 및 가독성 향상.

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#410)

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#409)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 가드 강화 (#409)

* feat(mobile): 캘린더 날짜별 할일 완료 상태 표시 (#401)

* feat(mobile): RepeatIcon 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 캘린더 날짜별 할일 완료 상태 표시

- 전부 완료: 날짜 아래 파란 물고기 아이콘
- 미완료 할일 있음: 날짜 아래 작은 회색 점
- 할일 없음: 날짜만 표시
- 기존 +N 완료 개수 텍스트 제거

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 할일 바텀시트 칩/반복 분리 리팩토링

- 칩 영역 가로 스크롤 + 반복칩 추가
- 반복 설정 전용 피커 뷰 분리 (TodoRepeatPickerContent)
- 날짜 피커에서 반복 관련 코드 제거
- AiParseButton 컴포넌트로 마이크 로직 캡슐화
- 칩 스타일 아웃라인으로 변경

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): 키보드 열린 상태에서 칩 터치 안 되는 문제 수정

ScrollView의 keyboardShouldPersistTaps 기본값이 "never"라
키보드가 열려있을 때 칩 탭이 키보드 닫기에 소비되어 onPress가 실행되지 않던 문제 수정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 반복 설정 확인 버튼 유효성 검증 추가

- PickerHeader에 isConfirmDisabled prop 추가
- 요일 미선택/종료일 미선택/범위 내 요일 없음 시 확인 버튼 비활성화
- 자동 종료일(+7일) 기본값 제거, 명시적 선택 필요
- hasSelectedDayInRange 유틸 추가 및 테스트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(mobile): hasSelectedDayInRange O(n) 루프를 O(1) 수학 연산으로 개선

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): AI 기능 안내 툴팁 추가

- ⓘ 아이콘 탭 시 Popover로 AI 음성 파싱 사용법 안내
- 툴팁 로직을 AiFeatureTooltip 컴포넌트로 분리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 캘린더 날짜별 카테고리 색상 인디케이터 표시

- 클라이언트 모델/매퍼에 categoryColors 필드 추가
- 카테고리 1개: 단색 점, 2개+: 색상 바 (최대 3색)
- 인디케이터 높이를 물고기 아이콘과 동일하게 정렬

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(tooling): VSCode Biome 저장 시 자동 포맷/린트 설정 추가

  - editor.formatOnSave, organizeImports 추가
  - language-specific 블록 통합
  - deprecated biome.lspBin → biome.lsp.bin 변경

* fix(mobile): Android BottomTabs 경계선 제거 (#414)

* fix(mobile): Android 탭바 콘텐츠 경계 선 제거

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): 캘린더 카테고리 인디케이터 border-radius 조정

* refactor(mobile): 탭바 하단 패딩을 useBottomTabBarHeight로 동적 처리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: hijjoy <hijjoy@hijjoyui-MacBookPro.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 카테고리 관리를 마이 탭으로 이동 및 섹션 구조 UX 개편 (#415)

* feat(mobile): 카테고리 관리를 마이 탭으로 이동 및 섹션 구조 개편

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 플러스버튼 색상 수정

* feat(mobile): 마이탭 섹션 구조 UX 개선 및 UI 미세 조정

- 마이페이지 섹션을 활동/구독/설정/지원으로 재구성
- 카테고리 관리를 활동 섹션으로 이동, 구독을 설정보다 상위 배치
- PlusIcon Flex 래퍼 제거, SettingNavigation 항목 shade 조정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): iOS NativeTabs에서 useBottomTabBarHeight crash 수정 (#418)

* chore(mobile): v1.0.4 변경

---------

Co-authored-by: hyewon <hijjoy@naver.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Kim <matthew@Matthewui-MacBookPro.local>
Co-authored-by: hijjoy <hijjoy@hijjoyui-MacBookPro.local>
dydals3440 added a commit that referenced this pull request Mar 19, 2026
* feat(mobile): 태블릿 지원 true 설정

* feat(mobile): 소셜 로그인 버튼 UI 통일 및 Apple HIG 준수 (#356)

- 모든 소셜 로그인 버튼을 동일한 SocialLoginButton(풀 버튼) 형태로 통일
- Apple 버튼 다크모드 대응: 전용 색상 토큰(apple-button/apple-button-dark) 추가
- Apple 로고 SVG fill을 currentColor로 변경하여 colorClassName 지원
- 미사용 SocialLoginIconButton 컴포넌트 및 "또는" 구분선 제거

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): Firebase 자동 screen_view 중복 수집 비활성화

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정 (#359)

* fix(mobile): 디자인 스펙에 맞게 oklch 색상 값 교정

- gray 5~10 L값 교정 (반올림으로 인한 어둡게 렌더링 수정)
- gray-10 보라빛 틴트 제거 (C=0.005 H=285 → 0)
- main/secondary/error 브랜드 색상 스펙 hex 정밀 매칭
- dark white 따뜻한 틴트 제거 (H=29 → 무채색)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 다크 모드 background/surface 색상 틴트 제거

- --background: 따뜻한 틴트(C=0.0056, H=29) 제거 → 무채색
- --surface: 보라빛 틴트(C=0.005, H=285) 제거 → 무채색

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 목표 달성 배지 기능 추가 (#360)

* feat(mobile): 주간 달성 배지 기능 추가

- 주간 완료율 기반 배지 시스템 (perfect/almost/completed)
- 상장 스타일 요약 카드 및 배지 목록 UI
- Achievement 모델, 서비스, 매퍼, 쿼리, 뷰모델 구현
- DI 컨테이너 등록 및 마이페이지 내비게이션 연결

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 패턴 아키텍처 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 긴 텍스트 잘림 방지를 위한 레이아웃 수정

- 리포트 헤더 날짜 범위 flex-wrap 적용
- 프리미엄 배너, 제안 목록 텍스트 정렬 및 줄바꿈 전략 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(mobile): 달성 배지 UI 가이드 문서 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 달성 배지 연도를 현재 연도 자동 계산으로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): weekly-badge 관련 로깅 추가

* refactor(mobile): 배지 이미지를 webp 포맷으로 변환

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): ViewModel 예외 케이스 가이드 추가

단순 변환은 select에서 인라인 처리 가능하다는 예외 케이스 문서화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 상세 페이지 추가

- detail API 연결 (service + query key + query options)
- achievements/[year]/[week] 상장 카드 상세 화면
- 리스트 아이템 탭 → 상세 네비게이션 + ListRow 리팩토링

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): CertificateBorder 공용 컴포넌트 분리

AchievementSummaryCard에서 CertificateBorder를 별도 파일로 추출하여
상세 페이지와 리스트 요약 카드에서 공유

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가 (#365)

* refactor(api): scheduler 내부 정리 및 WeeklyAchievement catch-up 추가

- ITimezoneStrategy 인터페이스 추출, 모든 strategy에 implements 적용
- handleHourlySweep → handleMinuteSweep 메서드명 정정
- pushEnabled 유저 없는 타임존의 WeeklyAchievement catch-up 로직 추가
- wrapAllTimezones 캐시 메서드 및 allTimezones 캐시 키 추가
- subtractMonths 날짜 유틸리티 추가
- jobs barrel export 추가

* refactor(api): WeeklyAchievement catch-up 중복 dayjs 계산 제거 및 테스트 데이터 보정

* feat(mobile): 반복 설정 UX 개선 및 시스템 글꼴 스케일 대응 (#363)

* feat(mobile): 반복 설정 날짜 선택 UX 개선

- 반복 기간 설정 라벨 변경 및 날짜 범위 표시 개선
- 선택된 반복 요일 요약 텍스트 추가
- 반복 모드에서 오늘 날짜 배경 하이라이트 비활성화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 피드 프로필 이름 최대 너비 제한 및 InfoIcon 텍스트 전환

- 긴 이름(최대 20자)이 레이아웃을 깨지 않도록 max-w + numberOfLines 적용
- InfoIcon SVG를 ⓘ 텍스트로 변경하여 폰트 스케일 대응

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 시스템 글꼴 크기 비례 스케일링 유틸 함수 추가

fontScaledSize(size, ratio) — PixelRatio.getFontScale() 기반으로
아이콘/버튼 크기를 시스템 글꼴에 비례하여 스케일링한다.
ratio 파라미터로 반영 비율 조절 가능 (기본 0.5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 아이콘/버튼 시스템 글꼴 스케일 적용 및 바텀시트 레이아웃 개선

- TodoFormContent: chips flex-wrap 레이아웃으로 변경, 버튼/아이콘 fontScaledSize 적용
- PickerHeader: CloseIcon fontScaledSize 적용
- TodoList: 카테고리 PlusIcon fontScaledSize 적용
- ProfileCard: CopyIcon fontScaledSize 적용
- KeyboardBottomSheet: 하단 패딩 여유 추가
- testing-guide: 유틸 함수 테스트 가이드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(mobile): fontScaledSize JSDoc 기본값 수정 (0.3 → 0.5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): fontScaledSize 호출을 인라인으로 변경

- PickerHeader의 HEADER_ICON_SIZE 상수 제거
- TodoFormContent의 scaledButtonSize/scaledIconSize/scaledMicIconSize 변수 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 테스트 설명에서 Given/When/Then 장황한 형식 제거

- testing-guide.md: it 설명은 간결하게 작성하도록 가이드 수정
- scale.test.ts: 7개 테스트 설명을 간결한 한국어로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(docs): 약관 업데이트

* feat(mobile): 24시간제 시간 형식 설정 및 앱 전체 적용 (#369)

* chore(mobile): 알림 설정 설명 문구를 ~해요 체로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 24시간제 설정을 앱 전체 시간 표시에 반영

- 알림 설정 화면에 24시간제 토글 추가
- 할일 목록, 친구 할일, AI 리포트 시간 표시에 timeFormat 반영
- iOS DateTimePicker locale 동적 전환 (en_GB/ko)
- formatTime, formatHour, formatReminderTime에 timeFormat 파라미터 추가
- formatTimeDisplay 유틸 함수 및 테스트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): TodoTimePickerContent에 Suspense boundary 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): formatTimeDisplay 기본값을 TWELVE_HOUR로 통일

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 주간 배지 공유 기능 추가 ⭐️  (#367)

* feat(mobile): 주간 배지 공유 기능 추가

- useShareView 훅으로 ViewShot 캡처 + expo-sharing 공유 로직 분리
- 배지 상세/요약 화면에 공유 버튼 추가
- badge_share_attempted 애널리틱스 이벤트 추가
- ShareIcon 아이콘 추가 및 fontScaledSize 적용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 공유 캡처 실패 시 에러 토스트 추가

- isAvailableAsync 체크를 캡처 전으로 이동
- 캡처 실패 시 에러 토스트 표시
- trackEvent를 shareCapture 전으로 이동

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(mobile): 배지 목록 빈 상태 UI를 상장 스타일로 개선

- 기본 Result 컴포넌트 대신 CertificateBorder 활용한 empty state
- 기록 영역에 Result 컴포넌트로 안내 표시
- badge_empty 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mobile): 콕 찌르기 쿨다운 에러 메시지 수정

- 오늘 할 일 기반이므로 시간 안내 대신 상태 안내로 변경

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#371)

* feat(api): AI 제안에 카테고리 추천 추가 및 분석 주기를 매일로 변경 (#370)

* feat(mobile): 카테고리 id를 기준으로 바로 선택할 수 있게 UX 변경

* refactor(api): Gemini 코드 리뷰 반영 — jobId 타임존 버그 수정

* feat(api): 투두 파싱 프롬프트에 요일 약어 및 월+요일 복합 규칙 추가

- DayAbbr 규칙: 한글 요일 약어 매핑(월=MON, 화=TUE, ...) 및 조합 패턴(월수금→MON+WED+FRI)
- Compound 확장: N월+요일약어→isRecurring:true, startDate=N월1일, endDate=N월말일
- "4월 월수금 출근" 같은 월+요일 복합 표현의 endDate가 해당 월 말일로 정확히 설정됨

* feat(mobile): v1.0.1 update

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장 (#376)

* feat(mobile): 캘린더 뷰 모드 선택 값 MMKV 저장

closes #375

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV persist 함수 네이밍 통일

- useState setter는 관례적 네이밍(setX) 유지
- MMKV 저장 포함 함수는 persistX로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): 캘린더 뷰 모드 읽기에서 타입 단언 제거

- VALID_VIEW_MODES 배열 + as CalendarViewMode 대신 직접 문자열 비교로 변경
- TypeScript 자동 narrowing 활용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(mobile): MMKV 저장소에 DIP 적용 및 preference 순수 함수 분리

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 김용민 <dydals3440@gmail.com>

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#378)

* fix(mobile): Android 마이페이지 하단 컨텐츠 탭 바 가림 수정 (#377)

* refactor(mobile): 탭 바 오버레이 패딩 상수 추출 (#377)

하드코딩된 paddingBottom: 120을 LAYOUT.tabBarOverlayPadding 상수로 분리

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 (#379)

* feat(mobile): analytics 이벤트 강화 및 친구 요청 lifecycle 추적 추가

- todo_created 이벤트에 source, is_recurring, has_scheduled_time, is_all_day, visibility 속성 추가
- 반복 할 일 생성(createRecurringTodo) 추적 추가
- category_created에 color 속성, category_updated 이벤트 신규 추가
- AI 파싱 source를 react-hook-form 상태로 관리 (props 없이)
- friend_request_accepted, friend_request_rejected 이벤트 추가
- onSuccess 내 trackEvent 호출 순서 통일 (invalidate → toast → trackEvent)

* fix(mobile): onSuccess 내 trackEvent 호출 순서 통일 (Gemini review)

카테고리 생성/수정 mutation에서 trackEvent를 invalidateQueries, toast 뒤로 이동하여
전체 코드베이스의 onSuccess 패턴(invalidate → toast → trackEvent)과 일관성 유지

* feat(mobile): 문의하기 기능 추가 (#381)

* feat(mobile): 문의하기 기능 추가 (#380)

* refactor(mobile): CONTENT_PLACEHOLDER를 멀티라인 템플릿 리터럴로 변환 (#380)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#383)

* refactor(mobile): 마이페이지/프로필 설정 UI 리팩토링 및 SettingNavigation 공통 컴포넌트 추출 (#382)

* refactor(mobile): SettingNavigation Compound Component 패턴 전환 (#382)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#385)

* fix(api): 카카오 프로필 이미지 미표시 수정 (#384)

* test(api): 카카오 토큰 검증 시 secure_resource 파라미터 검증 추가 (#384)

* refactor(api): secure_resource 파라미터를 URL 상수에 직접 포함 (#384)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386) (#387)

* feat(api,mobile): 리마인드 콕 찌르기 기능 추가 (#386)

* refactor(api): countTodayTodos 쿼리 가독성 개선 (#386)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#389)

* fix(mobile): 다크모드에서 Apple 아이콘 미표시 수정 (#388)

* refactor(mobile): ThemedAppleIcon 제거, dark: modifier로 통일 (#388)

* chore(mobile): v1.0.2 버전 업데이트

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#392)

* feat(mobile): 할일 액션 메뉴에서 카테고리 변경 기능 추가 (#391)

* fix(mobile): 카테고리 바텀시트 stale state 및 방어 코드 개선 (#391)

- CategorySelectBottomSheet: {isOpen && (...)} 패턴으로 재오픈 시 선택 상태 초기화
- SuggestionCategoryBottomSheet: ?? 0 제거, early return null로 방어 코드 개선

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#394)

* fix(mobile): 문의하기 화면 키보드 UX 개선 (#393)

* refactor(mobile): scrollTo 매직 넘버를 실제 콘텐츠 높이로 대체

onContentSizeChange로 콘텐츠 높이를 추적하여 scrollTo의
하드코딩된 9999 값을 제거하고 정확한 스크롤 위치를 사용

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가 (#395)

* feat(api,mobile): 친구 목록 드래그 앤 드롭 순서 변경 기능 추가

Follow 모델에 sortOrder 필드를 추가하고, 친구 목록에서 꾹 눌러
드래그로 순서를 변경할 수 있는 기능을 구현한다.

API:
- Prisma 스키마에 sortOrder 필드 및 인덱스 추가
- PATCH /follows/friends/:followId/reorder 엔드포인트 추가
- 상대 위치 기반 reorder + shift 알고리즘 구현
- 친구 수락 시 sortOrder 자동 할당 (maxSortOrder + 1)
- 기존 데이터 하위 호환 SQL 마이그레이션

Mobile:
- DraggableFlatList 기반 드래그 앤 드롭 UI
- 낙관적 업데이트 훅 (useDraggableFriendReorderList)
- reorderFriend 서비스 메서드 및 mutation options

* fix: 코드 리뷰 반영 및 친구 목록 레이아웃 수정

- reorder 시 followRequestNotFound → friendReorderTargetNotFound로 변경하여
  순서 변경 맥락에 맞는 에러 메시지 사용
- DraggableFlatList에 containerStyle flex:1 추가하여 전체 높이 채우도록 수정

* refactor: 코드 스타일 개선 및 analytics 이벤트 추가

- 단일 라인 if/return을 멀티 라인 브레이스로 변환 (가독성)
- API 로그 메시지 영문 → 한국어 전환 (로깅 가이드 준수)
- friend_reordered analytics 이벤트 추가

* chore(mobile): v1.0.3 버전 업데이트

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#399)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 문서 최신화 (#398)

* refactor(mobile): notification 모델 아키텍처 준수 리팩토링

- 서버 DTO 스키마를 model에서 제거, @aido/validators에서 import
- Policy에서 비-Policy 함수(isUnread, getExternalUrl) 제거
- 순수 함수 getCategoryLabel, getInternalRoute export
- *Result → *Response 네이밍 통일 (validators 기준)

* fix(api): ai 모듈 import 경로를 상대 경로로 수정

Gemini 코드 리뷰 반영 - @/modules/ 절대 경로를 상대 경로로 변경하여
api-conventions.md 규칙 준수

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#404)

* feat(api): 일일 완료 현황에 카테고리 색상 필드 추가 (#403)

* refactor(api): Gemini 코드 리뷰 반영 - colorMap 루프 간결화

* feat(api): AI 제안 패턴 유형 확장 - 순차/발전 패턴 감지 추가 (#406)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#408)

* feat(api): AI 리포트 프롬프트 주간/월간 분리 및 코칭 품질 개선 (#407)

* refactor(api): Gemini 코드 리뷰 반영 - buildReportPrompt 분기 구조 개선

type 기준으로 먼저 분기한 뒤 hasActivity를 확인하는 구조로 변경하여
중복 조건 제거 및 가독성 향상.

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#410)

* feat(api): 푸시알림 문구 랜덤 variants 시스템 + 온보딩/마일스톤/윈백 확장 (#409)

* refactor(api): Gemini 코드 리뷰 반영 - 일관성 개선 및 가드 강화 (#409)

* feat(mobile): 캘린더 날짜별 할일 완료 상태 표시 (#401)

* feat(mobile): RepeatIcon 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 캘린더 날짜별 할일 완료 상태 표시

- 전부 완료: 날짜 아래 파란 물고기 아이콘
- 미완료 할일 있음: 날짜 아래 작은 회색 점
- 할일 없음: 날짜만 표시
- 기존 +N 완료 개수 텍스트 제거

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 할일 바텀시트 칩/반복 분리 리팩토링

- 칩 영역 가로 스크롤 + 반복칩 추가
- 반복 설정 전용 피커 뷰 분리 (TodoRepeatPickerContent)
- 날짜 피커에서 반복 관련 코드 제거
- AiParseButton 컴포넌트로 마이크 로직 캡슐화
- 칩 스타일 아웃라인으로 변경

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): 키보드 열린 상태에서 칩 터치 안 되는 문제 수정

ScrollView의 keyboardShouldPersistTaps 기본값이 "never"라
키보드가 열려있을 때 칩 탭이 키보드 닫기에 소비되어 onPress가 실행되지 않던 문제 수정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 반복 설정 확인 버튼 유효성 검증 추가

- PickerHeader에 isConfirmDisabled prop 추가
- 요일 미선택/종료일 미선택/범위 내 요일 없음 시 확인 버튼 비활성화
- 자동 종료일(+7일) 기본값 제거, 명시적 선택 필요
- hasSelectedDayInRange 유틸 추가 및 테스트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(mobile): hasSelectedDayInRange O(n) 루프를 O(1) 수학 연산으로 개선

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): AI 기능 안내 툴팁 추가

- ⓘ 아이콘 탭 시 Popover로 AI 음성 파싱 사용법 안내
- 툴팁 로직을 AiFeatureTooltip 컴포넌트로 분리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 캘린더 날짜별 카테고리 색상 인디케이터 표시

- 클라이언트 모델/매퍼에 categoryColors 필드 추가
- 카테고리 1개: 단색 점, 2개+: 색상 바 (최대 3색)
- 인디케이터 높이를 물고기 아이콘과 동일하게 정렬

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(tooling): VSCode Biome 저장 시 자동 포맷/린트 설정 추가

  - editor.formatOnSave, organizeImports 추가
  - language-specific 블록 통합
  - deprecated biome.lspBin → biome.lsp.bin 변경

* fix(mobile): Android BottomTabs 경계선 제거 (#414)

* fix(mobile): Android 탭바 콘텐츠 경계 선 제거

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): 캘린더 카테고리 인디케이터 border-radius 조정

* refactor(mobile): 탭바 하단 패딩을 useBottomTabBarHeight로 동적 처리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: hijjoy <hijjoy@hijjoyui-MacBookPro.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 카테고리 관리를 마이 탭으로 이동 및 섹션 구조 UX 개편 (#415)

* feat(mobile): 카테고리 관리를 마이 탭으로 이동 및 섹션 구조 개편

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mobile): 플러스버튼 색상 수정

* feat(mobile): 마이탭 섹션 구조 UX 개선 및 UI 미세 조정

- 마이페이지 섹션을 활동/구독/설정/지원으로 재구성
- 카테고리 관리를 활동 섹션으로 이동, 구독을 설정보다 상위 배치
- PlusIcon Flex 래퍼 제거, SettingNavigation 항목 shade 조정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mobile): iOS NativeTabs에서 useBottomTabBarHeight crash 수정 (#418)

* chore(mobile): v1.0.4 변경

* fix(api): 리마인더 알림에 수정 전 투두 제목이 표시되는 버그 수정 (#421)

* fix(api): 리마인더 알림에 수정 전 투두 제목이 표시되는 버그 수정 (#420)

* test(api): 리마인더 제목 변경 테스트에 Math.random mock 적용 (#420)

* refactor(api): ReminderJobData에서 미사용 todoTitle 필드 제거 (#420)

* feat(api,validators): 관리자 알림에 action 필드 추가 (#423)

* feat(api,validators): 관리자 알림에 action 필드 추가 (#422)

* feat(api): action URL을 metadata.externalUrl로 전달하여 알림 목록 탭 시 외부 링크 지원

- AdminService broadcast/targeted에서 action.url이 있으면 metadata.externalUrl 자동 포함
- describe에 누락된 NONE 액션 타입 설명 추가 (Gemini review 반영)
- action + metadata 관련 단위 테스트 3건 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: hyewon <hijjoy@naver.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Matthew Kim <matthew@Matthewui-MacBookPro.local>
Co-authored-by: hijjoy <hijjoy@hijjoyui-MacBookPro.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: mobile 📱 모바일 - Expo 기반 모바일 앱 UI/UX 및 클라이언트 로직 관련 type: fix 🐛 버그 수정 - 사용자 이탈을 방지하고 시스템 안정성을 확보하는 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 문의하기 화면 키보드 UX 개선

1 participant