bookquote

화면 설계 — 인증 콜백 /auth/callback · /callback (이미 구현 — 역정리 + 개선 권고)

그룹 3. 입력 근거: lib/features/auth/auth_callback_screen.dart, lib/app/deep_link_handler.dart, lib/app/router.dart(코드 기준). 게스트 라우트. transient(매직링크 클릭 직후 잠깐).

1. 목적 / 진입·이탈 / 라우트

2. 와이어프레임

┌─────────────────────────┐
│                         │
│         ◌               │  CircularProgressIndicator(color: accent500)
│      로그인 중…          │
│                         │  (권고: 8초+ 경과 시 "조금 더 걸리고 있어요…" / 12초에
│                         │   "링크에 문제가 있는 것 같아요 [다시 로그인]")
└─────────────────────────┘

3. 상태 (코드 기준)

| 상태 | 처리 | 심각도 | |—|—|—| | isSupabaseReady == false | 다음 프레임에 context.go('/auth/login') (키 미주입 빌드 방어) | 낮음 | | isSupabaseReady == true | Timer(10s, () { if (mounted) context.go('/auth/login'); }) — 10초 안전망. dispose에서 _timeout?.cancel() | — | | 세션 교환 (웹) | Supabase.initializedetectSessionInUri가 URL ?code= 자동 감지·교환 → SIGNED_IN 이벤트 → _redirectfrom ?? '/'로 | — | | 세션 교환 (모바일) | DeepLinkHandlerapp_links 스트림 받아 supabase.auth.getSessionFromUrl(uri). handler _handle(uri): uri.path.startsWith('/auth/callback') 또는 uri.host == 'auth' 또는 uri.toString().contains('code=') 아니면 무시. 맞으면 getSessionFromUrl try/catch(실패 시 debugPrint만) | — | | 10초 경과 | 세션 안 옴 → /auth/login. 이유 안내 없음 — 만료된/이미 쓴 링크인지 느린 네트워크인지 구분 X | 중간 (개선) | | DeepLinkHandler.start() | kIsWeb이면 no-op, !isSupabaseReady면 return, 중복 시작 방지. getInitialLink()(콜드스타트) + uriLinkStream.listen(_handle) | — |

4. 인터랙션

5. 토큰 매핑

6. 재사용 / 신규

7. 엣지 / 접근성 + 수정·보강 항목

교차 관심사: ⑦ 게스트 라우트(isAuthPath) · ② deep link payload 보존(아래 ②). 양호(유지): 웹/모바일 양쪽 처리 · isSupabaseReady 분기 · _callback 별도 라우트(URI 파싱 함정 회피) · _timeout cancel on dispose. 수정·보강 권고 (현행 ≠ 권고):

변경 이력