d3ro-voice/docs/v2/phase-V2-2-setup.md
yunchan8804 97eb886ec3 feat(V2-2): Supabase 인프라 — 스키마 + RLS + Edge Functions 스캐폴딩
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 따라 수행.
2026-04-08 15:21:08 +09:00

6.3 KiB

Phase V2-2: Supabase 인프라 — 사용자 설정 가이드

이 문서는 사용자가 로컬 밖에서 수행해야 하는 작업만 안내합니다. 로컬 코드 변경(SQL 마이그레이션, Edge Functions 스캐폴딩)은 이미 server/supabase/에 포함되어 있습니다.


1. Supabase 계정/프로젝트 생성

  1. https://supabase.com 접속 → Sign in with GitHub (권장)
  2. New project 클릭
    • Name: d3ro-voice
    • Database Password: 강력한 비밀번호 (1Password 등에 저장)
    • Region: ap-northeast-2 (Seoul) 권장
    • Pricing Plan: Free (시작 후 Pro로 업그레이드 가능)
  3. 프로젝트 생성 완료(~2분) 후 대시보드 접속

2. API 키 확인 (Settings → API)

다음 4개 값을 메모:

용도 노출 범위
Project URL SUPABASE_URL — 모든 클라이언트 공개 가능
anon public SUPABASE_ANON_KEY — 클라이언트 읽기/쓰기 (RLS 보호) 공개 가능
service_role SUPABASE_SERVICE_ROLE_KEY — 서버 전용 (RLS 우회) 절대 공개 금지
Project Ref CLI 연동용 공개 가능

3. Supabase CLI 설치

Windows

scoop install supabase
# 또는
winget install Supabase.CLI

macOS

brew install supabase/tap/supabase

4. 로컬 프로젝트 연결

cd D:/workspace/voice

# Supabase 계정 로그인 (브라우저 열림)
supabase login

# 원격 프로젝트와 연결 (Project Ref 필요)
cd server/supabase
supabase link --project-ref <YOUR_PROJECT_REF>

5. 마이그레이션 푸시

# server/supabase/migrations/* 를 원격에 적용
supabase db push

실행 결과:

  • 20260409000001_initial_schema.sql — 테이블/인덱스 생성
  • 20260409000002_rls_policies.sql — RLS 정책
  • 20260409000003_auth_triggers.sql — handle_new_user, moddatetime
  • 20260409000004_storage_buckets.sql — storage 버킷 + 정책

검증: Studio → Database → Tables에서 12개 테이블 확인

6. OAuth Provider 등록

6.1 Google OAuth

  1. https://console.cloud.google.com → 프로젝트 생성 (d3ro-voice)
  2. APIs & ServicesCredentialsCreate CredentialsOAuth client ID
  3. Application type: Web application
  4. Authorized redirect URIs:
    • https://<YOUR_PROJECT_REF>.supabase.co/auth/v1/callback
  5. Client IDClient Secret 복사
  6. Supabase 대시보드 → Authentication → Providers → Google
    • Enable 체크
    • Client ID / Client Secret 입력 → Save

6.2 GitHub OAuth

  1. GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
  2. Homepage URL: https://d3ro.dev
  3. Authorization callback URL: https://<YOUR_PROJECT_REF>.supabase.co/auth/v1/callback
  4. Client ID, Client Secret 복사 → Supabase Authentication → Providers → GitHub

6.3 Apple OAuth (선택, 나중에 가능)

Apple Developer Program 계정 필요. iOS 출시 전에 등록. 가이드: https://supabase.com/docs/guides/auth/social-login/auth-apple

7. Edge Functions 배포

cd server/supabase

# 시크릿 설정 (배포 전)
supabase secrets set GOOGLE_CLOUD_STT_KEY=<google_api_key>
supabase secrets set ANTHROPIC_API_KEY=<anthropic_api_key>

# 함수 배포
supabase functions deploy stt-proxy
supabase functions deploy llm-proxy

배포 후 호출 URL:

  • https://<YOUR_PROJECT_REF>.supabase.co/functions/v1/stt-proxy
  • https://<YOUR_PROJECT_REF>.supabase.co/functions/v1/llm-proxy

7.1 AI API 키 발급

Google Cloud STT:

  1. Google Cloud Console → API & Services → Library → Speech-to-Text API → Enable
  2. Credentials → Create API Key (Speech-to-Text API로 제한 권장)
  3. 빌링 활성화 필요 ($300 free credit)

Anthropic API:

  1. https://console.anthropic.com → API Keys → Create Key
  2. 최소 $5 credit 충전

8. 환경변수 관리

8.1 로컬 개발 (.env)

루트에 .env.local 생성 (.gitignore되어 있음):

# Supabase
VITE_SUPABASE_URL=https://<YOUR_PROJECT_REF>.supabase.co
VITE_SUPABASE_ANON_KEY=<anon_public_key>

# apps/web (Phase V2-3에서 사용)
NEXT_PUBLIC_SUPABASE_URL=https://<YOUR_PROJECT_REF>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon_public_key>

# Edge Functions 로컬 개발용 (server/supabase/.env)
GOOGLE_CLOUD_STT_KEY=<google_api_key>
ANTHROPIC_API_KEY=<anthropic_api_key>

8.2 프로덕션 (Supabase Dashboard)

  • Supabase 내부 시크릿: supabase secrets set KEY=value
  • Vercel/Netlify 등 호스팅: 각 플랫폼의 환경변수 설정 페이지 사용

9. 검증 체크리스트

  • Studio에서 12개 테이블 확인 (profiles, teams, team_members, meetings, meeting_memos, meeting_documents, transcripts, history, dictionary, memo_tags, daily_usage, subscriptions)
  • Authentication → Users에서 첫 테스트 유저 로그인 가능
  • 테스트 유저 로그인 후 profiles 테이블에 자동 행 생성됨 (handle_new_user 트리거 동작)
  • subscriptions 테이블에도 tier=free 행 자동 생성
  • Storage → 3개 버킷 (audio/exports/avatars) 확인
  • Edge Functions → stt-proxy, llm-proxy 배포 상태 확인
  • Edge Functions 호출 테스트 (curl 또는 Studio의 Invoke):
    curl -X POST https://<YOUR_PROJECT_REF>.supabase.co/functions/v1/llm-proxy \
      -H "Authorization: Bearer <user_jwt>" \
      -H "Content-Type: application/json" \
      -d '{"messages":[{"role":"user","content":"hi"}]}'
    
    "[llm-proxy placeholder ...]" 응답이 오면 인증/쿼터 체인 정상

10. 다음 페이즈와의 연결

V2-2가 완료되면:

  • V2-3 (Web MVP): NEXT_PUBLIC_SUPABASE_* 환경변수로 Next.js 앱이 백엔드 연결
  • V2-4 (데스크톱 동기화): VITE_SUPABASE_*로 Electron 앱이 백엔드 연결
  • Edge Functions의 placeholder를 실제 Google STT / Anthropic API 호출로 교체

11. 문제 해결

supabase db push 시 FK 오류: → 기존 스키마가 있으면 supabase db reset (주의: 데이터 삭제) 또는 수동 drop 후 재시도

RLS로 인해 INSERT 차단: → auth.uid()가 null이면 정책 통과 못함. 반드시 로그인된 클라이언트에서 호출

Edge Function 배포 후 500 에러: → supabase functions logs stt-proxy로 런타임 에러 확인. 대부분 시크릿 미설정