d3ro-voice/packages/core
윤찬 46b77f1118 feat(desktop): SaaS [5] 티어 enforcement — 로컬 해방 + 클라우드 gate (빅뱅 Phase 4)
비즈니스 모델 확정:
- 익명 로컬 사용자 → 로컬 기능 16개 전부 무제한 (entry point)
- 클라우드 기능 (PREMIUM_LLM, CLOUD_SYNC) → 로그인 필수
- 로그인 free → PREMIUM_LLM 5/일, CLOUD_SYNC 허용
- 로그인 pro → PREMIUM_LLM 500/일 (fair use cap)
- 로그인 pro_plus → PREMIUM_LLM 무제한

기존 정책 폐기:
- DICTATION 20/일 quota 삭제
- LLM_PROCESS 10/일 quota 삭제
- LIVE_CAPTION/VOICE_MEMO/SCREEN_CONTEXT/VOICE_COMMAND/LLM_CHAIN
  pro lock 해제 → free
- FILE_TRANSCRIPTION/VOICE_CONVERSATION/DICTATION_TEMPLATE/
  MEETING_SUMMARY/LOCAL_RAG/OS_AUTOMATION pro_plus lock 해제 → free

types.ts:
- Feature enum: PREMIUM_LLM, CLOUD_SYNC 추가
- FeatureAccess.reason: 'login_required' 추가

LicenseService.ts:
- QUOTA_LIMITS / FEATURE_MIN_TIER 전면 재작성
- CLOUD_FEATURES Set 신규
- canUse(): CLOUD_FEATURES && isLocalMode() → login_required 조기 반환
- syncFromCloud(tier): Supabase subscriptions 티어를
  electron-store에 캐시 + tier-changed emit
- resetToFree(): 로그아웃 시 pro/pro_plus 캐시 + 라이센스 필드 전부 null
- isLocalMode() import 추가

CloudSyncService.ts:
- _fetchSubscriptionTier(userId): subscriptions 테이블에서 활성 티어 조회
  (row 없음 / 비정상 값 → free 폴백)
- _onAuthenticated: DB open → tier fetch → syncFromCloud → auth-changed → Realtime
- _onSignOut: Voice/Meeting/Caption stop → Realtime stop → auth.signOut →
  token clear → license.resetToFree → closeCurrent → openLocal → emit null

검증:
- desktop tsc --noEmit 
- desktop npm run build 
- 로컬 사용자 모든 기존 기능 접근 가능 (pro lock 완전 제거)
2026-04-11 10:23:50 +09:00
..
src feat(desktop): SaaS [5] 티어 enforcement — 로컬 해방 + 클라우드 gate (빅뱅 Phase 4) 2026-04-11 10:23:50 +09:00
package.json feat(V2-1b): packages/core 추출 — 공유 타입/에러/채널/유틸 분리 2026-04-08 14:39:46 +09:00
tsconfig.json feat(V2-1b): packages/core 추출 — 공유 타입/에러/채널/유틸 분리 2026-04-08 14:39:46 +09:00