Skip to content

feat: 앱 링크(Universal/App Link) 및 warm start 딥링크 지원#329

Merged
iOdiO89 merged 23 commits into
devfrom
feat/283-app-link
Jul 11, 2026
Merged

feat: 앱 링크(Universal/App Link) 및 warm start 딥링크 지원#329
iOdiO89 merged 23 commits into
devfrom
feat/283-app-link

Conversation

@iOdiO89

@iOdiO89 iOdiO89 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

작업 요약

  • 안드로이드 app Link 연동
  • iOS universal link & smark banner 연동

작업 내용

앱 링크 (Universal Link / App Link)

웹 URL(piki.day, staging.piki.day, dev.piki.day)을 탭하면 네이티브 앱이 열리도록 iOS/Android 앱 링크를 설정하고, 앱 내 WebView에서 해당 경로로 이동하는 딥링크 라우팅을 구현했습니다.

iOS Universal Link

  • apple-app-site-association 추가 — /auth/callback/*, /api/*는 앱 가로채기 제외 (OAuth·API 흐름 보호)
  • app.jsonassociatedDomains 설정 (applinks:piki.day 등)
  • +native-intent.ts에서 https URL → /?web=<경로> 형태로 정규화

Android App Link

  • assetlinks.json 추가 (패키지 day.no30s.piki)
  • app.jsonintentFilters 설정 (autoVerify: true)
  • Android는 AASA exclude가 없어 webDeepLink.ts에서 /auth/callback, /api 경로를 클라이언트 측 차단

iOS Smart Banner

  • 토너먼트 참여 페이지(/tournament/join/[id])에 generateMetadataitunes.appArgument 설정
  • Safari에서 "앱에서 열기" 배너 탭 시 해당 경로로 앱 진입 가능

Warm start 딥링크 (핵심 UX 개선)

  • cold start: WebView URI를 통째로 교체 (기존 방식, 스플래시가 로딩 처리)
  • warm start: 이미 로드된 WebView에 APP_REQ_NAVIGATE 브릿지 메시지로 SPA 전환 (router.push)
    • 문서 전체 리로드 없이 부드러운 페이지 전환
    • 전환 중 NavigationOverlay 로딩 오버레이 노출
    • 5초 타임아웃 안전장치 포함
  • @piki/coreAPP_REQ_NAVIGATE 메시지 타입 추가

스크린샷

  • cold start (앱 quit 상태에서 접속 → 로딩 완료 전까지 스플래시 유지. 화면 준비되면 타겟 페이지로 넘어감)
ScreenRecording_07-12-2026.6-55-38_1.mov
  • warm start (앱 background 상태에서 접속 → 로딩 완료 전까지 현재 접속 중인 화면에 로딩 오버레이 표시. 화면 준비되면 타겟 페이지로 넘어감)
ScreenRecording_07-12-2026.6-56-09_1.mov

연관 이슈

closes #283

Summary by CodeRabbit

  • 새 기능
    • iOS Universal Links 및 Android App Links 구성을 추가하고, HTTPS 딥링크를 앱에서 인식하도록 개선했습니다.
    • 토너먼트 초대 링크에서 iOS Smart Banner용 메타데이터를 동적으로 생성합니다.
    • 앱 실행 중(워ーム 스타트) 딥링크 전환 시 전체 화면 로딩 오버레이를 표시합니다.
  • 개선
    • Universal Link/Smart App Banner에서 전달된 전체 URL 기반으로 웹 경로를 매끄럽게 전환합니다.
    • 내부 경로만 안전하게 이동하도록 검증해 오작동과 외부 리다이렉트를 방지합니다.
  • 문서/설정
    • Apple/Android용 .well-known 연결 설정과 헤더 응답을 보강했습니다.

iOdiO89 and others added 20 commits June 29, 2026 16:40
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- AASA 파일 추가 (콜백/api 경로는 exclude)
- iOS associatedDomains 설정
- Universal Link/Smart Banner app-argument의 https URL을 WebView 경로로 라우팅
* chore: PR 봇을 Slack 에서 Discord 로 이관

slack-pr-bot.yml 제거 + discord-pr-bot.yml 추가 (서버 PIKI-Server 검증본 기반).
리뷰어 멘션(initial_reviewers + requested_reviewers)·연관 이슈(close #N) 로직 동일.

클라 slack 커밋 이력(#14·#17·#18·#20)을 추적해 서버와 다른 클라 특화를 반영:
- 트리거·부모 메시지 조건: ready_for_review → reopened (#17, 기존 slack 봇과 동일).
- 요약 파싱 섹션명: Task → 작업 요약 (클라 PR 템플릿이 '## 작업 요약'). 클라 slack 은 두 요약 함수의
  섹션명이 '작업 내용'/'작업 요약' 으로 불일치(#20 이 한쪽만 수정)해 부모 메시지 요약이 항상 비던 버그가
  있었는데, 이관본은 둘 다 '작업 요약' 으로 통일해 함께 고친다.
- 요약에서 중첩 리스트('  -') skip (#18).

alert-direct-push job 제외(클라 범위 밖). 배포는 클라가 Vercel 이라 이 이관 범위 밖.
secret(DISCORD_BOT_TOKEN 공유·DISCORD_PR_CHANNEL_ID 전용·DISCORD_USER_MAP) 설정 완료.

* PR 봇 부모 메시지 라벨을 갱신 메시지와 같은 볼드·대문자 서식으로 통일

부모(최초) 메시지는 '🔥 연관 이슈'·'**branch**' 처럼 볼드 없는 소문자였고
갱신 메시지는 '🔥 **연관 이슈**'·'**Branch**' 로 달라, 첫 갱신 때 라벨 서식이
바뀌어 보였다. 부모 쪽을 갱신 쪽 서식에 맞춰 일치시킨다.

* synchronize 알림의 커밋 수·최신 커밋을 페이지네이션에 견고하게 계산

PR 커밋 API 는 30개/페이지(오래된→최신 순)라 첫 페이지만 받아 length 로 세면
31개 이상 PR 에서 커밋 수가 30 으로 잘리고, 첫 페이지 .[-1] 도 최신 커밋이 아니었다.
커밋 수는 이벤트 payload 의 .pull_request.commits 로, 최신 커밋은 마지막 페이지
(per_page=1 & page=총개수)로 집어 정확하게 만든다.
* PR 봇에 상태 리액션·부모 고정·스레드 정리·라벨 표시·헬퍼 공유 반영

이관 이후 서버 봇에 쌓인 개선을 클라 봇에 맞춰 반영한다.

- 상태 리액션: 부모 메시지에 열림/작업중/머지/종료를 이모지로 전환 표시(429 rate limit 재시도 포함)
- 부모 고정: 열린(리뷰 대기) PR 부모를 채널 상단에 고정, 종료 시 해제
- 스레드 정리: 종료 시 스레드명에 결과 프리픽스(✅/🗑️)+archive+lock
- 부모 카드에 라벨 표시(build_label_text)
- find_meta 가 메타 주석을 JSON 마커로 정확히 매칭 — 파일명을 언급한 리뷰 코멘트를
  집어 THREAD_ID 를 못 읽고 이후 스텝이 전부 skip 되던 버그(머지 알림 누락) 해소
- 헬퍼 4개를 $RUNNER_TEMP 공유 스크립트로 추출해 스텝 간 중복 제거(checkout 불필요)
- 커밋 수는 .pull_request.commits 로 정확화

클라 적응: push 트리거·alert-direct-push 잡 제외, ready_for_review→reopened,
작업 요약 섹션 매칭+중첩 불릿 스킵, 부모 카드 라벨 서식을 갱신 카드와 통일.
최신 커밋 메시지는 contents:read 없이 동작하도록 PR commits 엔드포인트로 조회.

* 재오픈된 PR 의 부모 재고정·스레드 복구 (reopened 흐름 정상화)

reopened 는 메타 주석이 이미 있어 post_parent 스텝이 스킵되는데, 부모 고정·상태
복구가 그 스텝 출력에만 의존해 재오픈 시 깨졌다. reopened 는 서버 봇엔 없고 클라
트리거라, 이 흐름 버그는 클라 전용이다.

- 부모 재고정: pin 스텝의 부모 id 를 post_parent → find_meta 로 폴백하고 조건도
  find_meta.message_id 를 포함하도록 넓혀, 재오픈 시 상단 고정이 복구되게 한다.
- 스레드 복구: 종료 시 archived·locked 로 잠그고 이름에 🗑️ 프리픽스를 다는데,
  재오픈 시 되돌리는 경로가 없어 이후 synchronize 답글이 잠긴 스레드라 실패했다.
  reopened 에 unarchive·unlock + 이름 원복 스텝을 추가한다.
* fix: 게스트 MEMBER_ONLY 접근 시 로그인 무한 루프 수정

회원(MEMBER) 토큰일 때만 로그인 페이지를 건너뛰도록 제한.
게스트는 로그인에 남아 archive↔login 무한 루프 방지.

* fix: 게스트 자동 로그인 시 현재 요청부터 token 적용되도록 수정

* refactor: 로그인 약관 안내 문구를 page로 분리

* feat: 게스트 세션 살아있는 경우 게스트 로그인 선택 시 리프레시 진행

* style: 토스트 위치 오류 수정

* feat: 게스트 로그인 redirect path가 /archive인 경우 /home으로 이동 및 안내 토스트 노출

* fix: 앱 부팅 시 refresh cookie 죽는 문제 해결

* fix: proxy에서 앱 auth token 도 처리 가능하도록 수정

* refactor: 앱 token refresh timeout 추가

* fix: 앱 토큰 만료(401) 시 WebView 쿠키도 정리

* fix: 앱 refresh 응답 snake_case 파싱 수정

* chore: proxy.ts refresh 401 임시 안전망 제거 (백엔드 rotation grace 적용) (#295)

* chore: proxy.ts refresh 401 임시 안전망 제거 (백엔드 rotation grace 적용) (#295)

* fix: iOS 26 Safari 노치 영역이 흰색으로 보이는 문제 수정 (#293)

Co-authored-by: Jung Sun A <amber0809@naver.com>

* refactor: 로그인 후 리다이렉트 로직 유틸로 추출

- 로그인 성공 후 경로 계산 중복 제거 (getPostLoginRedirectPath)

* fix: 공유 위시 등록 시 refresh 401이면 죽은 토큰 정리

Share Extension이 만료된 토큰으로 재시도를 반복하지 않도록 refresh 401 시 clearTokens 호출

---------

Co-authored-by: 조영찬 <tigerbone@naver.com>
* feat: web Sentry 에러 모니터링 도입

* feat: app Sentry 에러 모니터링 도입

* feat: web/app sentry 에러 로깅 규약 추가

- app: @sentry/react-native 셋업(_layout init+wrap, metro, 플러그인, eas 환경별 주입)
- 공용 captureError 유틸(web/app) — 태그/컨텍스트 일관 부착
- API 5xx·네트워크 에러 중앙 수집(axios 인터셉터 / app fetch)
- 유저 식별 setUser(id), 세션 만료 시 해제
- error.tsx 캡처, ignoreErrors 노이즈 필터
- app WebView onError/onHttpError, 백그라운드 FCM 핸들러 수집

* test: 에러 검증용 테스트 페이지 생성

* fix: SENTRY_AUTH_TOKEN turbo passThroughEnv 추가 (소스맵 업로드)

* feat: Session Replay 마스킹 완화 (이메일만 마스킹, 나머지 노출)

* feat: API 에러 리포트 제목을 'API {status} {method} {path}' 형식으로 개선

* Revert "test: 에러 검증용 테스트 페이지 생성"

This reverts commit 87f9e53.

* fix: 소셜 로그인 5xx 응답 JSON 파싱 실패 시 Sentry 수집 누락 수정

* fix: 로그아웃 시 Sentry 유저 컨텍스트 해제

* fix: Session Replay 타이핑 입력창만 마스킹 (maskAllInputs)

* fix: 소셜 로그인 2xx 응답 본문 파싱 실패도 Sentry 수집
* feat: 토스트 offset 페이지별 override 메커니즘 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: 홈 탭바 위로 토스트 위치 조정

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: 보관 페이지 하단 바 위로 토스트 위치 조정

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: 토스트 offset 수치 조정

* refactor: 토스트 offset zustand 스토어를 CSS :has() 마커 방식으로 대체

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* PR 봇 스레드에 팀원 자동 추가로 팀 전원 사이드바 노출

Discord 공개 스레드는 멤버(생성자·초대·멘션된 사람)만 사이드바에 뜬다. 부모 카드가
작성자만 @멘션해 작성자만 자기 PR 스레드가 보이고 남의 스레드는 안 떴다.

- 스레드 생성 직후 DISCORD_USER_MAP 의 팀원 전원을 thread-members 로 추가해 새 PR
  스레드가 팀 전원 사이드바에 뜨게 한다(멘션과 달리 조용히 목록에만 올림).
- 이 변경 이전 열린 PR 스레드용으로 backfill-thread-members 잡을 추가한다
  (workflow_dispatch 수동 실행). notify-discord 는 pull_request 로 가드해 dispatch 시엔 안 돈다.

* 연관 이슈 링크의 Discord 임베드 카드 억제

부모 카드의 연관 이슈 링크가 GitHub 임베드 카드로 커지게 떠서 본문(작업 요약 등)을
아래로 밀어냈다. 이슈 URL 을 <> 로 감싸 임베드만 억제하고 클릭 링크는 유지한다.
PR 타이틀 링크는 그대로 둬 PR 카드는 계속 뜬다.

* 작업 요약 추출이 STAR 의 Task 섹션도 인식

FE 팀 PR 은 ## 작업 요약, 서버 STAR 로 쓴 PR 은 ## Task 를 쓴다. build_summary 가
작업 요약만 찾아 STAR PR 은 '요약 없음'이 됐다. 두 섹션명을 모두 인식하게 해
어느 관례로 쓰든 요약이 채워지게 한다.

* 작업 요약의 Task 섹션 인식 제거

FE 팀은 ## 작업 요약을 쓰고 봇이 이미 이를 매칭하므로, STAR 의 ## Task 인식 추가는
불필요해 되돌린다. 요약은 PR 본문에 ## 작업 요약 을 두는 팀 관례로 채운다.
서버 봇(#703)과 갈라진 두 가지를 클라에도 반영해 동작을 일치시킨다.

- 머지 시 close 정리에서 locked 제거(archived 만) — 닫히되 글을 쓸 수 있게(archived 만이라
  글을 쓰면 다시 열림). 머지된 PR 스레드가 잠겨 글을 못 쓰던 문제 해소.
- 백필 잡을 종합형(backfill-threads)으로 교체: 열린 PR→팀원 추가+열림, 머지 PR→✅+닫힘,
  미머지 닫힘→🗑️+닫힘. 기존엔 열린 스레드 팀원 추가만 했다. 과거 find_meta 버그로 안 닫힌
  스레드까지 소급 정리(멱등).
* docs: 역할 분배 문서 추가

* docs: 현재 api 에러 대응 현황 문서 추가

* docs: 에러 처리 정책 문서 추가

* feat: 공통 API 에러 메시지 유틸 추가

* feat: 전역 mutation/query 에러 안전망 도입

* refactor: 비어있는 개별 onError 삭제 (전역 안전망 위임)

* refactor: 개별 훅 5xx 토스트 분기 제거 (이중 토스트 방지)

* PR 봇을 Slack 에서 Discord 로 이관 (#308)

* chore: PR 봇을 Slack 에서 Discord 로 이관

slack-pr-bot.yml 제거 + discord-pr-bot.yml 추가 (서버 PIKI-Server 검증본 기반).
리뷰어 멘션(initial_reviewers + requested_reviewers)·연관 이슈(close #N) 로직 동일.

클라 slack 커밋 이력(#14·#17·#18·#20)을 추적해 서버와 다른 클라 특화를 반영:
- 트리거·부모 메시지 조건: ready_for_review → reopened (#17, 기존 slack 봇과 동일).
- 요약 파싱 섹션명: Task → 작업 요약 (클라 PR 템플릿이 '## 작업 요약'). 클라 slack 은 두 요약 함수의
  섹션명이 '작업 내용'/'작업 요약' 으로 불일치(#20 이 한쪽만 수정)해 부모 메시지 요약이 항상 비던 버그가
  있었는데, 이관본은 둘 다 '작업 요약' 으로 통일해 함께 고친다.
- 요약에서 중첩 리스트('  -') skip (#18).

alert-direct-push job 제외(클라 범위 밖). 배포는 클라가 Vercel 이라 이 이관 범위 밖.
secret(DISCORD_BOT_TOKEN 공유·DISCORD_PR_CHANNEL_ID 전용·DISCORD_USER_MAP) 설정 완료.

* PR 봇 부모 메시지 라벨을 갱신 메시지와 같은 볼드·대문자 서식으로 통일

부모(최초) 메시지는 '🔥 연관 이슈'·'**branch**' 처럼 볼드 없는 소문자였고
갱신 메시지는 '🔥 **연관 이슈**'·'**Branch**' 로 달라, 첫 갱신 때 라벨 서식이
바뀌어 보였다. 부모 쪽을 갱신 쪽 서식에 맞춰 일치시킨다.

* synchronize 알림의 커밋 수·최신 커밋을 페이지네이션에 견고하게 계산

PR 커밋 API 는 30개/페이지(오래된→최신 순)라 첫 페이지만 받아 length 로 세면
31개 이상 PR 에서 커밋 수가 30 으로 잘리고, 첫 페이지 .[-1] 도 최신 커밋이 아니었다.
커밋 수는 이벤트 payload 의 .pull_request.commits 로, 최신 커밋은 마지막 페이지
(per_page=1 & page=총개수)로 집어 정확하게 만든다.

* PR 봇 서버 개선 반영 (상태 리액션·부모 고정·스레드 정리·라벨·헬퍼 공유) (#310)

* PR 봇에 상태 리액션·부모 고정·스레드 정리·라벨 표시·헬퍼 공유 반영

이관 이후 서버 봇에 쌓인 개선을 클라 봇에 맞춰 반영한다.

- 상태 리액션: 부모 메시지에 열림/작업중/머지/종료를 이모지로 전환 표시(429 rate limit 재시도 포함)
- 부모 고정: 열린(리뷰 대기) PR 부모를 채널 상단에 고정, 종료 시 해제
- 스레드 정리: 종료 시 스레드명에 결과 프리픽스(✅/🗑️)+archive+lock
- 부모 카드에 라벨 표시(build_label_text)
- find_meta 가 메타 주석을 JSON 마커로 정확히 매칭 — 파일명을 언급한 리뷰 코멘트를
  집어 THREAD_ID 를 못 읽고 이후 스텝이 전부 skip 되던 버그(머지 알림 누락) 해소
- 헬퍼 4개를 $RUNNER_TEMP 공유 스크립트로 추출해 스텝 간 중복 제거(checkout 불필요)
- 커밋 수는 .pull_request.commits 로 정확화

클라 적응: push 트리거·alert-direct-push 잡 제외, ready_for_review→reopened,
작업 요약 섹션 매칭+중첩 불릿 스킵, 부모 카드 라벨 서식을 갱신 카드와 통일.
최신 커밋 메시지는 contents:read 없이 동작하도록 PR commits 엔드포인트로 조회.

* 재오픈된 PR 의 부모 재고정·스레드 복구 (reopened 흐름 정상화)

reopened 는 메타 주석이 이미 있어 post_parent 스텝이 스킵되는데, 부모 고정·상태
복구가 그 스텝 출력에만 의존해 재오픈 시 깨졌다. reopened 는 서버 봇엔 없고 클라
트리거라, 이 흐름 버그는 클라 전용이다.

- 부모 재고정: pin 스텝의 부모 id 를 post_parent → find_meta 로 폴백하고 조건도
  find_meta.message_id 를 포함하도록 넓혀, 재오픈 시 상단 고정이 복구되게 한다.
- 스레드 복구: 종료 시 archived·locked 로 잠그고 이름에 🗑️ 프리픽스를 다는데,
  재오픈 시 되돌리는 경로가 없어 이후 synchronize 답글이 잠긴 스레드라 실패했다.
  reopened 에 unarchive·unlock + 이름 원복 스텝을 추가한다.

* fix: 게스트 인증 플로우 버그 2건 수정 + 관련 UX 개선 (#291)

* fix: 게스트 MEMBER_ONLY 접근 시 로그인 무한 루프 수정

회원(MEMBER) 토큰일 때만 로그인 페이지를 건너뛰도록 제한.
게스트는 로그인에 남아 archive↔login 무한 루프 방지.

* fix: 게스트 자동 로그인 시 현재 요청부터 token 적용되도록 수정

* refactor: 로그인 약관 안내 문구를 page로 분리

* feat: 게스트 세션 살아있는 경우 게스트 로그인 선택 시 리프레시 진행

* style: 토스트 위치 오류 수정

* feat: 게스트 로그인 redirect path가 /archive인 경우 /home으로 이동 및 안내 토스트 노출

* fix: 앱 부팅 시 refresh cookie 죽는 문제 해결

* fix: proxy에서 앱 auth token 도 처리 가능하도록 수정

* refactor: 앱 token refresh timeout 추가

* fix: 앱 토큰 만료(401) 시 WebView 쿠키도 정리

* fix: 앱 refresh 응답 snake_case 파싱 수정

* chore: proxy.ts refresh 401 임시 안전망 제거 (백엔드 rotation grace 적용) (#295)

* chore: proxy.ts refresh 401 임시 안전망 제거 (백엔드 rotation grace 적용) (#295)

* fix: iOS 26 Safari 노치 영역이 흰색으로 보이는 문제 수정 (#293)

Co-authored-by: Jung Sun A <amber0809@naver.com>

* refactor: 로그인 후 리다이렉트 로직 유틸로 추출

- 로그인 성공 후 경로 계산 중복 제거 (getPostLoginRedirectPath)

* fix: 공유 위시 등록 시 refresh 401이면 죽은 토큰 정리

Share Extension이 만료된 토큰으로 재시도를 반복하지 않도록 refresh 401 시 clearTokens 호출

---------

Co-authored-by: 조영찬 <tigerbone@naver.com>

* feat: Sentry 에러 모니터링 도입 (#296)

* feat: web Sentry 에러 모니터링 도입

* feat: app Sentry 에러 모니터링 도입

* feat: web/app sentry 에러 로깅 규약 추가

- app: @sentry/react-native 셋업(_layout init+wrap, metro, 플러그인, eas 환경별 주입)
- 공용 captureError 유틸(web/app) — 태그/컨텍스트 일관 부착
- API 5xx·네트워크 에러 중앙 수집(axios 인터셉터 / app fetch)
- 유저 식별 setUser(id), 세션 만료 시 해제
- error.tsx 캡처, ignoreErrors 노이즈 필터
- app WebView onError/onHttpError, 백그라운드 FCM 핸들러 수집

* test: 에러 검증용 테스트 페이지 생성

* fix: SENTRY_AUTH_TOKEN turbo passThroughEnv 추가 (소스맵 업로드)

* feat: Session Replay 마스킹 완화 (이메일만 마스킹, 나머지 노출)

* feat: API 에러 리포트 제목을 'API {status} {method} {path}' 형식으로 개선

* Revert "test: 에러 검증용 테스트 페이지 생성"

This reverts commit 87f9e53.

* fix: 소셜 로그인 5xx 응답 JSON 파싱 실패 시 Sentry 수집 누락 수정

* fix: 로그아웃 시 Sentry 유저 컨텍스트 해제

* fix: Session Replay 타이핑 입력창만 마스킹 (maskAllInputs)

* fix: 소셜 로그인 2xx 응답 본문 파싱 실패도 Sentry 수집

* feat: mutation 오류 발생 시 Sentry 로깅 추가

* docs: 역할정리 수정

* docs: 역할 관련 문서 업데이트

---------

Co-authored-by: sevineleven <117634128+sevineleven@users.noreply.github.com>
Co-authored-by: 조영찬 <tigerbone@naver.com>
* refactor: 게스트 참여 dead code 제거

* refactor: 게스트 참여 dead code 제거 2

---------

Co-authored-by: Jung Sun A <amber0809@naver.com>
* refactor: 링크 입력 시 텍스트에서 URL 자동 추출

* fix: URL 패턴 anchor 추가로 트레일링 텍스트 제출 방지
@iOdiO89 iOdiO89 self-assigned this Jul 11, 2026
@iOdiO89 iOdiO89 added feature New feature or request APP Good for newcomers labels Jul 11, 2026
@iOdiO89 iOdiO89 linked an issue Jul 11, 2026 that may be closed by this pull request
15 tasks
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
depromeet Ready Ready Preview, Comment Jul 11, 2026 10:56pm

@github-actions
github-actions Bot requested review from soyeong0115 and ychany July 11, 2026 22:05
@github-actions

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 04922a3b-271a-4c9d-8a3d-43bdcd271cfc

📥 Commits

Reviewing files that changed from the base of the PR and between 5058663 and 2ec6bca.

📒 Files selected for processing (2)
  • apps/app/app/index.tsx
  • apps/web/src/hooks/useAppNavigate.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/app/app/index.tsx
  • apps/web/src/hooks/useAppNavigate.ts

📝 Walkthrough

Walkthrough

HTTPS 도메인을 iOS Universal Links와 Android App Links 대상으로 등록하고, 웹 경로를 앱의 cold start 또는 warm start 흐름으로 전달합니다. warm start는 웹브리지 메시지와 내부 경로 검증을 거쳐 SPA 라우팅 및 전환 오버레이를 수행합니다.

Changes

딥링크 진입과 경로 정규화

Layer / File(s) Summary
플랫폼 링크 설정과 URL 경로 추출
apps/app/app.json, apps/app/utils/webDeepLink.ts
iOS associated domains와 Android HTTPS intent filter를 추가하고, 허용 호스트 URL에서 pathname과 query를 추출하며 제외 경로를 처리합니다.
Cold start 및 warm start 분기
apps/app/app/+native-intent.ts, apps/app/hooks/useWebDeepLink.ts, apps/app/app/index.tsx
Universal Link와 Smart App Banner URL을 /?web= 형식으로 정규화하고, cold start에는 WebView URI를 전달하며 warm start에는 웹 경로를 로드된 WebView로 전달합니다.

웹브리지 기반 warm start 내비게이션

Layer / File(s) Summary
내비게이션 메시지 계약과 앱 전달
packages/core/src/consts/webBridge.ts, packages/core/src/types/navigation.ts, packages/core/src/types/webBridge.ts, packages/core/src/index.ts, apps/app/app/index.tsx
APP_REQ_NAVIGATE 메시지와 경로 payload 타입을 추가하고, 앱의 warm start 경로를 WebBridge 메시지로 전송합니다.
웹 라우팅과 안전성 검증
apps/web/src/hooks/useAppNavigate.ts, apps/web/src/utils/isSafeInternalPath.ts
내부 경로를 검증한 뒤 router.push를 실행하고, 목표 pathname과 현재 pathname을 비교해 pending 상태와 timeout 해제를 관리합니다.
내비게이션 오버레이
apps/web/src/components/Providers.tsx, apps/web/src/components/navigation-overlay/index.tsx, apps/web/src/consts/zIndex.ts
내비게이션 pending 상태에서 접근성 속성을 포함한 전체 화면 Spinner 오버레이를 표시합니다.

웹 연동 메타데이터와 연결 파일

Layer / File(s) Summary
앱 연결 파일과 응답 헤더
apps/web/public/.well-known/*, apps/web/next.config.mjs
AASA와 Android assetlinks association 파일을 추가하고 두 well-known 경로에 JSON Content-Type을 설정합니다.
iOS Smart App Banner 메타데이터
apps/web/src/app/tournament/join/[id]/page.tsx
환경변수와 요청 host를 사용해 tournament join URL 및 invite code 기반의 itunes.appArgument 메타데이터를 생성합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant OS
  participant App
  participant WebView
  participant WebRouter
  User->>OS: HTTPS 도메인 링크 선택
  OS->>App: Universal Link 또는 App Link로 앱 실행
  App->>WebView: cold start 경로 로드 또는 warm start 메시지 전송
  WebView->>WebRouter: APP_REQ_NAVIGATE 경로 전달
  WebRouter->>WebRouter: 내부 경로 검증 후 SPA 라우팅
Loading

Possibly related PRs

  • TeamPiKi/PiKi-Client#153: 공용 WebBridge 메시지 계약과 앱 측 메시지 처리 흐름을 함께 확장합니다.

Suggested labels: WEB

Suggested reviewers: ychany, soyeong0115

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 Universal/App Link와 warm start 딥링크 지원이라는 핵심 변경을 정확히 요약합니다.
Linked Issues check ✅ Passed [#283] AASA/assetlinks, Expo 설정, WebView 경로 반영, cold/warm start 처리까지 핵심 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 스마트 배너, 로딩 오버레이, 브리지 타입 추가 등도 모두 딥링크/앱 링크 구현 범위에 포함됩니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/283-app-link

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/app/app/index.tsx`:
- Around line 43-51: Update handleWarmStartNavigate to defer and retain the
deep-link path while isSynced indicates the WebView is not ready, then send the
queued path through WebBridge.postMessage once synchronization completes.
Preserve immediate delivery for ready WebViews and clear each queued path after
successful delivery.

In `@apps/web/src/hooks/useAppNavigate.ts`:
- Around line 26-46: Reset the navigation timeout whenever a new
APP_REQ_NAVIGATE message is accepted, even if isNavigatePending remains true.
Update the useEffect dependencies or timer trigger around setTargetPathname and
the navigate callback so each new target starts a full OVERLAY_TIMEOUT_MS
interval, while retaining cleanup for prior timers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: aba152d6-c607-4661-afa1-5ebe8b0f43f9

📥 Commits

Reviewing files that changed from the base of the PR and between 462f210 and 5058663.

📒 Files selected for processing (18)
  • apps/app/app.json
  • apps/app/app/+native-intent.ts
  • apps/app/app/index.tsx
  • apps/app/hooks/useWebDeepLink.ts
  • apps/app/utils/webDeepLink.ts
  • apps/web/next.config.mjs
  • apps/web/public/.well-known/apple-app-site-association
  • apps/web/public/.well-known/assetlinks.json
  • apps/web/src/app/tournament/join/[id]/page.tsx
  • apps/web/src/components/Providers.tsx
  • apps/web/src/components/navigation-overlay/index.tsx
  • apps/web/src/consts/zIndex.ts
  • apps/web/src/hooks/useAppNavigate.ts
  • apps/web/src/utils/isSafeInternalPath.ts
  • packages/core/src/consts/webBridge.ts
  • packages/core/src/index.ts
  • packages/core/src/types/navigation.ts
  • packages/core/src/types/webBridge.ts

Comment thread apps/app/app/index.tsx
Comment thread apps/web/src/hooks/useAppNavigate.ts Outdated
@iOdiO89
iOdiO89 merged commit 98b51d5 into dev Jul 11, 2026
8 checks passed
@iOdiO89
iOdiO89 deleted the feat/283-app-link branch July 11, 2026 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP Good for newcomers feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: iOS Universal Link / Android App Link 추가

4 participants