✨ 어드민 API 환경(stage/prod) 플로팅 스위처 추가 - #619
Conversation
로그인 이메일로 dev/prod를 자동 판별하던 방식을 제거하고, 저장된 환경 값을 "stage"/"prod"로 통일했다. 레거시로 저장된 "dev" 값은 loadAdminApiEnvironment에서 "stage"로 해석해 기존 사용자 선택을 보존한다. 환경 전환은 이후 FAB이 호출할 switchAdminApiEnvironment(clearSession → saveAdminApiEnvironment → 리다이렉트)로 일원화한다.
어드민 배포가 main 하나로 통합됨에 따라, 로그인 이메일 대신 화면 우하단 플로팅 버튼(FAB)으로 stage/prod API 환경을 명시적으로 전환하도록 했다. 클릭 시 confirm으로 로그아웃 경고 후 switchAdminApiEnvironment를 호출해 세션을 정리하고 환경을 저장한 뒤 /auth/login으로 전체 페이지 이동한다. 로컬 오버라이드(VITE_API_SERVER_URL) 상태에서는 LOCAL로 표시하고 전환을 비활성화한다. 로그인 전에도 환경을 고를 수 있도록 루트 레이아웃에 마운트했다.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (13)
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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10e7dcc0e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| clearSession(); | ||
| saveAdminApiEnvironment(next); | ||
| redirect("/auth/login"); |
There was a problem hiding this comment.
Preserve the selected environment through the login check
When the target environment has no refresh cookie, this redirect opens /auth/login, whose effect immediately calls ensureSessionToken(); the failed reissue calls clearSession(), removes the just-saved adminApiEnvironment, and leaves the login form defaulting to PROD. Consequently, an administrator cannot perform the intended first login to STAGE because every switch is undone before credentials are submitted; skip that reissue check after switching or avoid clearing the explicit environment selection on reissue failure.
Useful? React with 👍 / 👎.
| useEffect(() => { | ||
| setEnvironment(resolveDisplayedEnvironment()); | ||
|
|
||
| const handleStorageChange = () => setEnvironment(resolveDisplayedEnvironment()); |
There was a problem hiding this comment.
Reload other tabs when the stored environment changes
When the admin console is open in multiple tabs and one tab switches environments, this handler only changes the badge in the other tabs. Their mounted pages and React Query caches remain populated with data from the old environment, while subsequent requests resolve their base URL from the newly stored environment and the shared access token has been removed, so an old-environment view can issue mutations against the new environment; the storage handler should force the same reload/cache reset used by the initiating tab.
Useful? React with 👍 / 👎.
요약
이메일 기반 환경 판별 로직(#615, #616)을 제거하고, 우하단 플로팅 버튼으로 어드민이 stage/prod API 환경을 명시적으로 전환할 수 있도록 했습니다. 어드민 배포를 main 브랜치 하나로 통합하는 작업(#618)의 후속입니다.
관련 이슈: #615, #616, #618
동작 방식
confirm다이얼로그로 재확인 → 세션 초기화 후 새 환경 값 저장 →/auth/login으로 전체 페이지 이동 (react-query 캐시 등 메모리 상태를 확실히 비우기 위한 하드 리다이렉트)ensureSessionToken()이 새로 저장된 환경 기준으로 reissue를 시도합니다. 해당 환경에 유효한 refresh 쿠키가 있으면 자동 로그인되고, 없으면 로그인 폼이 표시됩니다.dev→stage로 전환했습니다. 레거시로 저장돼 있던"dev"값은"stage"로 해석하여 하위 호환을 유지합니다.VITE_API_SERVER_URL로 로컬 오버라이드가 설정된 경우 FAB은LOCAL표시와 함께 비활성화됩니다(전환 불가).행동 변화 (주의)
기존에는 로그인 이메일이 dev 계정 패턴이면 자동으로 stage API로 라우팅됐지만, 이제는 그렇지 않습니다. 로그인 전에 FAB으로 원하는 환경을 먼저 선택해야 합니다. 기본값은 PROD입니다.
리뷰 반영 (2차 커밋)
EnvironmentBanner.tsx와EnvironmentSwitcherFab.tsx에 복붙돼 있던environmentStyles/environmentLabels/resolveDisplayedEnvironment/DisplayedEnvironment타입을apps/admin/src/components/layout/environmentDisplay.ts공용 모듈로 추출하여 드리프트 위험 제거 (렌더 결과 동일)environment.test.ts에 섞여 있던switchAdminApiEnvironment테스트(대상:./session)를session.test.ts로 분리,environment.test.ts에는getApiBaseUrlForEnvironment테스트만 남기고 불필요해진 mock/hoisted 선언 정리실사용 버그 수정 (3차 커밋)
STAGE로 전환 후 로그인하면 요청이 여전히 prod(
https://api.solid-connection.com/admin/auth/sign-in)로 나가는 문제가 실사용 중 발견되어 수정했습니다.재현 순서
clearSession()→saveAdminApiEnvironment("stage")→/auth/login이동 (여기까지는 정상)/auth/login마운트 시ensureSessionToken()이 자동 실행되어 reissue를 시도 (stage로 정상 요청)reissueAccessTokenIfPossible의 catch가clearSession()을 호출 → 이 안에 있던removeAdminApiEnvironment()가 방금 저장한"stage"값을 지워버림resolveActiveApiBaseUrl()이 저장값을 못 찾고 prod로 폴백 → prod로 로그인 요청이 나감근본 원인:
clearSession()이 환경 저장 키까지 함께 지우는 동작은 환경이 로그인 이메일에서 파생되던 #615 시절의 잔재였습니다. 지금은 환경이 FAB으로 관리하는 독립적인 사용자 선택이므로, 로그아웃/401/reissue 실패 등 세션 정리 경로에서도 살아남아야 합니다.수정 내용
apps/admin/src/lib/auth/session.ts:clearSession()에서removeAdminApiEnvironment()호출 제거(관련 import 정리). 이제 세션 정리는 access token만 지우고 환경 선택은 건드리지 않습니다.switchAdminApiEnvironment의 JSDoc도 더 이상 사실이 아닌 "clearSession이 환경 키까지 지우므로 순서가 중요하다"는 설명을 제거하고 실제 동작만 남겼습니다.apps/admin/src/lib/utils/localStorage.ts: 더 이상 쓰이지 않는removeAdminApiEnvironment함수 자체를 삭제.apps/admin/src/lib/auth/session.test.ts: 기존 순서 검증 테스트를 걷어내고, **"저장된 어드민 API 환경 값은 clearSession() 이후에도 유지된다"**는 회귀 테스트를 추가(실제 jsdom localStorage로 검증).apps/admin/src/lib/utils/localStorage.test.ts: 삭제된removeAdminApiEnvironment관련 테스트 제거.검증
🤖 Generated with Claude Code