Skip to content

[TWI-130] 초대 코드 공유 및 딥링크 진입 처리#131

Open
chanho0908 wants to merge 15 commits intodevelopfrom
feat/#130-invitation
Open

[TWI-130] 초대 코드 공유 및 딥링크 진입 처리#131
chanho0908 wants to merge 15 commits intodevelopfrom
feat/#130-invitation

Conversation

@chanho0908
Copy link
Contributor

@chanho0908 chanho0908 commented Mar 22, 2026

이슈 번호

closes #130

작업내용

요구사항

1. 멘트

[키피럽 함께 시작해요]
함께 시작하고 일상  시너지를!

1. '키피럽' 설치해 주세요. [스토어 링크]
2. 회원가입을  주세요.
3. 아래 링크를 통해 연결하거나, 연결 코드를 메이트과 공유하세요!

[딥링크]

2. 액션

상태 동작
앱 미설치 웹 페이지 → Play Store 리다이렉트
미로그인 로그인 완료 후 초대 코드 자동 입력된 상태로 초대코드 입력 화면 이동
로그인 + 커플 연결 전 초대 코드 자동 입력된 상태로 초대코드 입력 화면 이동
로그인 + 커플 연결 완료 무시

배포는 우리 파이어베이스 계정에 Firebase Hosting 사용해서 했어 !!
image

초대 링크 공유하기

  • CoupleConnectScreen의 공유하기 버튼 클릭 시 Android 기본 공유 시트 호출
  • 공유 텍스트: 앱 소개 + Play Store URL + 초대 딥링크 포함

딥링크 처리 (App Links)

  • Firebase Hosting(keepiluv.web.app) 배포: 앱 미설치 시 Play Store 리다이렉트
  • AndroidManifest: twix:// custom scheme + https://keepiluv.web.app App Links intent-filter 등록
  • InviteLaunchDispatcher: custom scheme / App Links 두 가지 scheme 모두 처리

결과물

공유하기 딥링크 진입 (회원가입 X) 딥링크 진입 (회원가입 O)
공유 시트 호출 초대 코드 자동 입력 Play Store 이동
Image Image Image

리뷰어에게 추가로 요구하는 사항 (선택)

  • 이전에 이야기했던 스플래시 화면에서 온보딩이 완료되지 않았을 때 토큰 여부에 따라 메인 화면으로 이동하던 문제 수정하는거
    이번 작업하면서 필요해서 내가 구현해놨어 ! 현수가 구현한거랑 다르거나 추가로 설정해야하는 작업 있으면 말해줘 :)
  • 처음 구현해보는 기능이라 어떤 엣지케이스가 엣지 케이스가 있을지 잘 예측이 안 돼서 현수가 아는 케이스가 있다면 체크 부탁해 :)
  • 릴리즈 빌드에서 잘 돌아가는지 테스트 부탁해 !!

chanho0908 and others added 7 commits March 22, 2026 21:20
- InviteLaunchDispatcher: custom scheme(twix://) 및 App Links(https) 처리
- InviteLaunchEventSource: INVITE_WEB_HOST, PLAY_STORE_URL 상수 및 buildInviteDeepLink 추가
- core:share 모듈을 settings.gradle.kts, app/build.gradle.kts에 등록
- Koin shareModule 등록

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ShareInviteLink Intent/SideEffect 추가
- OnBoardingViewModel: ShareInviteLink 인텐트 처리
- CoupleConnectRoute: 공유하기 버튼 클릭 시 딥링크 + 스토어 URL 포함한 텍스트 공유
- strings.xml: 공유 메시지 문자열 상수화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- NavRoutes.InviteRoute: code 쿼리 파라미터 추가 및 createRoute() 함수 구현
- OnboardingNavGraph: InviteRoute navArgument 등록, initialInviteCode 전달
- InviteCodeRoute: initialInviteCode로 코드 자동 입력 처리
- CoupleConnectionRoute → InviteRoute 이동 시 createRoute() 사용으로 {code} 리터럴 버그 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SplashViewModel: 토큰 갱신 성공 후 온보딩 상태 체크 추가
- SplashSideEffect: NavigateToOnBoarding(status) 추가
- SplashRoute: navigateToOnBoarding 콜백 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MainActivity: InviteLaunchEventSource inject 및 onCreate/onNewIntent에서 dispatchFromIntent 호출
- AppNavHost: inviteLaunchEventSource koinInject 기본값 적용
- SplashNavGraph: 온보딩 미완료 + pendingInviteCode 존재 시 InviteRoute로 직접 이동
- LoginNavGraph: 로그인 완료 후 COUPLE_CONNECTION 상태 + pendingInviteCode 존재 시 InviteRoute로 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AndroidManifest: singleTask launchMode, custom scheme(twix://) 및 App Links(https://keepiluv.web.app) intent-filter 추가
- Firebase Hosting: 앱 미설치 시 Play Store 리다이렉트 페이지 배포
- .gitignore: assetlinks.json 민감 정보 제외

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chanho0908 chanho0908 linked an issue Mar 22, 2026 that may be closed by this pull request
2 tasks
@chanho0908 chanho0908 changed the title ✨ Feat: 초대 코드 공유 및 딥링크 진입 처리 초대 코드 공유 및 딥링크 진입 처리 Mar 22, 2026
@chanho0908 chanho0908 self-assigned this Mar 22, 2026
@chanho0908 chanho0908 added the Feature Extra attention is needed label Mar 22, 2026
coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

- `onboarding_invite_share_message` 문자열의 가독성 향상을 위해 타이틀 및 연결 코드 부분에 줄바꿈(`\n`) 반영
@chanho0908 chanho0908 changed the title 초대 코드 공유 및 딥링크 진입 처리 [TWI-130]초대 코드 공유 및 딥링크 진입 처리 Mar 22, 2026
@chanho0908 chanho0908 changed the title [TWI-130]초대 코드 공유 및 딥링크 진입 처리 [TWI-130] 초대 코드 공유 및 딥링크 진입 처리 Mar 22, 2026
chanho0908 and others added 2 commits March 22, 2026 22:40
불필요한 중간 화면이 백스택에 쌓이는 문제 수정
OnboardingGraph로 먼저 이동 후 destination으로 이동하는 2단계 패턴을
destination으로 직접 이동하는 단일 호출로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
서버 응답 G4000(400) 코드에 대한 처리 추가
- strings.xml: toast_self_invite_code 문자열 추가
- OnBoardingViewModel: SELF_INVITE_CODE_ERROR_CODE 상수 추가 및 handleCoupleConnectException에 G4000 케이스 처리
- 기존 else 미처리 케이스도 일반 에러 토스트로 정리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt (1)

52-53: ⚠️ Potential issue | 🟠 Major

초대 코드 로딩 전 공유 시 빈 코드가 전송될 수 있습니다.

초기 로딩이 끝나기 전에 공유 액션이 들어오면 빈 문자열이 그대로 공유되어 링크 품질이 깨집니다. 공유 전에 isBlank()를 검사하고, 비어 있으면 토스트 후 재조회하도록 가드해 주세요.

가드 로직 제안
-            OnBoardingIntent.ShareInviteLink ->
-                emitSideEffect(OnBoardingSideEffect.InviteCode.ShareInviteLink(currentState.inviteCode.myInviteCode))
+            OnBoardingIntent.ShareInviteLink -> {
+                val inviteCode = currentState.inviteCode.myInviteCode
+                if (inviteCode.isBlank()) {
+                    showToast(R.string.onboarding_couple_fetch_my_invite_code_fail, ToastType.ERROR)
+                    fetchMyInviteCode()
+                    return
+                }
+                emitSideEffect(OnBoardingSideEffect.InviteCode.ShareInviteLink(inviteCode))
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt`
around lines 52 - 53, 현재 OnBoardingViewModel에서 OnBoardingIntent.ShareInviteLink
처리 시 currentState.inviteCode.myInviteCode를 바로 공유해 빈 문자열이 전송될 수 있으니,
ShareInviteLink 분기에서 inviteCode = currentState.inviteCode.myInviteCode를 받아
isBlank()로 검사하고 비어있으면 emitSideEffect로 토스트(예:
OnBoardingSideEffect.ShowToast("초대코드 로딩중입니다"))를 발행한 뒤 재조회용 인텐트(예:
dispatch(OnBoardingIntent.LoadInviteCode) 또는 loadInviteCode() 호출)를 트리거해 중복 전송을
막고, 비어있지 않을 때만
emitSideEffect(OnBoardingSideEffect.InviteCode.ShareInviteLink(inviteCode))를
호출하도록 변경하세요.
🧹 Nitpick comments (1)
feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt (1)

106-117: 404 케이스의 error.message 문자열 분기는 취약합니다.

메시지 문구가 서버/번역 정책으로 바뀌면 분기가 바로 깨질 수 있습니다. 404도 백엔드와 에러 code 계약이 가능하다면 code 기반 분기로 전환하는 쪽이 더 안전한데, 이 방향으로 맞춰보는 건 어떨까요?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt`
around lines 106 - 117, The 404 branch in the when block currently inspects
error.message (lines handling AppError.Http && error.status == 404) which is
fragile; change it to branch on a stable error code property (e.g., use
AppError.Http.code or add one if missing) instead of INVALID_INVITE_CODE_MESSAGE
/ ALREADY_USED_INVITE_CODE_MESSAGE string constants, updating the conditional
inside the AppError.Http && error.status == 404 case to check error.code values
and then call showToast(...) or
emitSideEffect(OnBoardingSideEffect.InviteCode.NavigateToNext) accordingly; keep
a safe fallback to the existing message-based checks only when error.code is
null to preserve behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/design-system/src/main/res/values/strings.xml`:
- Line 191: Fix the typo in the onboarding invite share message string resource:
update the value of the string named "onboarding_invite_share_message" to
replace "메이트과" with the correct particle "메이트와" so the displayed share text
reads correctly for users.

In `@feature/splash/src/main/java/com/twix/splash/navigation/SplashNavGraph.kt`:
- Around line 47-53: The current branch choosing logic uses only pendingCode !=
null which allows empty strings to be treated as valid; update the check around
inviteLaunchEventSource.pendingInviteCode.value so you treat blank/empty the
same as null (use isNullOrBlank()), call
inviteLaunchEventSource.consumePendingInviteCode() when a pending value exists,
and only call NavRoutes.InviteRoute.createRoute(pendingCode) when
pendingCode.isNullOrBlank() is false; otherwise fall back to
NavRoutes.CoupleConnectionRoute.route.

---

Duplicate comments:
In `@feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt`:
- Around line 52-53: 현재 OnBoardingViewModel에서 OnBoardingIntent.ShareInviteLink
처리 시 currentState.inviteCode.myInviteCode를 바로 공유해 빈 문자열이 전송될 수 있으니,
ShareInviteLink 분기에서 inviteCode = currentState.inviteCode.myInviteCode를 받아
isBlank()로 검사하고 비어있으면 emitSideEffect로 토스트(예:
OnBoardingSideEffect.ShowToast("초대코드 로딩중입니다"))를 발행한 뒤 재조회용 인텐트(예:
dispatch(OnBoardingIntent.LoadInviteCode) 또는 loadInviteCode() 호출)를 트리거해 중복 전송을
막고, 비어있지 않을 때만
emitSideEffect(OnBoardingSideEffect.InviteCode.ShareInviteLink(inviteCode))를
호출하도록 변경하세요.

---

Nitpick comments:
In `@feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt`:
- Around line 106-117: The 404 branch in the when block currently inspects
error.message (lines handling AppError.Http && error.status == 404) which is
fragile; change it to branch on a stable error code property (e.g., use
AppError.Http.code or add one if missing) instead of INVALID_INVITE_CODE_MESSAGE
/ ALREADY_USED_INVITE_CODE_MESSAGE string constants, updating the conditional
inside the AppError.Http && error.status == 404 case to check error.code values
and then call showToast(...) or
emitSideEffect(OnBoardingSideEffect.InviteCode.NavigateToNext) accordingly; keep
a safe fallback to the existing message-based checks only when error.code is
null to preserve behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: cf08e12c-44fe-4a7a-812d-a881f18bb6db

📥 Commits

Reviewing files that changed from the base of the PR and between 60b79f8 and 88d4055.

📒 Files selected for processing (3)
  • core/design-system/src/main/res/values/strings.xml
  • feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt
  • feature/splash/src/main/java/com/twix/splash/navigation/SplashNavGraph.kt

InviteRoute에서도 pendingInviteCode를 collectAsStateWithLifecycle로 구독하여
딥링크 수신 시 WriteInviteCode intent로 코드 자동 입력 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Keepiluv Keepiluv deleted a comment from coderabbitai bot Mar 22, 2026
@Keepiluv Keepiluv deleted a comment from coderabbitai bot Mar 22, 2026
@chanho0908 chanho0908 requested a review from dogmania March 23, 2026 03:50
@chanho0908 chanho0908 requested review from dogmania and removed request for dogmania March 23, 2026 03:51
coderabbitai[bot]

This comment was marked as resolved.

@chanho0908
Copy link
Contributor Author

@coderabbitai review

@Keepiluv Keepiluv deleted a comment from coderabbitai bot Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

초대장 보내기 기능 개발

1 participant