server/supabase/ 신규 디렉토리:
config.toml — Supabase CLI 설정
- 프로젝트 ID, DB 포트, auth providers (Google/GitHub/Apple),
edge_runtime, functions.*.verify_jwt 설정
migrations/ (PostgreSQL DDL, 시간순):
- 20260409000001_initial_schema.sql
12개 테이블: profiles, teams, team_members, meetings,
meeting_memos, meeting_documents, transcripts, history,
dictionary, memo_tags, daily_usage, subscriptions
+ 인덱스 + FK CASCADE + transcripts Realtime publication
- 20260409000002_rls_policies.sql
개인 전용(history/dictionary): user_id = auth.uid()
팀 공유(meetings 등): 본인 OR team_members 조회 subquery
daily_usage: 읽기만, 쓰기는 service_role RPC
- 20260409000003_auth_triggers.sql
handle_new_user — auth.users INSERT → profiles+subscriptions 자동 생성
moddatetime — 8개 테이블 updated_at 자동 갱신
increment_daily_usage — service_role 전용 쿼터 RPC
- 20260409000004_storage_buckets.sql
audio/exports/avatars 3개 버킷 + 경로 기반 접근 정책
(파일 경로가 {user_id}/...로 시작해야 쓰기 허용)
functions/ (Deno/TypeScript Edge Functions):
- _shared/cors.ts — CORS 헤더 + preflight 핸들러
- _shared/auth.ts — requireUser (JWT 검증 + User 반환)
- _shared/quota.ts — 티어별 쿼터 체크 + consume + service role client
- stt-proxy/index.ts — Google Cloud STT 래퍼 스캐폴딩
placeholder 응답, 실제 API 호출 코드는 주석으로 포함
- llm-proxy/index.ts — Anthropic Messages API 래퍼 스캐폴딩
티어별 허용 모델 정책 (free=Haiku, pro=Sonnet, team=Opus)
설계 문서:
- docs/v2/phase-V2-2.md — 상세 설계 (스키마/RLS/Edge Functions/Realtime)
- docs/v2/phase-V2-2-setup.md — 사용자 액션 가이드 (Supabase 계정/
OAuth 등록/CLI/배포/검증)
apps/desktop typecheck 통과 (server/는 Deno 런타임이라 별도).
실제 Supabase 프로젝트 배포는 사용자가 phase-V2-2-setup.md 따라 수행.
12 KiB
12 KiB
D3RO-VOICE 프로젝트 현황
마지막 갱신: 2026-04-08 규칙 13: 작업 완료 즉시 이 파일 갱신 의무
현재 단계
V1 (Electron) 완료 → V2 (Monorepo) 진행 중
- Phase V2-1 ✅ 완료 (Monorepo 전환 — a/b/c/d)
- Phase V2-2 🟡 로컬 작업 완료, 사용자 액션 대기
- SQL 마이그레이션 4개 파일 + Edge Functions 2개 스캐폴딩 작성 완료
- Supabase 프로젝트 생성/OAuth 등록/배포는 사용자가 직접 수행
- 가이드:
docs/v2/phase-V2-2-setup.md
- 다음: Phase V2-3 (Web App MVP — Next.js)
V1 완료 페이즈
| Phase | 내용 | 상태 |
|---|---|---|
| 1~9 | 기본 음성 어시스턴트 (STT/LLM/TTS/핫키/팝업) | ✅ |
| 10 | Killer features (메모, 보이스 커맨드, 스크린 컨텍스트, 체인, 캡션) | ✅ |
| 11 | Monetization (라이선스, 쿼터) | ✅ |
| 12 | Pro features (파일 전사, 회의 요약, 딕테이션 템플릿) | ✅ |
| 13 | 음성 대화, RAG, 보이스 액션 | ✅ |
| 14 | 회의 모드 | ✅ |
| 14.5 | 회의 고도화 (다중 문서 생성/편집/내보내기) | ✅ |
| 15 | Auto Polish + AI 채팅 + 마인드맵 + 공유 | ✅ |
| 15.5 | 화자 구분 (LLM 추정 + pyannote) | ✅ |
추가 개선사항 (post-15.5)
- 히스토리/회의 목록 반응형 그리드 + 카드 UI
- 설정 LLM 모델 드롭다운
- 오디오 테스트 실시간 레벨 미터
- Ollama 미실행 시 설치 경로 탐색 후 자동 스폰 (2026-04-08)
V2 진행 상황
Phase V2-1: Monorepo + Core 추출 — 진행 중
| Sub-phase | 범위 | 상태 |
|---|---|---|
| V2-1a | npm workspaces + apps/desktop으로 V1 이동 | ✅ 완료 |
| V2-1b | packages/core 추출 (types, errors, ipc-channels, constants, utils) | ✅ 완료 |
| V2-1c | packages/ui 추출 (DS 컴포넌트 + theme + theme-vars) | ✅ 완료 |
| V2-1d | packages/i18n 추출 (locale JSON + 훅) | ✅ 완료 |
V2-1d 완료 내역
packages/i18n/(@d3ro/i18n) 신규 생성:src/locales/12개 JSON (ko/en/ja/zh/zh-TW/es/fr/de/pt/ru/vi/th)src/index.tsx: TFunction, Locale, LOCALE_META, resolveTranslation, createFormatDate/Number/RelativeDate/Time, I18nContext, useI18n, I18nProvider
- Electron 독립성 확보:
I18nStorageinterface 추가 (load/save 어댑터)- 기존
window.electronAPI.config직접 호출 →storageprop 주입 패턴 - 기본값은 noopStorage (메모리 한정)
- 기존
apps/desktop/src/renderer/App.tsx에electronI18nStorage어댑터 구현 후<I18nProvider storage={electronI18nStorage}>로 주입- apps/desktop 설정:
@d3ro/i18n: "*"dep 추가- tsconfig paths, vite alias, externalize exclude에
@d3ro/i18n추가
- 일괄 치환:
./i18n,../i18n,../../i18n→@d3ro/i18n(29 파일) apps/desktop/src/renderer/i18n/디렉토리 완전 제거
V2-1d 검증
- typecheck ✅
- build ✅
- dev 런타임 ✅ (DB/핫키/Ollama/Main window 모두 정상)
- Electron 의존이 완전히 apps/desktop에만 남아 monorepo 원칙 준수 (packages/i18n은 React에만 의존, 웹/모바일에서 그대로 재사용 가능)
V2-1c 완료 내역
packages/ui/(@d3ro/ui) 신규 생성:src/theme.ts(d3roPalette/d3roTypo/d3roShadow SSOT 전체)src/theme-vars.ts(팝업/main 프로세스용 CSS 변수 맵)src/components/ds/{CrtDisplay, InstrumentPanel, Led, MetalCard, MetalDial, PhosphorText, PhysicalButton, ScreenPanel, ButtonGroup, index}.tsxsrc/index.tsbarrel
packages/ui/package.json: React/MUI/Emotion은 peerDependencies,@d3ro/core만 직접 depapps/desktop/src/shared/디렉토리 완전 제거 (theme-vars가 마지막이었음)- subpath exports:
./theme,./theme-vars,./components/ds - DS 컴포넌트 내부
../../theme상대 경로는 그대로 유효 (packages/ui 내부에서 해결) - 일괄 치환:
../theme,../../theme,./theme→@d3ro/ui/theme../components/ds,../../components/ds,./ds,../ds→@d3ro/ui/components/ds../ds/<Component>,../../ds/<Component>→@d3ro/ui/components/ds(세부 파일 import는 barrel로 통합)@shared/theme-vars→@d3ro/ui/theme-vars(WindowManager 1건)
apps/desktop/tsconfig.node/web.json:@shared/*paths 완전 제거,@d3ro/ui,@d3ro/ui/*paths 추가,include에서src/shared/**/*제거electron.vite.config.ts:@sharedalias 제거,@d3ro/uialias 추가, externalize exclude에@d3ro/ui추가vitest.config.ts: alias 교체
V2-1c 검증
typecheck✅build✅dev런타임 ✅ (DB/핫키/Ollama/Main window 정상)apps/desktop/src/shared/디렉토리 자체가 사라져@shared/*는 이제 프로젝트에 존재하지 않음
V2-1b 완료 내역
packages/core/패키지 신규:@d3ro/core, subpath exports (types/errors/ipc-channels/constants/utils/*), docx dep 포함- 6개 파일
git mv로packages/core/src/로 이동:apps/desktop/src/shared/{types,errors,ipc-channels,constants}.tsapps/desktop/src/main/utils/{meeting-markdown,markdown-to-docx}.ts
packages/core/src/index.tsbarrel export 추가apps/desktop/package.json에"@d3ro/core": "*"dep 추가apps/desktop/tsconfig.node.json,tsconfig.web.json의paths에@d3ro/core/*추가,@shared/*는 theme-vars용으로 유지apps/desktop/electron.vite.config.tsalias 3개 섹션에@d3ro/core추가 + M1 수정:resolve('src/shared')→resolve(__dirname, 'src/shared')externalizeDepsPluginexclude에@d3ro/core추가 (main/preload 둘 다)apps/desktop/vitest.config.ts에@d3ro/corealias 추가- 일괄 치환:
@shared/{types,errors,ipc-channels,constants}→@d3ro/core/*(사용자 79개 파일, 167건)- static import (
from '@shared/...') - dynamic import (
import('@shared/...')) - type expression import (
keyof import('@shared/...').AppConfig)
- static import (
MeetingModeService.ts의 상대 경로 utils import (../utils/meeting-markdown,../utils/markdown-to-docx)를@d3ro/core/utils/*로 교체packages/core내부 자기 참조:meeting-markdown.ts의@shared/types→../types상대 경로
V2-1b 검증
npm run typecheck✅npm run build✅ (main+preload+renderer)npm run dev런타임 실행 ✅ (DB/핫키/Ollama 모두 정상)apps/desktop/src/shared/에는theme-vars.ts1개만 남음 (V2-1c에서 이동 예정)
V2-1a 완료 내역
- 루트
package.json을 npm workspaces 루트로 재구성 (workspaces: apps/, packages/) turbo.json,tsconfig.base.json추가 (Turborepo 자체 설치는 뒤로 미룸)- V1 파일 전체를
apps/desktop/으로git mv:- src/, resources/, tests/, sidecar/, scripts/
- electron.vite.config.ts, electron-builder.yml, vitest.config.ts
- tsconfig.node.json, tsconfig.web.json (+ 새 tsconfig.json)
apps/desktop/package.json신규 (name: "@d3ro/desktop", 기존 deps 그대로)@electron/rebuild --version=33.4.11로 native 모듈 재빌드 (better-sqlite3, uiohook-napi)- 루트 tsconfig.json → apps/desktop references 형태
V2-1a 결정사항
- 패키지 매니저: npm workspaces 유지 (pnpm 전환은 별도 sub-phase)
- 이유: Turborepo는 npm workspaces와 호환, 구조 이동과 PM 전환을 동시에 하면 롤백 불가
- site/: 루트 유지 (랜딩 페이지, V2 무관)
- docs/, memory/, CLAUDE.md: 루트 유지
- productName: "d3ro-voice" 필수 — package name을
@d3ro/desktop으로 바꾸면 Electron의app.getName()이 바뀌어 userData 경로가%APPDATA%\@d3ro\desktop\으로 이동(기존 DB/설정 유실).productName을 명시하면app.getName()이 이를 우선 반환하여%APPDATA%\d3ro-voice\그대로 유지됨.
검증 결과
npm run typecheck✅npm run build✅ (electron-vite main+preload+renderer)npm run dev✅ 실제 실행 → DB 경로d3ro-voice/로 복원, 기존 핫키(Alt keyCode=2) 로드, Ollama 자동 실행 감지 모두 정상npm run dist(electron-builder installer)은 V2-1 완료 후 별도 검증
Phase V2-2: Supabase 인프라 — 로컬 작업 완료
작성된 파일 (server/supabase/)
config.toml— Supabase CLI 설정 (로컬 + OAuth providers)migrations/20260409000001_initial_schema.sql— 12개 테이블 (profiles, teams, team_members, meetings, meeting_memos, meeting_documents, transcripts, history, dictionary, memo_tags, daily_usage, subscriptions) + 인덱스 + FK CASCADEmigrations/20260409000002_rls_policies.sql— 개인/팀 이중 RLS 패턴migrations/20260409000003_auth_triggers.sql—handle_new_user(profiles + subscriptions 자동 생성),moddatetime(8개 테이블 updated_at 트리거),increment_daily_usage(service_role 전용 쿼터 RPC)migrations/20260409000004_storage_buckets.sql— audio/exports/avatars 버킷 + 경로 기반 정책functions/_shared/— cors.ts, auth.ts (requireUser), quota.ts (티어별 쿼터)functions/stt-proxy/index.ts— Google Cloud STT 래퍼 스캐폴딩 (placeholder 응답)functions/llm-proxy/index.ts— Anthropic Messages API 래퍼 스캐폴딩 (티어별 모델 정책)seed.sql— 개발 시드 (빈 상태).gitignore— .branches/, .temp/, .env
설계 문서
docs/v2/phase-V2-2.md— 상세 설계 (스키마/RLS/Edge Functions/실시간/Storage)docs/v2/phase-V2-2-setup.md— 사용자 액션 가이드 (Supabase 계정/OAuth/CLI/배포)
사용자 액션 대기 중 (로컬 외 작업)
- Supabase 프로젝트 생성 (https://supabase.com)
supabase login && supabase link --project-ref <REF>supabase db push(4개 마이그레이션 적용)- Google/GitHub OAuth 앱 등록 + Supabase Auth Providers 설정
- Google Cloud STT 키 + Anthropic API 키 발급
supabase secrets set+supabase functions deploy
설계 결정사항
- UUID PK: V1은 nanoid(text), V2는 PostgreSQL
gen_random_uuid(). V2-4 (동기화)에서 기존 SQLite 데이터는 nanoid 유지, 새 데이터는 UUID. - timestamptz: V1은 epoch ms(integer), V2는
timestamptz. V2-4 동기화 시 타입 변환 필요. - 멀티테넌시: 모든 테이블에
user_id. 회의 관련 테이블은team_idnullable 추가. - RLS 이중 패턴: 개인 전용(history/dictionary)은 단순
user_id = auth.uid(). 팀 공유(meetings)는 본인 ORteam_members조회 subquery. - 쿼터 집계:
increment_daily_usageRPC는SECURITY DEFINER+service_roleonly. 일반 유저는 읽기만. - Realtime:
transcripts테이블만supabase_realtimepublication에 추가 (회의 중 세그먼트 동기화 용). - Edge Functions placeholder: 인증/쿼터 파이프라인은 완성, 실제 AI API 호출은 주석 처리된 실제 구현 코드 포함. V2-3 (Web MVP) 진행 전까지 유지.
Phase V2-3~V2-8: 미착수
Web App MVP, 데스크톱 동기화, Mac 빌드, Mobile App, 팀 기능, 결제/출시
알려진 차단/이슈
- @nut-tree-fork/nut-js 포크 사용 (V1 잔여 이슈)
- Ollama 의존성: 없으면 LLM 기능 사용 불가 (2026-04-08 자동 실행 기능 추가로 UX 개선)
디렉토리 구조 (V2-1a 목표)
d3ro-voice/ # 루트 (monorepo)
├── apps/
│ └── desktop/ # 기존 V1 전체
│ ├── src/
│ ├── resources/
│ ├── build/
│ ├── package.json # name: @d3ro/desktop
│ ├── electron.vite.config.ts
│ ├── electron-builder.yml
│ ├── tsconfig*.json
│ └── drizzle.config.ts
├── packages/ # V2-1b/c/d에서 채움
├── site/ # 랜딩 페이지 (루트 유지)
├── docs/ # 설계서/페이즈 문서
├── memory/ # 이 파일
├── pnpm-workspace.yaml # 또는 package.json "workspaces"
├── turbo.json
├── package.json # 루트 workspace
├── tsconfig.base.json
└── CLAUDE.md