Merge feat/107 onto develop - #148
Merged
Merged
Conversation
settings.gradle.kts에 신규 모듈을 등록하고 todakun.feature 플러그인을 적용한다. 네임스페이스는 com.kikidan.sajucontents로 정의한다. # Conflicts: # settings.gradle.kts
목적 5종·후보 날짜 검증을 포함한 CreateDayFortunesUseCase와 DayFortune/FortuneCategory 도메인 모델, Repository 인터페이스를 추가한다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
여러 날짜의 운세를 병렬로 조회하고 결과를 관리하는 기능을 추가한다. - `GetDayFortuneUseCase` 및 리포지토리 메서드 추가 - Orbit MVI 기반의 `DateFortuneResultViewModel` 구현 - `loadResults` 호출 시 `async`/`awaitAll`을 사용하여 여러 ID의 운세를 병렬로 조회하되, 요청한 순서대로 결과를 유지하도록 처리 - 운세 조회 실패 시 `ShowError` 사이드 이펙트 노출 및 탭 전환 기능 구현 - ViewModel 및 UseCase에 대한 단위 테스트 추가
RemoteDayFortuneDataSource 인터페이스와 runCatchingCancellable 기반 DayFortuneRepositoryImpl을 추가하고 Hilt 바인딩을 연결한다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> # Conflicts: # core/data/src/main/java/com/kikidan/data/di/RepositoryModule.kt
RemoteDayFortuneDataSource 인터페이스에 getDayFortune을 추가하고, Repository에서 runCatchingCancellable을 통해 결과를 Result<DayFortune>으로 래핑하여 반환한다. FakeDataSource와 Repository 단위 테스트를 추가하여 정상 반환 및 예외 처리 동작을 검증한다.
사용하지 않는 운세 공유 다이얼로그, 카카오톡 공유 및 URL 복사 관련 문자열 리소스를 삭제한다. `date_fortune_share_` 접두어를 가진 리소스들을 정리하여 디자인 시스템 모듈 내의 문자열을 관리한다.
POST /api/v1/day-fortunes 연동을 위한 Request/Response DTO와 Ktor 기반 RemoteDayFortuneDataSourceImpl을 추가한다. 서버가 모르는 enum 값이 와도 죽지 않도록 매핑한다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
api/v1/day-fortunes/{id} 엔드포인트로 GET 요청을 보내 특정 ID의 운세 정보를 조회한다.
bodyNotNull()을 사용하여 응답 데이터가 누락된 경우 예외를 발생시키며,
정상 응답 시 날짜(LocalDate)와 카테고리 정보가 도메인 모델로 올바르게 매핑되는지 검증하는 테스트를 추가한다.
RemoteDataSourceModule 내 데이터 소스 관련 import 문을 알파벳 순으로 정렬한다.
여러 날짜의 운세를 병렬로 조회하고 결과를 관리하는 기능을 추가한다. - `GetDayFortuneUseCase` 및 리포지토리 메서드 추가 - Orbit MVI 기반의 `DateFortuneResultViewModel` 구현 - `loadResults` 호출 시 `async`/`awaitAll`을 사용하여 여러 ID의 운세를 병렬로 조회하되, 요청한 순서대로 결과를 유지하도록 처리 - 운세 조회 실패 시 `ShowError` 사이드 이펙트 노출 및 탭 전환 기능 구현 - ViewModel 및 UseCase에 대한 단위 테스트 추가
DateFortuneContract(State/SideEffect)와 Orbit 기반 DateFortuneViewModel을 추가한다. 성별 선택값은 상태에만 보관하고 UseCase로 전달하지 않는다(백엔드 필드 부재, 블로커 B-2). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Orbit MVI 패턴을 적용하여 택일 기능의 상태 관리와 화면 이동 로직을 구현한다. 서버 API 사양에 맞춰 성별 필드는 입력받되 제출 가능 여부(canSubmit) 판단에서는 제외한다. 입력 화면(InputRoute)과 결과 화면(ResultRoute)을 추가하여 ViewModel과 Composable을 연결한다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
- `NavigateToResult` SideEffect에 결과 ID 리스트를 전달하여 결과 화면 전환 시 데이터를 식별할 수 있도록 한다. - `ShowToast`, `ShowError` SideEffect에서 리소스 ID 의존성을 제거하고 `data object`로 변경하여 UI 레이어와의 결합도를 낮춘다. - ViewModel의 메서드명을 `onPurposeSelect` 대신 `selectPurpose`, `toggleDate`, `submit` 등 행위 중심의 명칭으로 변경한다. - `app` 모듈의 의존성에 `saju-contents` 피처 모듈을 추가한다.
제출 성공 시 생성된 결과 데이터를 UI 상태에 저장하는 대신, 결과 ID 목록을 `NavigateToResult` 사이드 이펙트로 전달하도록 변경한다. 이에 따라 `DateFortuneState`에서 `results`와 `selectedResultIndex` 필드를 삭제하고, 불필요해진 `selectTabResult` 함수와 관련 테스트 코드를 제거한다.
불러온 일진 결과를 점수(score) 내림차순으로 정렬하고, 상위 3개 항목만 결과로 사용한다. 점수가 같을 경우 기존의 순서가 유지되며, 정렬된 결과의 첫 번째 항목이 선택되도록 selectedResultIndex를 0으로 설정한다.
공유 팝업의 표시 상태(`isShareDialogVisible`)를 관리하고, 공유 실패(`ShowShareError`)나 URL 복사 완료(`ShowUrlCopied`) 시 팝업을 닫으며 SideEffect를 발생시킨다. 새로 추가된 로직에 대한 ViewModel 단위 테스트를 작성한다.
FakeDayFortuneRepository에 getDayFortune 구현을 추가하여 ID 기반의 결과 반환 시뮬레이션을 지원한다. DateFortuneSideEffect에서 메시지 리소스 ID 인자가 제거됨에 따라 ViewModelTest의 사이드 이펙트 검증 로직을 수정한다.
`kakao-share` SDK를 추가하고 운세 결과를 외부로 공유할 수 있는 다이얼로그를 구현한다. 카카오톡 앱 공유를 우선 시도하며, 앱 미설치 시 웹 공유(`WebSharerClient`)로 폴백한다. URL 복사 시 서비스 딥링크를 클립보드에 저장하는 기능을 함께 제공한다.
AndroidManifest에 카카오 공유 딥링크와 Android App-Link 처리를 위한 intent-filter를 추가한다. 환경별(debug/release) 호스트 및 키 설정을 위해 manifestPlaceholders와 BuildConfig를 활용하며, 공유 다이얼로그에서 카카오 SDK의 TextTemplate에 실행 파라미터를 포함하도록 수정한다. * AndroidManifest에 `kakaoLink` 및 `day-fortune` 경로에 대한 intent-filter 추가 * build.gradle에서 `local.properties`를 통해 환경별 `APP_LINK_HOST` 및 `KAKAO_APP_KEY` 주입 * `DateFortuneShareDialog`에서 하드코딩된 URL을 제거하고 `BuildConfig` 기반의 동적 링크 생성 * 카카오 공유 시 웹/모바일 웹 URL 및 앱 실행 파라미터(`id`) 설정 추가
CI 환경에서 API 키나 호스트 설정 등 `local.properties`에 정의된 값이 없을 경우 빌드가 중단되는 문제를 방지한다. `error()` 호출 대신 빈 문자열을 기본값으로 할당하도록 수정하고, 변수명을 `props`에서 `localProperty`로 변경하여 의미를 명확히 한다.
TODO 키워드와 설명 사이에 공백이 누락된 부분을 수정하여 일관성을 맞춘다. app 모듈과 feature/saju-contents 모듈의 빌드 스크립트를 대상으로 한다.
일일 운세뿐만 아니라 연간 운세 등 다양한 결과 화면에서 재사용할 수 있도록 `DateFortuneShareDialog`를 `FortuneShareDialog`로 이름을 변경하고 일반화한다. 도메인별로 달라지는 공유 URL 생성 로직을 제거하고 호출부에서 `shareUrl`을 파라미터로 전달받도록 수정했으며, 관련 리소스 ID에서도 `date_` 접두어를 제거했다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
일간/연간 운세 등 여러 결과 화면에서 공통으로 사용할 수 있도록 `date_fortune_` 접두어를 `fortune_`로 변경한다. 공유 다이얼로그와 운세 카테고리 라벨 리소스가 포함된다.
`/day-fortune` 외에 `/year-fortune`, `/compatibility` 경로를 추가하여 지원 범위를 넓힌다. `pathPrefix` 대신 `path`를 사용해 매칭 경로를 명확히 하고, `scheme`와 `host`를 개별 태그로 분리하여 선언한다.
Orbit MVI 패턴을 적용하여 택일 기능의 상태 관리와 화면 이동 로직을 구현한다. 서버 API 사양에 맞춰 성별 필드는 입력받되 제출 가능 여부(canSubmit) 판단에서는 제외한다. 입력 화면(InputRoute)과 결과 화면(ResultRoute)을 추가하여 ViewModel과 Composable을 연결한다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs # Conflicts: # feature/saju-contents/src/main/java/com/kikidan/sajucontents/DateFortuneViewModel.kt # feature/saju-contents/src/main/java/com/kikidan/sajucontents/model/DateFortuneSideEffect.kt # feature/saju-contents/src/test/java/com/kikidan/sajucontents/DateFortuneViewModelTest.kt
목적 선택, 성별 선택, 후보 날짜 캘린더 바텀시트를 포함한 입력 화면과 카테고리별 별점을 동적으로 렌더링하는 결과 화면을 추가한다. TodakunChip의 선택/비선택 스타일 불일치 버그를 함께 수정한다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> # Conflicts:
dayfortune 패키지 아래에 혼재되어 있던 화면과 컴포넌트들을 각각 screen 및 component 패키지로 분리하여 정리한다. Route를 제외한 상세 Screen 컴포저블은 internal로 가시성을 제한하고, 유닛 테스트 파일도 변경된 구조에 맞춰 이동한다.
서버 API 명세에 포함되지 않는 성별 선택 기능을 삭제하고 관련 상태를 정리한다. 상단 프로그레스 바를 서브 헤더로 교체하며, 하단 CTA 버튼을 스크롤 영역에서 분리하여 화면 하단에 고정(Sticky)되도록 수정한다. 토스트 메시지 노출 로직을 Screen에서 Route로 이동하여 책임을 분리하고, `TodakunSubHeader`의 내부 패딩을 제거하여 레이아웃 유연성을 확보한다.
`kizitonwose-calendar` 라이브러리를 도입하여 `MultiSelectCalendar`를 `VerticalCalendar` 기반으로 리팩터링한다. 기존 수동 구현 방식보다 스크롤 및 상태 관리가 효율적이며, 디자인 가이드에 맞춰 선택 상태 및 오늘 날짜 표시 UI를 수정한다. - **UI 개선**: `SelectedDateChipRow`의 칩 디자인을 수정하고, 바텀시트 우측 상단에 닫기 버튼을 추가한다. - **기능 추가**: `DateFortuneInputScreen`의 선택 필드에 초기화(`onClear`) 동작을 연결한다. - **안정성**: 달력 상태 계산 시 `ImmutableList`를 사용하도록 변경하고 관련 테스트 코드를 업데이트한다.
ViewModel의 이벤트 처리 함수명을 액션 중심으로 변경(onXXX -> XXX)하고, 커스텀 Toast 로직을 SnackbarHostState 사용으로 대체합니다. - 결과 화면 이동 시 결과 ID 목록(`List<String>`)을 전달하도록 수정 - SelectedDateChipRow의 clickable 수식어 위치를 조정하여 터치 영역 개선 - 불필요한 LaunchedEffect 및 로컬 상태를 제거하고 SideEffect를 통해 Snackbar 표시 - 전체적인 코드 스타일 및 trailing comma 정리
feature 모듈 내에서만 사용되는 UI 컴포넌트들의 가시성을 `internal`로 제한하고, 재사용성이 낮은 소규모 컴포넌트들을 사용처로 통합하여 파일 구조를 단순화한다. - `SelectedDateChipRow`, `ResultDateTabRow`, `MultiSelectCalendar` 등의 가시성을 `internal`로 변경 - `FortuneCategoryStars`, `CategoryStarItem`을 `FortuneScoreCard` 내부로 통합 - `PurposeChipGroup`을 `DateFortuneInputScreen` 내부로 통합 - 택일 운세 관련 문자열 리소스를 `core:designsystem` 모듈로 이동 및 통합 관리 - 미사용 `GenderSelector` 컴포넌트 삭제 - `DateFortuneSideEffect`의 토스트 및 에러 메시지 전달 방식 수정에 따른 테스트 코드 업데이트
일관된 코드 스타일 유지를 위해 `com.kikidan.designsystem.R` 임포트 위치를 정렬한다.
디자인 시안에 맞춰 배경 이미지, 커스텀 게이지, 별점 표시 등을 적용하여 UI를 개선했다. - Canvas를 사용한 점수 게이지 구현 및 별점 표시 방식 변경(최대 3개 고정) - 제목 텍스트 내 특정 문구 하이라이트(AnnotatedString) 및 하단 버튼 툴팁 추가 - 진입 시 ID 기반 결과 로드 로직 및 에러 처리(Snackbar) 사이드 이펙트 구현 - 공유/내보내기 전용 아이콘 적용 및 시스템 바 패딩(systemBarsPadding) 대응
공유 버튼 클릭 시 ViewModel의 공유 로직을 호출하도록 연결한다. 공유 실패(ShowShareError) 및 URL 복사 완료(ShowUrlCopied) SideEffect 발생 시 스낵바를 표시하는 핸들러를 추가한다. Co-Authored-By: Claude 3.5 Sonnet <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
`CalendarContract`와 `ACTION_INSERT` 인텐트를 사용하여 선택된 운세 결과를 시스템 캘린더에 등록하는 기능을 추가한다. 기기에 캘린더 앱이 설치되어 있지 않은 경우 `ActivityNotFoundException`을 캐치하여 에러 스낵바를 노출하며, 운세 날짜를 `allDay` 이벤트로 변환하여 전달한다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
`state.isShareDialogVisible` 상태에 따라 `DateFortuneShareDialog`를 노출하도록 구현한다. 다이얼로그의 닫기, 카카오톡 공유 실패 처리, URL 복사 완료 알림 등의 이벤트를 ViewModel과 연결한다.
연도 선택 및 생성 로직(YearFortuneViewModel)과 결과 조회 로직(YearFortuneResultViewModel)을 분리한다. 공유 딥링크 등을 통해 결과 화면으로 직접 진입할 수 있도록, 결과 화면은 연도가 아닌 고유 ID를 기반으로 데이터를 로드하도록 변경한다. - 데이터 레이어에 ID 기반 조회(GET)와 연도 기반 생성(POST) 기능을 분리하여 추가한다. - NavigateToResult 사이드 이펙트의 인자를 year(Int)에서 id(String)로 변경한다. - YearFortuneResultScreen의 UI 구조를 개선하고 시스템바 및 내비게이션바 패딩을 적용한다.
`FortuneCategoryStar`를 `dayfortune` 패키지에서 `fortune` 패키지로 이동하고, 관련 리소스 ID의 `date_` 접두어를 제거하여 다른 운세 서비스에서도 재사용할 수 있도록 개선한다. 공유 다이얼로그에 `shareUrl` 파라미터를 추가하고 `BuildConfig`의 호스트 정보를 기반으로 URL을 생성하도록 변경하며, `FortuneScoreCard`는 점수 라벨을 외부에서 주입받을 수 있도록 수정한다.
운세 카테고리와 그에 해당하는 별점(star) 정보를 담는 데이터 클래스를 정의한다.
배경 이미지에 hazeSource를 설정하고 결과 카드들에 hazeEffect를 적용하여 유리 효과(Glassmorphism)를 구현한다. 블러 반경은 20.dp로 설정했으며, 이를 위해 Haze 라이브러리 의존성을 추가했다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
BuildConfig.APP_LINK_HOST에 스킴이 포함됨에 따라 shareUrlFor 함수에서 중복으로 붙던 "https://" 문자열을 삭제한다.
Fortune 도메인 모델·Repository·GetYearFortuneUseCase, Remote DataSource/DTO, YearFortuneViewModel과 연도 선택/결과 화면 Compose UI를 추가한다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> # Conflicts: # core/data-remote/src/main/java/com/kikidan/data_remote/di/RemoteDataSourceModule.kt
에러 발생 시 UI State의 error 필드를 업데이트하는 대신 ShowError SideEffect를 발생시킨다. 이를 통해 Route 내부의 불필요한 스낵바 상태 관리 및 타이머 로직을 제거하고, 외부에서 주입받은 SnackbarHostState를 사용하도록 개선한다. 또한 YearSelectionScreen의 레이아웃을 Column과 Row 조합 대신 LazyVerticalGrid로 변경하여 그리드 구현을 최적화하고 코드를 단순화한다. - 에러 처리를 위한 `YearFortuneSideEffect.ShowError` 추가 - ViewModel에서 `error` 상태 제거 및 `onErrorDismiss` 삭제 - `LazyVerticalGrid` 적용 및 시스템 바 패딩 설정 추가
연도 선택 및 생성 로직(YearFortuneViewModel)과 결과 조회 로직(YearFortuneResultViewModel)을 분리한다. 공유 딥링크 등을 통해 결과 화면으로 직접 진입할 수 있도록, 결과 화면은 연도가 아닌 고유 ID를 기반으로 데이터를 로드하도록 변경한다. - 데이터 레이어에 ID 기반 조회(GET)와 연도 기반 생성(POST) 기능을 분리하여 추가한다. - NavigateToResult 사이드 이펙트의 인자를 year(Int)에서 id(String)로 변경한다. - YearFortuneResultScreen의 UI 구조를 개선하고 시스템바 및 내비게이션바 패딩을 적용한다.
특정 피처에 종속되었던 공유 시트와 점수 UI를 `designsystem`의 공용 컴포넌트로 교체하고, 공유 상태에 따른 사이드 이펙트 처리를 추가한다. - `ShareBottomSheet`를 제거하고 공용 `FortuneShareDialog`를 적용한다. - 로컬에 정의했던 별점 및 점수 UI를 `FortuneScoreCard` 공용 컴포넌트로 대체한다. - 카카오톡 공유 실패 및 URL 복사 완료 시 스낵바를 띄우도록 `SideEffect`와 `Route` 로직을 추가한다. - `YearFortuneResultViewModel`의 상태 및 메서드 이름을 시트(Sheet)에서 다이얼로그(Dialog) 기반으로 변경한다. - 결과 화면에 배경 이미지를 추가하고, 공유 URL 생성 시 `BuildConfig.APP_LINK_HOST`를 사용하도록 수정한다. - 여러 화면에서 공통으로 사용하는 운세 카테고리 및 공유 관련 리소스 문자열을 `designsystem`으로 이동하고 이름을 일반화(`fortune_*`)한다.
배경 이미지에 hazeSource를 설정하고 결과 카드들에 hazeEffect를 적용하여 유리 효과(Glassmorphism)를 구현한다. 블러 반경은 20.dp로 설정했으며, 이를 위해 Haze 라이브러리 의존성을 추가했다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01299PBN5qzgPtdnPH2e25rs
화면의 역할을 더 명확하게 나타내기 위해 `YearSelectionScreen`을 `YearFortuneInputScreen`으로 변경하고 불필요한 import를 정리한다. `YearFortuneResultScreen`에서 공유 URL 생성 시 하드코딩된 `https://` 접두사를 제거한다.
`YearFortuneResultScreen`의 배경색을 기존 `TodakunColor.black`에서 디자인 요구사항에 맞춘 특정 다크 톤 색상(`0xFF00010B`)으로 변경한다.
사주 데이터를 기반으로 상대방과의 궁합을 확인하고 분석 결과를 보여주는 기능을 추가합니다. 파트너 정보를 입력하거나 기존 목록에서 선택하는 화면과 궁합 점수, 사주 구조, 오행 분포 등을 시각적으로 제공하는 결과 화면을 구현합니다. - `Compatibility` 도메인 모델 정의 및 관련 Repository, UseCase(`CreateCompatibility`, `GetCompatibility`) 레이어 추가 - 파트너 선택, 정보 로드 및 궁합 확인 로직을 담당하는 `CompatibilityInputViewModel` 및 화면 구현 - 궁합 점수 게이지, 사주 구조 비교, 오행 바 차트를 포함한 `CompatibilityResultScreen` 및 UI 컴포넌트 구현 - 파트너의 사주 명반 상세 조회를 위한 `GetPartnerMansaeryeokDetailUseCase` 및 데이터 소스 연동 - 사주 용어 표준화에 따른 `TwelveUnseong`(MOKYOK) 및 `TwelveSinsal`(YEONGMASAL) 명칭 수정 - `WheelPickerBottomSheet` 공개화 및 `TodakunWheelPicker` 버튼 라벨 커스터마이징 등 디자인 시스템 구성 요소 개선 - 신규 기능에 대한 ViewModel 단위 테스트 및 테스트용 Fake 객체 추가
[Feat]: 상대방 궁합 조회 기능 및 결과 화면 구현
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`UserRepository` 인터페이스의 변경 사항을 반영하여 테스트용 페이크 객체인 `FakeUserRepository`에 회원 탈퇴(`withdraw`) 메서드를 추가한다. - `FakeUserRepository`에 `withdraw` 메서드 오버라이드 및 `TODO` 구현 추가 - `WithdrawalReason` 도메인 모델 import 추가
테스트 코드의 일관성을 유지하기 위해 `FakeUserRepository` 내 메서드 형식을 수정하고 후행 쉼표(trailing comma)를 추가하여 가독성을 개선한다. - `withdraw` 메서드 매개변수에 후행 쉼표 추가 - 메서드 정의 간 빈 줄 추가 등 코드 스타일 정리
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
관련 이슈
작업 내용
변경사항 / 상세
중점 리뷰사항
스크린샷 (선택)