fix(desktop): CloudSync Realtime 자동 재구독 + Refresh token 실패 재인증 알림 (U1+U3, 빅뱅 Phase 5 Part 6)

## U1 — Realtime TIMED_OUT 자동 재구독

CloudSyncService.startRealtime()의 subscribe() 콜백이 TIMED_OUT 한 번만
로깅하고 끝나던 것을 지수 백오프 재구독으로 교체.
- SUBSCRIBED: retry count reset + timer clear
- TIMED_OUT / CHANNEL_ERROR / CLOSED: _scheduleRealtimeRetry() 트리거
- 백오프: 1s → 3s → 10s (MAX 3회)
- 초과 시 warn 로깅 후 포기 (Auto push fallback으로만 동작)
- stopRealtime()에서 타이머/카운터 cleanup

Publication, RLS, setAuth 모두 설정 완료 상태에서도 매 기동 시 TIMED_OUT이
찍히는 증상. 근본 원인은 Supabase 서버 transient(네트워크/WebSocket
타임아웃) 의심. 이 패치로 완전 해결은 아니지만 일시적 네트워크 jitter
복구 윈도우를 확보하고, 3회 실패 시 명확한 포기 메시지를 남긴다.

## U3 — Refresh token 실패 시 재인증 이벤트

init()의 refreshSession 실패 브랜치에서 warn 로깅 + 토큰 삭제만 수행해
사용자가 "왜 로그아웃됐지?" 상태로 방치되던 문제.
- logger.warn → logger.error(에러 레벨 승격)
- sync-error 이벤트 emit (사용자에게 보여줄 메시지 포함)
- auth-changed { user: null } emit (renderer 게이트 재잠금)
- catch 브랜치도 동일 처리 (기존엔 로깅만)

## U4 — package-lock.json optional dep (유지 결정)

rollup 전 플랫폼 optional deps가 lock에 기록돼 있지만 Windows 빌드자
사전 fetch 효율 + 크로스플랫폼 CI 환경을 고려해 유지. apps/desktop/
package.json:56에 @rollup/rollup-win32-x64-msvc 명시 의존이 있는 이유도
동일. 이 이슈는 확인 후 close.
This commit is contained in:
윤찬 2026-04-11 23:24:22 +09:00
parent dd591d06e7
commit dc7f93349e
2 changed files with 108 additions and 2 deletions

View file

@ -3,6 +3,38 @@
> 마지막 갱신: 2026-04-11 (빅뱅 Phase 5 Part 6 — Voice Conversation 몰입 패널 구현)
> 규칙 13: 작업 완료 즉시 이 파일 갱신 의무
## 빅뱅 Phase 5 Part 6++ (2026-04-11) — U1/U3/U4 남은 이슈 정리 ✅
### U1 — Realtime TIMED_OUT 자동 재구독 (CloudSyncService.ts)
Publication/RLS/setAuth 모두 설정 완료 상태에서도 매 기동 시 `TIMED_OUT`이 찍히는 증상. 근본 원인은 Supabase 서버 측 transient(네트워크/WebSocket 타임아웃) 의심으로 판정. Auto push(Phase 3.3) fallback이 완벽히 동작해 블로커는 아니지만, 다른 기기에서의 원격 변경 pull을 놓치는 window가 생김.
**변경**: `subscribe()` 콜백에 지수 백오프 자동 재구독 추가.
- `SUBSCRIBED` → retry count reset + 타이머 클리어
- `TIMED_OUT` / `CHANNEL_ERROR` / `CLOSED``_scheduleRealtimeRetry()`
- 백오프: 1s → 3s → 10s, 3회 초과 시 포기하고 경고 로그(Auto push로만 동작)
- `stopRealtime()`에서 타이머 cleanup + count reset
### U3 — Refresh token 실패 시 재인증 이벤트 emit (CloudSyncService.ts)
`init()``refreshSession` 실패 브랜치에서 기존에는 `warn` 로깅 + 토큰 삭제만 수행 → 사용자는 "왜 로그아웃됐지?" 상태로 방치. 재현이 쉽지 않지만 장시간 idle 후 발생 가능성 있어 예방적 개선.
**변경**:
- `logger.warn``logger.error`(에러 레벨 승격)
- `sync-error` 이벤트 emit (`"Sign-in session expired. Please sign in again."`)
- `auth-changed { user: null }` emit (renderer 게이트 재잠금)
- `try/catch`의 catch 브랜치도 동일 처리 (기존에는 로깅만)
### U4 — package-lock optional dep (확인 후 유지 결정)
`package-lock.json`에 rollup의 전 플랫폼 `optionalDependencies`(darwin/win32/linux/freebsd/android)가 기록돼 있음. Mac `npm install --force` 시 win32 관련 경고가 나왔지만 런타임 영향 없음. `apps/desktop/package.json:56``@rollup/rollup-win32-x64-msvc`가 명시적 의존으로 선언되어 있는 이유는 Windows 빌드자가 사전에 binding을 확보하기 위함.
**결정**: **유지**. 크로스플랫폼 개발/CI 효율 + Win 빌드자 경험을 우선. 향후 lock 재생성 시에도 선택적 제거 불필요. 이 이슈는 **close**.
### 변경 파일 (2)
- `apps/desktop/src/main/services/CloudSyncService.ts` — U1 재구독 + U3 재인증 이벤트
- `memory/project_status.md` — 본 섹션
## 빅뱅 Phase 5 Part 6+ (2026-04-11) — U7 AudioCaptureService Mac 분기 ✅
`AudioCaptureService.getDevices()``powershell -NoProfile`만 호출하던 것을