https://github.com/revfactory/satang
https://github.com/revfactory/satang
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/revfactory/satang
- Owner: revfactory
- Created: 2026-02-06T05:07:55.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-09T08:03:47.000Z (4 months ago)
- Last Synced: 2026-02-09T08:36:07.102Z (4 months ago)
- Language: TypeScript
- Homepage: https://satang.vercel.app
- Size: 5.08 MB
- Stars: 5
- Watchers: 0
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Satang
> **Claude Code로 노트북LM 클론 서비스를 기획부터 배포까지 1시간?!**
Google NotebookLM에서 영감을 받은 AI 기반 지식 노트북 서비스입니다.
이 프로젝트는 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)를 활용하여 얼마나 빠르게 실제 서비스를 구축할 수 있는지 실험하기 위해 만들어졌습니다.
## 개발 과정
| 단계 | 내용 |
|------|------|
| **1. 기획** | 노트북LM 서비스의 주요 화면을 스크린샷으로 캡처 |
| **2. Spec 정의** | Claude Code의 Spec 생성 스킬로 전체 프로젝트 스펙 문서 작성 |
| **3. 개발** | Spec 문서를 검토한 뒤 Claude Code와 함께 개발 시작 |
| **4. 테스트 & 디자인** | 생성된 서비스를 테스트하고, AI에게 디자인 리뷰 및 개선 요청 |
| **5. 배포** | 배포 설정 후 서비스 배포 |
## 서비스 화면
### 노트북 목록
노트북을 생성하고 관리하는 홈 화면입니다. 그리드/리스트 뷰 전환과 탭 필터링을 지원합니다.

### 소스 추가
PDF, 웹페이지 URL, 텍스트 등 다양한 형식의 소스를 노트북에 추가할 수 있습니다.

### 소스 확인 & AI 채팅
추가된 소스의 내용을 확인하고, AI와 대화하며 소스 기반 질의응답을 수행합니다.

### 인포그래픽 생성
소스 내용을 바탕으로 언어, 방향, 세부정보 수준 등을 설정하여 인포그래픽을 생성합니다.

### 인포그래픽 확인
생성된 인포그래픽을 확인하고 다운로드할 수 있습니다.

### 슬라이드 생성
소스 내용을 기반으로 형식, 언어, 깊이를 설정하여 슬라이드 자료를 생성합니다.

### 슬라이드 확인
생성된 슬라이드를 확인하고 다운로드할 수 있습니다.

## 주요 기능
- **노트북 관리** - 노트북 생성, 이름 변경, 삭제, 그리드/리스트 뷰
- **소스 관리** - PDF, URL, 텍스트, 이미지, 오디오 업로드 및 AI 자동 요약/텍스트 추출
- **AI 채팅** - 소스 기반 질의응답, 스트리밍 응답, 대화 이력 관리
- **스튜디오** - 인포그래픽 & 슬라이드 자료 자동 생성 (병렬 생성 & 실시간 진행 표시)
- **모바일 대응** - 데스크톱 3패널 리사이저블 / 모바일 탭 레이아웃
## 기술 스택
| 영역 | 기술 |
|------|------|
| **프레임워크** | Next.js 16 (React 19, Turbopack) |
| **언어** | TypeScript 5.9 |
| **스타일링** | Tailwind CSS v4 + shadcn/ui (Radix UI) |
| **상태 관리** | TanStack React Query + Zustand |
| **폼/검증** | React Hook Form + Zod |
| **백엔드** | Supabase (PostgreSQL + Auth + Storage) |
| **AI 채팅** | Google Gemini 3 Flash |
| **이미지 생성** | Google Gemini 3 Pro Image |
| **인증** | Google OAuth (Supabase Auth) |
| **모니터링** | Vercel Speed Insights |
## 시작하기
### 사전 요구사항
- Node.js 18+
- Supabase 프로젝트
- Google Gemini API 키 (Gemini 3 Flash + Gemini 3 Pro Image 사용)
### 설치
```bash
git clone https://github.com/revfactory/satang.git
cd satang
npm install
```
### 환경 변수
`.env.local` 파일을 생성하고 아래 내용을 설정합니다.
```env
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
GEMINI_API_KEY=your_gemini_api_key
```
### Supabase 설정
#### 1. 프로젝트 생성
[Supabase](https://supabase.com)에서 새 프로젝트를 생성합니다.
#### 2. 데이터베이스 스키마
Supabase 대시보드의 **SQL Editor**에서 마이그레이션 파일을 순서대로 실행합니다.
```
supabase/migrations/00001_initial_schema.sql
supabase/migrations/00002_add_users_insert_policy.sql
```
생성되는 테이블:
| 테이블 | 설명 |
|--------|------|
| `users` | 사용자 프로필 (Auth 연동 자동 생성) |
| `notebooks` | 노트북 |
| `sources` | 소스 (PDF, URL, 텍스트 등) |
| `chat_messages` | 채팅 메시지 |
| `studio_outputs` | 스튜디오 생성 콘텐츠 |
| `notes` | 메모 |
모든 테이블에 RLS(Row Level Security)가 적용되어 있으며, 사용자별 데이터 격리가 자동으로 이루어집니다.
#### 3. Google OAuth 인증 설정
1. [Google Cloud Console](https://console.cloud.google.com)에서 OAuth 2.0 클라이언트 ID를 생성합니다.
2. 승인된 리디렉션 URI에 아래 주소를 추가합니다:
```
https://.supabase.co/auth/v1/callback
```
3. Supabase 대시보드 → **Authentication** → **Providers** → **Google**에서 Client ID와 Client Secret을 입력합니다.
#### 4. Storage 버킷 설정
Supabase 대시보드 → **Storage**에서 버킷을 생성합니다.
**`sources` 버킷 (Private)**
소스 파일(PDF 등)을 저장합니다. Private 버킷으로 생성합니다.
```sql
-- 인증된 사용자 업로드 허용
CREATE POLICY "sources_insert" ON storage.objects
FOR INSERT TO authenticated
WITH CHECK (bucket_id = 'sources');
-- 본인 파일만 읽기 허용
CREATE POLICY "sources_select" ON storage.objects
FOR SELECT TO authenticated
USING (bucket_id = 'sources' AND auth.uid()::text = (storage.foldername(name))[1]);
-- 본인 파일만 삭제 허용
CREATE POLICY "sources_delete" ON storage.objects
FOR DELETE TO authenticated
USING (bucket_id = 'sources' AND auth.uid()::text = (storage.foldername(name))[1]);
```
**`studio` 버킷 (Public)**
생성된 인포그래픽/슬라이드 이미지를 저장합니다. Public 버킷으로 생성합니다.
```sql
-- 인증된 사용자 업로드 허용
CREATE POLICY "studio_insert" ON storage.objects
FOR INSERT TO authenticated
WITH CHECK (bucket_id = 'studio');
-- 공개 읽기 허용
CREATE POLICY "studio_select" ON storage.objects
FOR SELECT TO public
USING (bucket_id = 'studio');
-- 본인 파일만 삭제 허용
CREATE POLICY "studio_delete" ON storage.objects
FOR DELETE TO authenticated
USING (bucket_id = 'studio' AND auth.uid()::text = (storage.foldername(name))[1]);
```
### 실행
```bash
npm run dev
```
`http://localhost:3000`에서 서비스를 확인할 수 있습니다.
## 라이선스
MIT