백엔드가 중복 로그인 감지를 넣으면서, 내 토큰이 밀리면 이후 모든 요청이
403 + code 905(만료된 토큰입니다)로 떨어진다(JwtAuthenticationFilter).
어느 화면·어느 API에서 걸리든 같은 결말이어야 해서 backendFetch 한 곳에서
처리한다.
- 905/904를 받으면 /logout/revoked로 보낸다. 렌더 중에는 쿠키를 지울 수 없어
라우트 핸들러에서 세션을 파기하고 /login으로 안내와 함께 되돌린다.
- redirect()는 예외로 던져지므로 Server Action의 catch가 삼키면 안 된다.
저장소를 호출하는 catch에 unstable_rethrow를 넣어 통과시킨다.
- 그 경로는 쿠키가 이미 없어도 지나가야 안내가 유지돼 proxy 공개 경로에 넣는다.
Co-Authored-By: Claude Opus 5
개발 모드 Strict Mode(App Router 기본값)의 effect mount→cleanup→remount 2회 호출로
쿼리 파라미터 감지 토스트가 두 번 뜨는 것을 실제 브라우저 검증 중 확인했다. cleanup 없는
effect라 가드가 없으면 매 remount마다 showToast가 재실행된다. hasNotifiedRef로 최초
1회만 실행되도록 고정한다 — 사용자에게 보이는 알림은 Strict Mode 유무와 무관하게 항상
1회여야 한다.
Co-Authored-By: Claude Opus 5
로그아웃 Server Action이 백엔드 호출 실패를 /login?logoutError=1로 알리면, 새 클라이언트
컴포넌트 LogoutNotice가 마운트 시 기존 FeedbackProvider/Toast로 경고 토스트를 띄우고
쿼리 파라미터를 제거한다. redirect()는 Server Action에서 즉시 던져져 클라이언트가 결과를
돌려받을 수 없으므로, 토스트 표시를 목적지 페이지 마운트 이후로 미뤄 redirect와 경쟁하지
않게 한다. 내부 백엔드 메시지는 노출하지 않고 고정 문구만 보여준다.
Co-Authored-By: Claude Opus 5