공개 문서
docs/design-saas-engine.md
아래는 docs/design-saas-engine.md 와 동일한 원문입니다. Markdown과 HTML 변환 결과를 각각 복사할 수 있습니다.
공개 문서 원문 (Markdown)
# saas-engine 설계도
**문서**: 설계도 (아키텍처·구조·기술 방향)
**프로젝트**: saas-engine
**참조**: `docs/reference/notion-saas.md`
---
## 1. 목적·범위
- **목적**: 로그인·인증·결제·구독·사용량·제한을 담당하는 **재사용 가능한 SaaS 엔진**과, 이를 조합한 **기능 모듈·앱**을 한 저장소에서 관리한다.
- **범위**: 엔진(engine) + 기능(features) + 앱(apps). 메인 배포 단위는 루트 Next.js 앱이며, 추후 `apps/` 하위 앱으로 분리 가능.
---
## 2. 아키텍처 개요
```
┌─────────────────────────────────────────────────────────────────┐
│ 루트 Next.js 앱 │
│ (app/, lib/, proxy) — /login, /dashboard, /pricing, /checkout │
└─────────────────────────────┬───────────────────────────────────┘
│ re-export & 호출
▼
┌─────────────────────────────────────────────────────────────────┐
│ engine/ │ SaaS 인프라 (인증·결제·구독·사용량·제한·비용가드) │
├───────────────────┼─────────────────────────────────────────────┤
│ features/ │ 제품 기능 모듈 (Gemini 채팅, 이미지 생성 등) │
├───────────────────┼─────────────────────────────────────────────┤
│ apps/ │ 별도 SaaS 앱 (gemini-saas, image-saas 등) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Supabase (Auth + DB + RLS) │ 외부: Polar(결제), Gemini API 등 │
└─────────────────────────────────────────────────────────────────┘
```
---
## 3. 레이어별 설계
### 3.1 engine/ — SaaS 엔진
| 모듈 | 역할 | 데이터/API | 상태 |
|------|------|------------|------|
| **auth** | 인증, 세션, OAuth, 사용자 프로필 | Supabase Auth, `public.users` | ✅ 적용 완료 |
| **usage** | 사용량·쿼터 조회·증가 | `public.usage`, RPC `increment_usage` | ✅ 적용 완료 |
| **billing** | 결제·청구 (Polar 등) | Polar Checkout·`lib/polar.ts`·`/api/checkout` | 🔶 앱·lib 구현됨; `engine/billing` 이관은 `structure-improvement-plan` Phase 3 |
| **subscription** | 구독 플랜·상태 | `public.subscriptions`, 웹훅, `/api/subscription` | 🔶 앱·lib 구현됨; `engine/subscription` 이관은 Phase 3 |
| **rate-limit** | 요청 빈도 제한 | 메모리/Redis 등 | 예정 |
| **cost-guard** | 비용 상한 가드 | 사용량·비용 집계 | 예정 |
- **auth**: `engine/auth` — client/server Supabase, `getSession`, `signInWithGoogle`/`signInWithKakao`, `getCurrentUser`. 앱은 `@/lib/auth`, `@/lib/supabaseClient`, `@/lib/user`로 re-export 사용.
- **usage**: `engine/usage` — `checkUsageLimit`, `incrementUsage`, 기간(period) 단위 집계. Gemini 채팅 등 기능에서 호출.
### 3.2 features/ — 기능 모듈
| 모듈 | 역할 | 의존 엔진 | 상태 |
|------|------|------------|------|
| **gemini-chat** | AI 채팅, 대화 저장, 히스토리 | auth, usage | ✅ 구현 중/적용 |
| **image-generator** | 이미지 생성 기능 | auth, usage, rate-limit | 스캐폴드 |
| **automation** | 자동화 플로우 | auth, usage | 스캐폴드 |
- 기능 모듈은 engine을 import하여 사용. 앱은 features를 조합해 라우트·API 구현.
### 3.3 apps/ — SaaS 앱
| 앱 | 설명 | 상태 |
|----|------|------|
| **gemini-saas** | Gemini 래퍼 SaaS (채팅 중심) | 예정/부분 |
| **image-saas** | 이미지 생성 SaaS | 예정 |
- 현재는 **루트 Next.js 앱**이 메인 배포 단위. 필요 시 `apps/gemini-saas` 등을 별도 진입점으로 분리.
### 3.4 데이터베이스 (Supabase)
- **public.users**: Auth 트리거로 동기화 (`001_create_users_and_trigger.sql`, `002_sync_existing_users.sql`).
- **public.conversations**, **public.messages**: Gemini 채팅 대화·메시지 (`003_gemini_chat_tables.sql`).
- **public.usage**: 사용량 집계 (user_id, feature, period, request_count, total_tokens). RPC `increment_usage`로 원자적 증가 (`004_increment_usage_rpc.sql`).
- **subscriptions** (예정): Polar 웹훅 등으로 구독 플랜·상태 저장.
---
## 4. 기술 스택
| 구분 | 기술 |
|------|------|
| 프레임워크 | Next.js (App Router), TypeScript |
| 인증·DB | Supabase (Auth, Postgres, RLS) |
| 결제(예정) | Polar (Notion 튜토리얼 기준) |
| AI | Gemini API (채팅 등) |
| 배포 | Vercel |
| 스타일 | Tailwind CSS |
---
## 5. 앱–엔진 연동 규칙
- **인증**: `@/lib/auth`, `@/lib/supabaseClient`, `@/lib/user` — 모두 `engine/auth` re-export. 기존 로그인 플로우 유지.
- **미들웨어**: `engine/auth`의 `createServerSupabase(request, response)` 사용.
- **사용량**: API 라우트에서 `engine/usage`의 `checkUsageLimit`·`incrementUsage` 호출 (예: `/api/chat`).
---
## 6. 보안·운영 원칙
- **RLS**: 모든 사용자 데이터 테이블에 RLS 적용, `auth.uid()` 기준 정책.
- **API 키**: 서버 전용 키는 `NEXT_PUBLIC_` 미사용. `.env.local` / `.env.example` 규칙 준수.
- **시크릿**: `docs/reference/notion-saas.md` 및 워크스페이스 env 규칙 준수.
---
## 7. 문서 참조
- **기획·요구사항**: `docs/reference/notion-saas.md`
- **워크스페이스 구조**: `docs/workspace-structure.md`
- **인증·DB**: `docs/user-database-sync.md`, `docs/auth-gate-report.md`, `docs/supabase-google-oauth-setup.md`
공개 문서 변환 코드 (HTML)
<h1>saas-engine 설계도</h1>
<p><strong>문서</strong>: 설계도 (아키텍처·구조·기술 방향)<br><strong>프로젝트</strong>: saas-engine<br><strong>참조</strong>: <code>docs/reference/notion-saas.md</code></p>
<hr>
<h2>1. 목적·범위</h2>
<ul>
<li><strong>목적</strong>: 로그인·인증·결제·구독·사용량·제한을 담당하는 <strong>재사용 가능한 SaaS 엔진</strong>과, 이를 조합한 <strong>기능 모듈·앱</strong>을 한 저장소에서 관리한다.</li>
<li><strong>범위</strong>: 엔진(engine) + 기능(features) + 앱(apps). 메인 배포 단위는 루트 Next.js 앱이며, 추후 <code>apps/</code> 하위 앱으로 분리 가능.</li>
</ul>
<hr>
<h2>2. 아키텍처 개요</h2>
<pre><code>┌─────────────────────────────────────────────────────────────────┐
│ 루트 Next.js 앱 │
│ (app/, lib/, proxy) — /login, /dashboard, /pricing, /checkout │
└─────────────────────────────┬───────────────────────────────────┘
│ re-export & 호출
▼
┌─────────────────────────────────────────────────────────────────┐
│ engine/ │ SaaS 인프라 (인증·결제·구독·사용량·제한·비용가드) │
├───────────────────┼─────────────────────────────────────────────┤
│ features/ │ 제품 기능 모듈 (Gemini 채팅, 이미지 생성 등) │
├───────────────────┼─────────────────────────────────────────────┤
│ apps/ │ 별도 SaaS 앱 (gemini-saas, image-saas 등) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Supabase (Auth + DB + RLS) │ 외부: Polar(결제), Gemini API 등 │
└─────────────────────────────────────────────────────────────────┘
</code></pre>
<hr>
<h2>3. 레이어별 설계</h2>
<h3>3.1 engine/ — SaaS 엔진</h3>
<table>
<thead>
<tr>
<th>모듈</th>
<th>역할</th>
<th>데이터/API</th>
<th>상태</th>
</tr>
</thead>
<tbody><tr>
<td><strong>auth</strong></td>
<td>인증, 세션, OAuth, 사용자 프로필</td>
<td>Supabase Auth, <code>public.users</code></td>
<td>✅ 적용 완료</td>
</tr>
<tr>
<td><strong>usage</strong></td>
<td>사용량·쿼터 조회·증가</td>
<td><code>public.usage</code>, RPC <code>increment_usage</code></td>
<td>✅ 적용 완료</td>
</tr>
<tr>
<td><strong>billing</strong></td>
<td>결제·청구 (Polar 등)</td>
<td>Polar Checkout·<code>lib/polar.ts</code>·<code>/api/checkout</code></td>
<td>🔶 앱·lib 구현됨; <code>engine/billing</code> 이관은 <code>structure-improvement-plan</code> Phase 3</td>
</tr>
<tr>
<td><strong>subscription</strong></td>
<td>구독 플랜·상태</td>
<td><code>public.subscriptions</code>, 웹훅, <code>/api/subscription</code></td>
<td>🔶 앱·lib 구현됨; <code>engine/subscription</code> 이관은 Phase 3</td>
</tr>
<tr>
<td><strong>rate-limit</strong></td>
<td>요청 빈도 제한</td>
<td>메모리/Redis 등</td>
<td>예정</td>
</tr>
<tr>
<td><strong>cost-guard</strong></td>
<td>비용 상한 가드</td>
<td>사용량·비용 집계</td>
<td>예정</td>
</tr>
</tbody></table>
<ul>
<li><strong>auth</strong>: <code>engine/auth</code> — client/server Supabase, <code>getSession</code>, <code>signInWithGoogle</code>/<code>signInWithKakao</code>, <code>getCurrentUser</code>. 앱은 <code>@/lib/auth</code>, <code>@/lib/supabaseClient</code>, <code>@/lib/user</code>로 re-export 사용.</li>
<li><strong>usage</strong>: <code>engine/usage</code> — <code>checkUsageLimit</code>, <code>incrementUsage</code>, 기간(period) 단위 집계. Gemini 채팅 등 기능에서 호출.</li>
</ul>
<h3>3.2 features/ — 기능 모듈</h3>
<table>
<thead>
<tr>
<th>모듈</th>
<th>역할</th>
<th>의존 엔진</th>
<th>상태</th>
</tr>
</thead>
<tbody><tr>
<td><strong>gemini-chat</strong></td>
<td>AI 채팅, 대화 저장, 히스토리</td>
<td>auth, usage</td>
<td>✅ 구현 중/적용</td>
</tr>
<tr>
<td><strong>image-generator</strong></td>
<td>이미지 생성 기능</td>
<td>auth, usage, rate-limit</td>
<td>스캐폴드</td>
</tr>
<tr>
<td><strong>automation</strong></td>
<td>자동화 플로우</td>
<td>auth, usage</td>
<td>스캐폴드</td>
</tr>
</tbody></table>
<ul>
<li>기능 모듈은 engine을 import하여 사용. 앱은 features를 조합해 라우트·API 구현.</li>
</ul>
<h3>3.3 apps/ — SaaS 앱</h3>
<table>
<thead>
<tr>
<th>앱</th>
<th>설명</th>
<th>상태</th>
</tr>
</thead>
<tbody><tr>
<td><strong>gemini-saas</strong></td>
<td>Gemini 래퍼 SaaS (채팅 중심)</td>
<td>예정/부분</td>
</tr>
<tr>
<td><strong>image-saas</strong></td>
<td>이미지 생성 SaaS</td>
<td>예정</td>
</tr>
</tbody></table>
<ul>
<li>현재는 <strong>루트 Next.js 앱</strong>이 메인 배포 단위. 필요 시 <code>apps/gemini-saas</code> 등을 별도 진입점으로 분리.</li>
</ul>
<h3>3.4 데이터베이스 (Supabase)</h3>
<ul>
<li><strong>public.users</strong>: Auth 트리거로 동기화 (<code>001_create_users_and_trigger.sql</code>, <code>002_sync_existing_users.sql</code>).</li>
<li><strong>public.conversations</strong>, <strong>public.messages</strong>: Gemini 채팅 대화·메시지 (<code>003_gemini_chat_tables.sql</code>).</li>
<li><strong>public.usage</strong>: 사용량 집계 (user_id, feature, period, request_count, total_tokens). RPC <code>increment_usage</code>로 원자적 증가 (<code>004_increment_usage_rpc.sql</code>).</li>
<li><strong>subscriptions</strong> (예정): Polar 웹훅 등으로 구독 플랜·상태 저장.</li>
</ul>
<hr>
<h2>4. 기술 스택</h2>
<table>
<thead>
<tr>
<th>구분</th>
<th>기술</th>
</tr>
</thead>
<tbody><tr>
<td>프레임워크</td>
<td>Next.js (App Router), TypeScript</td>
</tr>
<tr>
<td>인증·DB</td>
<td>Supabase (Auth, Postgres, RLS)</td>
</tr>
<tr>
<td>결제(예정)</td>
<td>Polar (Notion 튜토리얼 기준)</td>
</tr>
<tr>
<td>AI</td>
<td>Gemini API (채팅 등)</td>
</tr>
<tr>
<td>배포</td>
<td>Vercel</td>
</tr>
<tr>
<td>스타일</td>
<td>Tailwind CSS</td>
</tr>
</tbody></table>
<hr>
<h2>5. 앱–엔진 연동 규칙</h2>
<ul>
<li><strong>인증</strong>: <code>@/lib/auth</code>, <code>@/lib/supabaseClient</code>, <code>@/lib/user</code> — 모두 <code>engine/auth</code> re-export. 기존 로그인 플로우 유지.</li>
<li><strong>미들웨어</strong>: <code>engine/auth</code>의 <code>createServerSupabase(request, response)</code> 사용.</li>
<li><strong>사용량</strong>: API 라우트에서 <code>engine/usage</code>의 <code>checkUsageLimit</code>·<code>incrementUsage</code> 호출 (예: <code>/api/chat</code>).</li>
</ul>
<hr>
<h2>6. 보안·운영 원칙</h2>
<ul>
<li><strong>RLS</strong>: 모든 사용자 데이터 테이블에 RLS 적용, <code>auth.uid()</code> 기준 정책.</li>
<li><strong>API 키</strong>: 서버 전용 키는 <code>NEXT_PUBLIC_</code> 미사용. <code>.env.local</code> / <code>.env.example</code> 규칙 준수.</li>
<li><strong>시크릿</strong>: <code>docs/reference/notion-saas.md</code> 및 워크스페이스 env 규칙 준수.</li>
</ul>
<hr>
<h2>7. 문서 참조</h2>
<ul>
<li><strong>기획·요구사항</strong>: <code>docs/reference/notion-saas.md</code></li>
<li><strong>워크스페이스 구조</strong>: <code>docs/workspace-structure.md</code></li>
<li><strong>인증·DB</strong>: <code>docs/user-database-sync.md</code>, <code>docs/auth-gate-report.md</code>, <code>docs/supabase-google-oauth-setup.md</code></li>
</ul>