[imgompanda/drsaju-opensource] AI Coding Agent Guide — 닥터사주 (Dr.Saju)
Claude
API Leak/Claude
13,607 characters
# AI Coding Agent Guide — 닥터사주 (Dr.Saju)
> **사용법**: AI 코딩 도구(Claude Code, Cursor, Windsurf 등)에 이 파일을 컨텍스트로 전달하세요.
> "이 프로젝트 셋업해줘" 또는 "이 프로젝트 분석해줘"라고 말하면 됩니다.
>
> **For AI Agents**: This is your project configuration. Read it before making any changes.
---
## 프로젝트 개요
**닥터사주(Dr.Saju)** — AI 기반 사주팔자/자미두수/서양점성술 분석 서비스
- 전통 만세력 계산은 TypeScript 코드로, 해석은 Google Gemini AI로 처리
- MIT 라이선스 오픈소스
### 핵심 원칙
```
"계산은 코드, 해석은 AI"
```
---
## 기술 스택
| 영역 | 기술 | 버전 |
|------|------|------|
| 프레임워크 | Next.js (App Router) | 16 |
| 언어 | TypeScript | 5 |
| 인증 + DB | Supabase | - |
| AI | Vercel AI SDK + Google Gemini | ai@6 |
| PDF | @react-pdf/renderer | 4 |
| 결제 | Paddle | - |
| UI | shadcn/ui + Tailwind CSS | 4 |
| 만세력 | manseryeok (MIT) | 1 |
| i18n | next-intl | 4 |
| 상태관리 | Zustand | 5 |
---
## 프로젝트 구조
```
src/
├── app/
│ ├── [locale]/ # 다국어 라우팅 (ko, en, ja, zh)
│ │ ├── page.tsx # 랜딩 페이지
│ │ ├── chat/[characterId]/ # AI 캐릭터 채팅
│ │ ├── reading/[id]/ # 사주 분석 결과
│ │ ├── my-readings/ # 내 분석 목록
│ │ ├── coin-shop/ # 코인 상점
│ │ ├── saju-report/ # PDF 리포트
│ │ ├── invite/[code]/ # 초대 링크
│ │ ├── (auth)/login/ # 로그인
│ │ ├── (marketing)/ # 약관, 개인정보보호
│ │ └── refund-policy/ # 환불 정책
│ ├── api/saju/ # 사주 API (8개 엔드포인트)
│ │ ├── analyze/ # AI 종합 분석
│ │ ├── chat/ # AI 채팅
│ │ ├── compatibility/ # 궁합 분석
│ │ ├── pdf/[id]/ # PDF 생성
│ │ ├── preview/ # 미리보기
│ │ ├── suggestions/ # AI 제안
│ │ ├── deduct-stars/ # 별 차감
│ │ └── update-status/ # 상태 업데이트
│ ├── api/webhooks/paddle/ # Paddle 결제 웹훅
│ └── auth/callback/ # OAuth 콜백
├── components/
│ ├── saju/ # 사주 전용 컴포넌트
│ │ ├── chat/ # 채팅 (ChatRoom, ChatBubble, ChatInput 등)
│ │ ├── input/ # 입력 (BirthDateForm, ConcernSelector 등)
│ │ ├── result/ # 결과 (FullAnalysis, MonthlyFortuneGrid 등)
│ │ ├── landing/ # 랜딩 (Navbar, Footer, FAQ, Testimonials)
│ │ ├── payment/ # 결제 (PaddleCheckout, PaymentSuccess)
│ │ ├── preview/ # 미리보기 (FiveElementChart, PaywallOverlay)
│ │ ├── share/ # 공유 (KakaoShareButton, ShareCard)
│ │ ├── layout/ # 레이아웃 (SajuLayout, MobileLayoutWrapper)
│ │ └── referral/ # 소개 (ReferralSection)
│ ├── ui/ # shadcn/ui 기본 컴포넌트 (34개)
│ └── shared/ # 공용 (Header, Footer, ThemeProvider 등)
├── lib/
│ ├── saju/ # 핵심 사주 엔진
│ │ ├── saju-engine.ts # 사주팔자 계산 (getFourPillars, calculateSaju 등)
│ │ ├── ziwei.ts # 자미두수 (createChart, calculateLiunian 등)
│ │ ├── natal.ts # 서양 점성술 (calculateNatal)
│ │ ├── advanced-analysis.ts # 고급 분석 (세운, 자미두수, 점성술 통합)
│ │ ├── calculator.ts # 수치 계산 보조
│ │ ├── characters.ts # 8가지 AI 캐릭터 데이터
│ │ ├── cities.ts # 도시 DB (진태양시 계산용)
│ │ ├── true-solar-time.ts # 진태양시 보정
│ │ ├── prompts.ts # AI 프롬프트 템플릿
│ │ ├── ai/analyzer.ts # Gemini AI 분석 호출
│ │ ├── pdf/saju-template.tsx # PDF 리포트 템플릿
│ │ └── referral.ts # 소개 시스템
│ ├── paddle/ # Paddle 결제 (client, config, webhook)
│ ├── ai/ # AI 모델 초기화
│ ├── analytics/ # 분석 트래킹
│ ├── discord/ # Discord 알림
│ └── resend/ # 이메일 (Resend)
├── services/ # 서버 액션 (saju, auth, analytics, email, referral)
├── store/saju.ts # Zustand 상태
├── types/saju.ts # 핵심 타입 정의
├── utils/supabase/ # Supabase 클라이언트 (client, server, admin)
├── i18n/ # 국제화 설정
└── middleware.ts # Next.js 미들웨어
messages/ # 다국어 메시지 (ko.json, en.json, ja.json, zh.json)
public/characters/ # 캐릭터 이미지 (31개)
public/fonts/ # NotoSansKR 폰트 (PDF용)
```
---
## 셋업 가이드 (순서대로)
### Step 1: 기본 설치
```bash
git clone https://github.com/imgompanda/drsaju-opensource.git
cd drsaju-opensource
npm install
cp .env.example .env.local
```
### Step 2: Supabase 설정 (필수)
1. https://supabase.com 에서 프로젝트 생성
2. Project URL, anon key, service role key 복사
3. `.env.local`에 입력:
```env
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbG...
SUPABASE_SERVICE_ROLE_KEY=eyJhbG...
```
4. Supabase에서 Google OAuth 설정:
- Authentication → Providers → Google 활성화
- Google Cloud Console에서 OAuth 2.0 Client ID 생성
- Redirect URL: `https://xxxxx.supabase.co/auth/v1/callback`
5. DB 테이블 생성 (Supabase SQL Editor에서 실행):
```sql
-- 사주 분석 결과 테이블
create table saju_readings (
id uuid default gen_random_uuid() primary key,
user_id uuid references auth.users(id),
birth_year int not null,
birth_month int not null,
birth_day int not null,
birth_hour int,
birth_minute int,
gender text not null,
city_name text,
concern_type text,
status text default 'pending',
analysis jsonb,
created_at timestamptz default now()
);
-- 채팅 메시지 테이블
create table chat_messages (
id uuid default gen_random_uuid() primary key,
user_id uuid references auth.users(id),
reading_id uuid references saju_readings(id),
character_id text not null,
role text not null,
content text not null,
created_at timestamptz default now()
);
-- 사용자 별(크레딧) 테이블
create table user_stars (
user_id uuid references auth.users(id) primary key,
balance int default 0,
updated_at timestamptz default now()
);
-- RLS 활성화
alter table saju_readings enable row level security;
alter table chat_messages enable row level security;
alter table user_stars enable row level security;
-- RLS 정책
create policy "Users can read own readings" on saju_readings for select using (auth.uid() = user_id);
create policy "Users can insert own readings" on saju_readings for insert with check (auth.uid() = user_id);
create policy "Users can update own readings" on saju_readings for update using (auth.uid() = user_id);
create policy "Users can read own messages" on chat_messages for select using (auth.uid() = user_id);
create policy "Users can insert own messages" on chat_messages for insert with check (auth.uid() = user_id);
create policy "Users can read own stars" on user_stars for select using (auth.uid() = user_id);
create policy "Users can update own stars" on user_stars for update using (auth.uid() = user_id);
```
### Step 3: Google Gemini API 키 (필수)
1. https://aistudio.google.com/apikey 에서 API 키 생성
2. `.env.local`에 입력:
```env
GOOGLE_GENERATIVE_AI_API_KEY=AIza...
```
### Step 4: 개발 서버 실행
```bash
npm run dev
```
http://localhost:3000 에서 확인. 이 단계에서 사주 계산 + AI 분석이 작동합니다.
### Step 5: Paddle 결제 (선택)
결제 기능이 필요한 경우:
1. https://sandbox-vendors.paddle.com 에서 Sandbox 계정 생성
2. 상품/가격 생성 (예: 별 30개 = 9,900원)
3. `.env.local`에 입력:
```env
PADDLE_API_KEY=pdl_sbox_...
PADDLE_WEBHOOK_SECRET=pdl_ntfset_...
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=test_...
NEXT_PUBLIC_PADDLE_ENVIRONMENT=sandbox
NEXT_PUBLIC_PADDLE_PRODUCT_STAR_30=pro_...
NEXT_PUBLIC_PADDLE_PRICE_STAR_30=pri_...
```
4. Paddle 웹훅 URL: `https://your-domain.com/api/webhooks/paddle`
### Step 6: 이메일 (선택)
```env
RESEND_API_KEY=re_...
```
### Step 7: 배포
```bash
# Vercel 배포
npx vercel
# 환경변수를 Vercel에도 설정하세요
```
---
## 커스터마이징 가이드
### 캐릭터 수정/추가
파일: `src/lib/saju/characters.ts`
```typescript
// 캐릭터 데이터 구조
{
id: 'doctor',
name: '닥터사주',
description: '정통 사주 전문가',
personality: '...',
avatarPath: '/characters/doctor.png',
cardPath: '/characters/doctor-card.png',
}
```
새 캐릭터 추가 시:
1. `characters.ts`에 데이터 추가
2. `public/characters/`에 아바타/카드 이미지 추가
3. `src/types/saju.ts`의 `CharacterType`에 ID 추가
### AI 프롬프트 수정
파일: `src/lib/saju/prompts.ts`
사주 분석의 톤, 깊이, 형식을 조절합니다. AI가 생성하는 분석 내용의 품질에 직접 영향을 줍니다.
### AI 모델 변경
파일: `src/lib/ai/model.ts`
Gemini → GPT-4, Claude 등으로 변경 가능. Vercel AI SDK가 여러 프로바이더를 지원합니다.
```typescript
// Gemini → OpenAI 변경 예시
import { openai } from '@ai-sdk/openai';
export const model = openai('gpt-4o');
```
### 결제 상품 변경
파일: `src/lib/paddle/config.ts`
상품 ID, 가격, 별(크레딧) 수량을 환경변수로 관리합니다.
### 랜딩 페이지 수정
파일: `src/app/[locale]/page.tsx` + `src/components/saju/landing/`
- `SajuNavbar.tsx` — 상단 네비게이션
- `CharacterCards.tsx` — 캐릭터 카드 그리드
- `SajuTestimonials.tsx` — 사용자 후기
- `SajuFAQ.tsx` — FAQ 아코디언
- `SajuFooter.tsx` — 하단 푸터
### PDF 리포트 수정
파일: `src/lib/saju/pdf/saju-template.tsx`
@react-pdf/renderer 기반. 레이아웃, 색상, 섹션 순서 등을 수정합니다.
### 다국어 추가
1. `messages/` 디렉토리에 새 언어 JSON 추가 (예: `vi.json`)
2. `src/i18n/routing.ts`에서 `locales` 배열에 추가
3. 메시지 키를 번역
### 사주 엔진 확장
파일: `src/lib/saju/saju-engine.ts`
주요 함수:
- `calculateSaju(input)` — 메인 사주 계산 (4주, 십신, 12운성, 대운, 오행)
- `getFourPillars(year, month, day, hour, minute)` — 4주 간지 반환
- `getRelation(dayStem, targetStem)` — 십신 관계
- `getTwelveMeteor(stem, branch)` — 12운성
- `getDaewoon(...)` — 대운 계산
자미두수: `src/lib/saju/ziwei.ts`
- `createChart(year, month, day, hour, minute, isMale)` — 명반 생성
서양 점성술: `src/lib/saju/natal.ts`
- `calculateNatal(input)` — 출생 차트
### 사업자 정보 교체
정책 페이지(`refund-policy`, `privacy-policy`, `terms`)에 placeholder가 있습니다:
- "Your Company Name" → 실제 상호명
- "Your Name" → 실제 대표자명
- "your-email@example.com" → 실제 이메일
- "000-00-00000" → 실제 사업자등록번호
---
## 주요 데이터 흐름
### 사주 분석 플로우
```
사용자 입력 (생년월일시, 성별, 고민)
↓
saju-engine.ts → calculateSaju() → 4주, 십신, 운성, 대운
↓
advanced-analysis.ts → 자미두수 + 점성술 추가 분석
↓
prompts.ts → AI 프롬프트 조합
↓
ai/analyzer.ts → Gemini API 호출
↓
DB 저장 (saju_readings)
↓
결과 표시 + PDF 다운로드
```
### 채팅 플로우
```
사용자 메시지
↓
api/saju/chat/route.ts → 캐릭터 프롬프트 + 사주 컨텍스트
↓
Gemini AI 스트리밍 응답
↓
DB 저장 (chat_messages) + 별 차감
```
### 결제 플로우
```
사용자 → PaddleCheckout → Paddle 결제 → 웹훅 → api/webhooks/paddle
↓
user_stars 테이블 업데이트 → 별 충전 완료
```
---
## 개발 컨벤션
- **서버 액션**: `src/services/` 하위, zod 검증 사용
- **클라이언트 상태**: Zustand (`src/store/`)
- **API 라우트**: `src/app/api/` (Route Handlers)
- **컴포넌트**: `"use client"` 명시, useTranslations() 사용
- **스타일**: Tailwind CSS 유틸리티 클래스
- **타입**: `src/types/`에 중앙 관리
- **환경변수**: 클라이언트용은 `NEXT_PUBLIC_` 접두사
---
## 트러블슈팅
| 문제 | 해결 |
|------|------|
| 한글 PDF 깨짐 | `public/fonts/`에 NotoSansKR 폰트 확인 |
| AI 분석 안 됨 | `GOOGLE_GENERATIVE_AI_API_KEY` 확인 |
| 로그인 안 됨 | Supabase Google OAuth redirect URL 확인 |
| 결제 웹훅 안 옴 | Paddle 웹훅 URL + `PADDLE_WEBHOOK_SECRET` 확인 |
| 시간 계산 이상 | 진태양시 보정 — `cities.ts`에 도시 경도 확인 |