Skip to content

fix: 페이지별 토스트 위치 커스터마이즈 (탭바 페이지 토스트 겹침 수정)#309

Merged
kanghaeun merged 6 commits into
devfrom
fix/297-customize-toast-position-by-page
Jul 6, 2026
Merged

fix: 페이지별 토스트 위치 커스터마이즈 (탭바 페이지 토스트 겹침 수정)#309
kanghaeun merged 6 commits into
devfrom
fix/297-customize-toast-position-by-page

Conversation

@kanghaeun

@kanghaeun kanghaeun commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

작업 요약

  • 홈/보관 페이지에서 토스트가 하단 탭바와 겹치는 문제 수정
  • 토스트 offset을 페이지(컴포넌트)별로 override할 수 있는 로직 추가

작업 세부 내용

전역 Toasteroffset: 90px 고정값 하나로 모든 페이지에 적용되어, Bottom Tab Bar가 있는 홈/보관 페이지에서 토스트가 탭바와 겹치는 문제를 수정했습니다.

  • 탭바는 bottom-[40px] + 자체 높이 약 68px → 상단이 뷰포트 바닥에서 약 108px 지점인데, 토스트 offset이 90px이라 탭바 상단과 겹침
  • 토너먼트 준비·로그인 등 하단 in-flow 버튼(~88px) 페이지는 기존 offset이 잘 맞는 상태

변경 사항

1. 토스트 offset 페이지별 override 메커니즘 추가 (components/toast/)

  • toast.const.ts — offset 상수 분리: DEFAULT(95px) / ABOVE_TAB_BAR(115px)
  • useToastOffset.ts — zustand 기반 스택형 override 스토어 + 마운트 동안 offset을 등록하고 언마운트 시 자동 해제하는 useToastOffset
  • Toaster — 마지막 override 값(없으면 DEFAULT)을 구독해 offset/mobileOffset에 적용

2. BottomTabBar 자동 등록 (components/bottom-tab-bar/)

  • 컴포넌트 내부에서 useToastOffset(TOAST_OFFSET.ABOVE_TAB_BAR) 호출
  • 탭바가 렌더되는 페이지(홈 등)는 별도 작업 없이 토스트가 탭바 위에 뜸

3. WishlistBottomBar 등록 (app/archive/_components/)

  • 보관 페이지 삭제 모드에서 탭바가 "n개 선택됨" pill로 교체되어 BottomTabBar가 언마운트돼도 offset이 유지되도록 자체 등록
  • 두 컴포넌트가 중복 등록해도 안전하도록 스토어를 스택 구조로 설계

변경하지 않은 것

  • 탭바 없는 페이지(토너먼트 준비/결과, 로그인, BottomCta 편집 등)는 기본 offset 유지 → 회귀 없음
  • toast.success() 등 기존 토스트 호출부 변경 없음
  • 향후 바텀시트/CTA 높이가 다른 페이지는 해당 컴포넌트에서 useToastOffset('...px') 한 줄로 개별 지정 가능

스크린샷

Before After
Before After

연관 이슈

closes #297

Summary by CodeRabbit

  • 버그 수정
    • 하단 탭 바가 있는 화면에서 토스트 알림이 탭 바와 겹치지 않도록 위치를 조정했습니다.
    • 삭제 모드에서 하단 바가 사라져도 토스트가 더 안정적으로 하단 영역 위에 표시되도록 개선했습니다.
    • 모바일과 데스크톱 모두에서 하단 여백 기준이 더 일관되게 적용됩니다.

kanghaeun and others added 4 commits July 5, 2026 18:36
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 5, 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 6, 2026 3:04am

@github-actions
github-actions Bot requested review from iOdiO89 and ychany July 5, 2026 10:06
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

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

@github-actions github-actions Bot added the fix Something isn't working label Jul 5, 2026
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kanghaeun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4e3d9350-a035-4f9b-b260-2878cca841d3

📥 Commits

Reviewing files that changed from the base of the PR and between 310d5bf and d5901d5.

📒 Files selected for processing (1)
  • apps/web/src/components/toast/index.tsx
📝 Walkthrough

Walkthrough

BottomTabBar와 WishlistBottomBar 컨테이너에 data-bottom-tab-bar 마커 속성을 추가하고, globals.css에서 해당 마커가 존재하는 페이지의 Sonner 토스트 하단 오프셋을 115px로 강제하는 CSS 규칙을 신설했으며, 기본 TOAST_OFFSET 상수를 90px에서 95px로 조정했습니다.

Changes

탭바 마커 기반 토스트 오프셋 조정

Layer / File(s) Summary
탭바 컨테이너에 마커 속성 추가
apps/web/src/components/bottom-tab-bar/index.tsx, apps/web/src/app/archive/_components/WishlistBottomBar.tsx
BottomTabBar와 WishlistBottomBar의 하단 고정 컨테이너에 data-bottom-tab-bar 속성과 설명 주석을 추가했고, BottomTabBar의 그라데이션 배경 JSX 표현과 import 순서를 정리함.
마커 기반 CSS 오프셋 강제 및 기본값 조정
apps/web/src/styles/globals.css, apps/web/src/components/toast/index.tsx
body:has([data-bottom-tab-bar]) 조건에서 하단 토스트의 offset 변수를 115px로 강제하는 CSS 규칙을 추가하고, TOAST_OFFSET 기본값을 90px에서 95px로 변경함.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • depromeet/PIKI-Client#263: 위시리스트 삭제 시 토스트를 노출하는 변경으로, 삭제 모드에서 하단 탭바 대비 토스트 위치를 조정하는 본 PR과 동일한 삭제-토스트 흐름을 지원함.

Suggested reviewers: ychany, iOdiO89

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 탭바 페이지용 마커/CSS만 추가되어 페이지별 useToastOffset 주입 구조와 비탭바 화면 기본 오프셋 요구를 충족하지 못합니다. useToastOffset 같은 페이지·레이아웃 단위 훅이나 컨텍스트를 추가하고, 비탭바 페이지와 하단 CTA 화면별 오프셋을 적용하세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 페이지별 토스트 위치 조정이라는 핵심 변경을 잘 요약해 적절합니다.
Out of Scope Changes check ✅ Passed 변경은 토스트 오프셋 조정과 탭바/위시 바 관련 수정에 한정되어 보여 명백한 범위 밖 변경은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

❤️ Share

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: 1

🤖 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/web/src/components/toast/index.tsx`:
- Around line 7-8: The imports in the toast component are using relative paths
while the rest of the PR follows the `@/` alias convention. Update the import
statements in the toast component to use absolute alias paths for toast.const
and useToastOffset, matching the patterns used by BottomTabBar and
WishlistBottomBar, and keep the import style consistent across apps/web/src.
🪄 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

Run ID: f2a1a6cc-0971-4f64-8d65-ac3a4e6a4848

📥 Commits

Reviewing files that changed from the base of the PR and between 66947a7 and 57c3b4f.

📒 Files selected for processing (5)
  • apps/web/src/app/archive/_components/WishlistBottomBar.tsx
  • apps/web/src/components/bottom-tab-bar/index.tsx
  • apps/web/src/components/toast/index.tsx
  • apps/web/src/components/toast/toast.const.ts
  • apps/web/src/components/toast/useToastOffset.ts

Comment thread apps/web/src/components/toast/index.tsx Outdated

@iOdiO89 iOdiO89 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

바텀탭 유무에 따라 toast bottom offset이 달라져서, 그걸 zustand store 기반으로 수정한 거 맞지?

우리 코드베이스에 zustand(상태관리툴) 사용처가 아직 없는데, toast에서만 zustand 쓰는 게 좀 마음에 걸리네. 개인적으로는 zustand 없이 문제를 해결할 수 있으면 더 좋을 것 같다는 생각 ..

4개 중에 하나로 수정해보면 어떨까! 개인적으로는 1 추천

대안

  1. CSS :has() — 하단바에 마커만 달고 body:has([data-bottom-tab-bar]) [data-sonner-toaster] { --offset-bottom: 115px !important }로 처리, JS 상태 0줄에 마운트/언마운트·삭제모드 전환까지 브라우저가 자동 처리돼서 가장 우아함
  2. useSyncExternalStore — React 내장 훅으로 모듈 전역 스택 구독, 외부 의존성 없이 zustand 동작을 그대로 재현하고 하단바가 스스로 offset 등록(colocation 유지)
  3. pathname 분기 — Toaster 내부에서 usePathname()으로 탭바 있는 라우트만 분기, 코드 최소·최고 가독성이지만 새 탭바 페이지 추가 시 route 목록 수동 관리 필요
  4. React Context + useState — 표준 React 패턴으로 Provider가 children+Toaster를 감싸 스택 관리, useSyncExternalStore와 쌍둥이지만 Provider가 하나 필요

@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.

🧹 Nitpick comments (2)
apps/web/src/app/archive/_components/WishlistBottomBar.tsx (1)

10-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

마커 속성명 data-bottom-tab-bar가 실제 용도와 어긋남.

삭제 모드에서는 BottomTabBar가 아니라 선택 개수 뱃지가 렌더되는데도 동일한 data-bottom-tab-bar 마커를 유지하고 있습니다. 실제 의도는 "하단에 고정 UI가 있으니 토스트를 올려야 한다"는 범용 신호이므로, 이름을 data-bottom-fixed-ui처럼 의미에 맞게 바꾸면 향후 유지보수자가 혼동하지 않을 것입니다. 코드/주석상으로는 명확히 문서화되어 있어 기능적으로 문제는 없습니다.

🤖 Prompt for 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.

In `@apps/web/src/app/archive/_components/WishlistBottomBar.tsx` around lines 10 -
14, The marker attribute name used in WishlistBottomBar is too specific to
BottomTabBar even though this component can render the deletion-mode badge
instead. Rename the existing data-bottom-tab-bar marker to a more generic name
such as data-bottom-fixed-ui in the WishlistBottomBar component, and update any
related globals.css comments or selectors so the intent matches the actual fixed
UI behavior.
apps/web/src/styles/globals.css (1)

193-196: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

115px 매직넘버 중복 - CSS 변수로 추출 고려.

--offset-bottom, --mobile-offset-bottom에 동일한 115px 값이 두 번 하드코딩되어 있습니다. 로컬 CSS 변수(예: --tab-bar-toast-offset: 115px)로 한 번만 선언 후 재사용하면 향후 값 조정 시 한 곳만 수정하면 됩니다.

♻️ 제안
 body:has([data-bottom-tab-bar]) [data-sonner-toaster][data-y-position='bottom'] {
-  --offset-bottom: 115px !important;
-  --mobile-offset-bottom: 115px !important;
+  --tab-bar-toast-offset: 115px;
+  --offset-bottom: var(--tab-bar-toast-offset) !important;
+  --mobile-offset-bottom: var(--tab-bar-toast-offset) !important;
 }
🤖 Prompt for 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.

In `@apps/web/src/styles/globals.css` around lines 193 - 196, The bottom toaster
offset in the globals stylesheet hardcodes the same 115px value twice. In the
body:has([data-bottom-tab-bar]) [data-sonner-toaster][data-y-position='bottom']
rule, extract that value into a local CSS variable and reuse it for both
--offset-bottom and --mobile-offset-bottom so it can be updated in one place.
🤖 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.

Nitpick comments:
In `@apps/web/src/app/archive/_components/WishlistBottomBar.tsx`:
- Around line 10-14: The marker attribute name used in WishlistBottomBar is too
specific to BottomTabBar even though this component can render the deletion-mode
badge instead. Rename the existing data-bottom-tab-bar marker to a more generic
name such as data-bottom-fixed-ui in the WishlistBottomBar component, and update
any related globals.css comments or selectors so the intent matches the actual
fixed UI behavior.

In `@apps/web/src/styles/globals.css`:
- Around line 193-196: The bottom toaster offset in the globals stylesheet
hardcodes the same 115px value twice. In the body:has([data-bottom-tab-bar])
[data-sonner-toaster][data-y-position='bottom'] rule, extract that value into a
local CSS variable and reuse it for both --offset-bottom and
--mobile-offset-bottom so it can be updated in one place.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d1c1fee7-7409-4e24-8aa9-ee14d4c9ca5f

📥 Commits

Reviewing files that changed from the base of the PR and between 57c3b4f and 310d5bf.

📒 Files selected for processing (4)
  • apps/web/src/app/archive/_components/WishlistBottomBar.tsx
  • apps/web/src/components/bottom-tab-bar/index.tsx
  • apps/web/src/components/toast/index.tsx
  • apps/web/src/styles/globals.css
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/components/toast/index.tsx

@kanghaeun

Copy link
Copy Markdown
Contributor Author

리뷰 반영해서 1번 CSS :has() 방식으로 수정했어! (310d5bf)

적용하면서 한가지 보완도 같이 진행

  • sonner가 모바일(600px 이하)에서는 --mobile-offset-bottom을 따로 쓰길래 두 변수 다 오버라이드

상태 관리 없이 처리되니 깔끔하당 좋은 제안 감사합니다

@kanghaeun
kanghaeun merged commit dad6817 into dev Jul 6, 2026
5 checks passed
@kanghaeun
kanghaeun deleted the fix/297-customize-toast-position-by-page branch July 6, 2026 03:38
iOdiO89 pushed a commit that referenced this pull request Jul 10, 2026
* 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>
iOdiO89 added a commit that referenced this pull request Jul 11, 2026
* chore: iOS Smart Banner 설정

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

* feat: iOS Universal Link 설정 및 딥링크 라우팅 확장

- AASA 파일 추가 (콜백/api 경로는 exclude)
- iOS associatedDomains 설정
- Universal Link/Smart Banner app-argument의 https URL을 WebView 경로로 라우팅

* feat: android app link 관련 config 추가

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

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

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

* 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 수집

* fix: 페이지별 토스트 위치 커스터마이즈 (탭바 페이지 토스트 겹침 수정) (#309)

* 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>

* feat: 딥링크 전환 로딩 오버레이 추가

* feat: 앱 링크 접속시 warm start 기능 추가

* PR 봇 스레드를 팀 전원이 볼 수 있게 (스레드 멤버 자동 추가) (#313)

* 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 본문에 ## 작업 요약 을 두는 팀 관례로 채운다.

* PR 봇 재싱크: 머지 스레드 잠금 해제 + 종합 백필 (서버 #703 반영) (#315)

서버 봇(#703)과 갈라진 두 가지를 클라에도 반영해 동작을 일치시킨다.

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

* refactor: 링크 입력창 모바일 키보드를 일반 텍스트 키보드로 변경 (#325)

* feat: 전역 API 에러 안전망 도입 및 개별 훅 에러 처리 정리 (#311)

* 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 제거 (#321)

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

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

---------

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

* chore: update app version

* chore: eas config 삭제

* refactor: 링크 입력 시 텍스트에서 URL 자동 추출 (#323)

* refactor: 링크 입력 시 텍스트에서 URL 자동 추출

* fix: URL 패턴 anchor 추가로 트레일링 텍스트 제출 방지

* fix: warm start 딥링크 보류 처리

* fix: 앱 내비게이션 타이머 갱신

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: 조영찬 <tigerbone@naver.com>
Co-authored-by: sevineleven <117634128+sevineleven@users.noreply.github.com>
Co-authored-by: kanghaeun <145974230+kanghaeun@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 페이지별 토스트 노출 위치 커스터마이징 필요

2 participants