d3ro-voice/apps/desktop
윤찬 dd1c3054dd feat(desktop): SaaS [1+2] 빌드 타임 env + OAuth 강제 로그인 게이트
배경:
사용자가 데스크톱 앱 Settings에서 직접 Supabase URL/Key를 입력해야 했음.
SaaS 데스크톱(Notion/Linear/Slack) 패턴에서는 사용자가 OAuth 로그인만 하면 끝이고
연결 정보는 빌드 타임에 박혀있어야 함. V1 single-user 잔재로 인한 UX 결함이었고
사용자가 'SaaS 설계가 잘못된 것 같다'고 우려할 만한 명확한 흠집.

[1] 빌드 타임 Supabase env 주입
- electron.vite.config.ts: defineConfig가 mode 받아 loadEnv('D3RO_') 호출
  - .env, .env.local 자동 로드 (vite/electron-vite 표준)
  - main 번들에 process.env.D3RO_SUPABASE_URL/ANON_KEY를 inline define으로 박음
- ConfigService:
  - BUILD_TIME_SUPABASE_URL / BUILD_TIME_SUPABASE_ANON_KEY 상수
  - isSupabaseBuildTimeConfigured() / getBuildTimeSupabase{Url,AnonKey}() 헬퍼
  - configGet('supabaseUrl'/'supabaseAnonKey')는 빌드 타임 값을 절대 우선
  - configSet은 빌드 타임 모드일 때 supabaseUrl/AnonKey 변경 거부 (덮어쓰기 방지)
- apps/desktop/.env.local 생성 (gitignored, llnocwyqvhgwpdjcqqyw 프로젝트)
- apps/desktop/env.example 템플릿 (committed)

[2] OAuth 첫 실행 강제 게이트
- CloudSyncState에 saasMode: boolean 필드 추가 (CloudSyncService.getState)
- LoginScreen.tsx 신규: Google/GitHub 버튼만 노출 (URL/Key 입력 필드 없음)
  - MetalCard + PhosphorText D3RO 디자인 시스템
  - i18n 키 재사용 (login.subtitle/google/github/terms)
- App.tsx에 AuthGate 추가:
  - cloudSync.getState로 saasMode + authenticated 조회
  - status: 'loading' | 'login-required' | 'authenticated' | 'legacy'
  - saasMode이고 인증 안 됨 → LoginScreen 강제
  - saasMode이고 인증 됨 → 기존 AppLayout
  - saasMode 아님 → 'legacy' (기존 동작 유지, 개발자가 .env.local 설정 안 한 경우)
  - onAuthChanged 구독으로 로그인 직후 자동 전환
- CloudSyncSection (Settings 안):
  - saasMode일 때 URL/Key 입력 필드 완전 숨김 (OAuth 버튼만)
  - !saasMode (legacy)일 때만 기존 입력 화면 유지

검증:
- typecheck OK
- dev 재시작 시 'CloudSync disabled — Supabase URL/key not configured' 로그 사라짐
  → 빌드 타임 env가 정상적으로 ConfigService에 주입되어 client 생성됨
- 첫 실행 시 사용자가 보는 화면 = LoginScreen (Google/GitHub만)
2026-04-11 09:38:12 +09:00
..
build feat(V2-5): macOS 빌드 지원 — 플랫폼 분기 + electron-builder mac 타겟 + CI 2026-04-08 15:57:16 +09:00
resources feat(V2-5): macOS 빌드 지원 — 플랫폼 분기 + electron-builder mac 타겟 + CI 2026-04-08 15:57:16 +09:00
scripts feat(V2-5): macOS 빌드 지원 — 플랫폼 분기 + electron-builder mac 타겟 + CI 2026-04-08 15:57:16 +09:00
sidecar feat(V2-1a): Monorepo 구조 전환 — apps/desktop으로 V1 이동 2026-04-08 14:04:41 +09:00
src feat(desktop): SaaS [1+2] 빌드 타임 env + OAuth 강제 로그인 게이트 2026-04-11 09:38:12 +09:00
tests feat(V2-1a): Monorepo 구조 전환 — apps/desktop으로 V1 이동 2026-04-08 14:04:41 +09:00
electron-builder.yml feat(V2-5): macOS 빌드 지원 — 플랫폼 분기 + electron-builder mac 타겟 + CI 2026-04-08 15:57:16 +09:00
electron.vite.config.ts feat(desktop): SaaS [1+2] 빌드 타임 env + OAuth 강제 로그인 게이트 2026-04-11 09:38:12 +09:00
env.example feat(desktop): SaaS [1+2] 빌드 타임 env + OAuth 강제 로그인 게이트 2026-04-11 09:38:12 +09:00
package.json feat(V2-4): 데스크톱 ↔ Supabase 동기화 (push only MVP) 2026-04-09 16:28:19 +09:00
tsconfig.json feat(V2-1a): Monorepo 구조 전환 — apps/desktop으로 V1 이동 2026-04-08 14:04:41 +09:00
tsconfig.node.json feat(V2-1d): packages/i18n 추출 — Electron 독립 i18n 엔진 2026-04-08 14:57:27 +09:00
tsconfig.web.json feat(V2-1d): packages/i18n 추출 — Electron 독립 i18n 엔진 2026-04-08 14:57:27 +09:00
vitest.config.ts feat(V2-1d): packages/i18n 추출 — Electron 독립 i18n 엔진 2026-04-08 14:57:27 +09:00