chore: 빅뱅 사이클 wrap-up — 핸드오프 + 상세 다음 세션 프롬프트

이번 세션에서 한 일:
- Mac 부트스트랩 + Supabase llnocwyqvhgwpdjcqqyw 배포
- V2-6차 고도화 [W][A~D] (웹 테마/Mermaid/오디오/Dashboard 차트)
- V2-6차 데스크톱 안정화 [E~L] (Mac 단축키, sidecar venv, beep, paste, qwen3 등)
- SaaS [1] 빌드 타임 Supabase env 주입 (electron.vite + ConfigService)
- SaaS [2] OAuth 첫 실행 강제 게이트 (LoginScreen + AuthGate + saasMode)

다음 세션 (빅뱅 사이클):
- memory/big-bang-prompt.md: 사용자가 다음 세션에 그대로 붙여넣을 상세 프롬프트
- Phase 1: 사용자별 SQLite 격리 (필수)
- Phase 2: 회원가입/온보딩 흐름 (profiles.onboarded_at)
- Phase 3: cloud-first 정책 (write queue + Supabase source of truth)
- Phase 4: 티어 enforcement (free quota)
- Phase 5: 데스크톱/웹/모바일 데이터 일원화 검증
- Phase 6: wrap-up

핸드오프:
- 이전 handoff-latest.md를 archive/2026-04-10-2300-windows-to-mac.md로 이동
- 새 handoff-latest.md: 이번 세션 결과 + 다음 세션 시작 명령
- project_status.md: SaaS 데스크톱 클라이언트 1차 섹션 추가
This commit is contained in:
윤찬 2026-04-11 09:45:20 +09:00
parent dd1c3054dd
commit 5ad1d19c3a
4 changed files with 616 additions and 145 deletions

View file

@ -135,6 +135,52 @@ V2 6차 고도화 (2026-04-11):
- [K] 🐛 fix(desktop): macOS 텍스트 붙여넣기 — `TextInsertService._insertViaClipboard``nut.Key.LeftControl + V` 하드코딩이라 macOS에서는 paste 안 됨 (Cmd+V여야). `pasteModKey = process.platform === 'darwin' ? LeftSuper : LeftControl` 분기. 잘못된 클립보드 검증("text 그대로면 정상") 로직 제거 (macOS는 Ctrl+V가 noop이라 항상 거짓 양성). macOS는 paste 후 sleep 250ms.
- [L] 🐛 fix(desktop): qwen3 reasoning 39초 + 빈 응답 — qwen3:4b는 reasoning model이라 응답에 `<think>...</think>` 블록을 길게 출력, 본문이 비어 _completeSession("")로 paste 호출 안 됨. SYSTEM_PROMPTS 전체에 `/no_think` 토큰 추가 (qwen3 비활성화, 다른 모델은 무시). `stripReasoningBlocks()` 추가 — `<think>`/`<thinking>` 태그 안전망. `processText`가 stripped 결과 길이 0이면 원본 transcript fallback + warn 로그.
## SaaS 데스크톱 클라이언트 1차 (2026-04-11)
> 사용자 표현: "설계가 잘못된 것 같다"
> 실제 상황: 백엔드/웹/모바일은 100% multi-tenant SaaS, 데스크톱만 V1 single-user 잔재로
> 사용자가 Settings에서 Supabase URL/Key를 직접 입력해야 하는 UX였음.
> Notion/Linear/Slack 데스크톱 패턴으로 정정.
### SaaS [1] 빌드 타임 Supabase env 주입
- `electron.vite.config.ts`: `defineConfig(({ mode }) => ...)`로 변경, `loadEnv(mode, cwd, 'D3RO_')`
`.env.local` 자동 로드 → main 번들에 `define`으로 inline 박음
- `apps/desktop/.env.local` 생성 (gitignored): `D3RO_SUPABASE_URL`, `D3RO_SUPABASE_ANON_KEY`
- `apps/desktop/env.example` 템플릿 (committed)
- `ConfigService`:
- `BUILD_TIME_SUPABASE_URL` / `BUILD_TIME_SUPABASE_ANON_KEY` 상수 (process.env에서 읽음)
- `isSupabaseBuildTimeConfigured()` 헬퍼 export
- `configGet('supabaseUrl'/'supabaseAnonKey')`은 빌드 타임 값 절대 우선
- `configSet`는 빌드 타임 모드일 때 supabaseUrl/AnonKey 변경 거부
### SaaS [2] OAuth 첫 실행 강제 게이트
- `CloudSyncState``saasMode: boolean` 필드 추가
- `LoginScreen.tsx` 신규: Google/GitHub 버튼만, MetalCard + PhosphorText, URL/Key 입력 노출 0
- `App.tsx` `AuthGate` 상태머신: `loading | login-required | authenticated | legacy`
- `saasMode && !authenticated` → LoginScreen 강제
- `saasMode && authenticated` → 기존 AppLayout
- `!saasMode` → legacy (기존 동작 유지)
- `onAuthChanged` 구독으로 로그인 후 자동 전환
- `CloudSyncSection` (Settings 안):
- `saasMode`일 때 URL/Key 입력 필드 완전 숨김 (OAuth 버튼만)
- `!saasMode` (legacy)일 때만 기존 입력 화면 유지
- 검증: 이전엔 항상 떴던 `CloudSync disabled — Supabase URL/key not configured` 로그 사라짐
### SaaS [3] 사용자별 SQLite 격리 — **다음 세션(빅뱅) 예정**
## 빅뱅 다음 세션 목표 (2026-04-11 wrap-up)
데스크톱을 진짜 SaaS 클라이언트로 완성. 자세한 계획 + 단계별 prompt는
`memory/handoff-latest.md` 참조.
핵심:
1. 사용자별 SQLite 격리 (`userData/users/${userId}/d3ro.db`)
2. 회원가입/온보딩 흐름 — OAuth 첫 가입 시 환영 + 기본 설정
3. cloud-first 정책 — Supabase가 source of truth, 로컬 cache는 read-through
4. 멀티 디바이스 sync 강화 (Realtime + last-write-wins → CRDT 검토)
5. 결제/티어 enforcement (free 일일 quota, 데스크톱에서도 차단)
6. 회의/지식 web ↔ 데스크톱 일원화
## SaaS 아키텍처 진단 (2026-04-11)
> 사용자 우려: "single-user로 잘못 만들어진 것 같다"