{"id":44205874,"url":"https://github.com/revfactory/satang","last_synced_at":"2026-02-13T02:01:46.242Z","repository":{"id":336791814,"uuid":"1151136956","full_name":"revfactory/satang","owner":"revfactory","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-09T08:03:47.000Z","size":5328,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-09T08:36:07.102Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://satang.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/revfactory.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-06T05:07:55.000Z","updated_at":"2026-02-09T08:04:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/revfactory/satang","commit_stats":null,"previous_names":["revfactory/kakaobook","revfactory/bonbon"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/revfactory/satang","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revfactory%2Fsatang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revfactory%2Fsatang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revfactory%2Fsatang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revfactory%2Fsatang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/revfactory","download_url":"https://codeload.github.com/revfactory/satang/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revfactory%2Fsatang/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29284716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T21:57:15.303Z","status":"ssl_error","status_checked_at":"2026-02-09T21:57:11.537Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-09T23:00:27.102Z","updated_at":"2026-02-09T23:00:50.229Z","avatar_url":"https://github.com/revfactory.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Satang\n\n\u003e **Claude Code로 노트북LM 클론 서비스를 기획부터 배포까지 1시간?!**\n\nGoogle NotebookLM에서 영감을 받은 AI 기반 지식 노트북 서비스입니다.\n이 프로젝트는 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)를 활용하여 얼마나 빠르게 실제 서비스를 구축할 수 있는지 실험하기 위해 만들어졌습니다.\n\n## 개발 과정\n\n| 단계 | 내용 |\n|------|------|\n| **1. 기획** | 노트북LM 서비스의 주요 화면을 스크린샷으로 캡처 |\n| **2. Spec 정의** | Claude Code의 Spec 생성 스킬로 전체 프로젝트 스펙 문서 작성 |\n| **3. 개발** | Spec 문서를 검토한 뒤 Claude Code와 함께 개발 시작 |\n| **4. 테스트 \u0026 디자인** | 생성된 서비스를 테스트하고, AI에게 디자인 리뷰 및 개선 요청 |\n| **5. 배포** | 배포 설정 후 서비스 배포 |\n\n## 서비스 화면\n\n### 노트북 목록\n노트북을 생성하고 관리하는 홈 화면입니다. 그리드/리스트 뷰 전환과 탭 필터링을 지원합니다.\n\n![노트북 목록](service_images/01_북리스트.png)\n\n### 소스 추가\nPDF, 웹페이지 URL, 텍스트 등 다양한 형식의 소스를 노트북에 추가할 수 있습니다.\n\n![소스 추가](service_images/02_소스추가.png)\n\n### 소스 확인 \u0026 AI 채팅\n추가된 소스의 내용을 확인하고, AI와 대화하며 소스 기반 질의응답을 수행합니다.\n\n![소스 확인](service_images/03_소스확인.png)\n\n### 인포그래픽 생성\n소스 내용을 바탕으로 언어, 방향, 세부정보 수준 등을 설정하여 인포그래픽을 생성합니다.\n\n![인포그래픽 생성](service_images/04_인포그래픽생성.png)\n\n### 인포그래픽 확인\n생성된 인포그래픽을 확인하고 다운로드할 수 있습니다.\n\n![인포그래픽 확인](service_images/05_인포그래픽확인.png)\n\n### 슬라이드 생성\n소스 내용을 기반으로 형식, 언어, 깊이를 설정하여 슬라이드 자료를 생성합니다.\n\n![슬라이드 생성](service_images/06_슬라이드생성.png)\n\n### 슬라이드 확인\n생성된 슬라이드를 확인하고 다운로드할 수 있습니다.\n\n![슬라이드 확인](service_images/07_슬라이드확인.png)\n\n## 주요 기능\n\n- **노트북 관리** - 노트북 생성, 이름 변경, 삭제, 그리드/리스트 뷰\n- **소스 관리** - PDF, URL, 텍스트, 이미지, 오디오 업로드 및 AI 자동 요약/텍스트 추출\n- **AI 채팅** - 소스 기반 질의응답, 스트리밍 응답, 대화 이력 관리\n- **스튜디오** - 인포그래픽 \u0026 슬라이드 자료 자동 생성 (병렬 생성 \u0026 실시간 진행 표시)\n- **모바일 대응** - 데스크톱 3패널 리사이저블 / 모바일 탭 레이아웃\n\n## 기술 스택\n\n| 영역 | 기술 |\n|------|------|\n| **프레임워크** | Next.js 16 (React 19, Turbopack) |\n| **언어** | TypeScript 5.9 |\n| **스타일링** | Tailwind CSS v4 + shadcn/ui (Radix UI) |\n| **상태 관리** | TanStack React Query + Zustand |\n| **폼/검증** | React Hook Form + Zod |\n| **백엔드** | Supabase (PostgreSQL + Auth + Storage) |\n| **AI 채팅** | Google Gemini 3 Flash |\n| **이미지 생성** | Google Gemini 3 Pro Image |\n| **인증** | Google OAuth (Supabase Auth) |\n| **모니터링** | Vercel Speed Insights |\n\n## 시작하기\n\n### 사전 요구사항\n\n- Node.js 18+\n- Supabase 프로젝트\n- Google Gemini API 키 (Gemini 3 Flash + Gemini 3 Pro Image 사용)\n\n### 설치\n\n```bash\ngit clone https://github.com/revfactory/satang.git\ncd satang\nnpm install\n```\n\n### 환경 변수\n\n`.env.local` 파일을 생성하고 아래 내용을 설정합니다.\n\n```env\nNEXT_PUBLIC_SUPABASE_URL=your_supabase_url\nNEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key\nSUPABASE_SERVICE_ROLE_KEY=your_service_role_key\nGEMINI_API_KEY=your_gemini_api_key\n```\n\n### Supabase 설정\n\n#### 1. 프로젝트 생성\n\n[Supabase](https://supabase.com)에서 새 프로젝트를 생성합니다.\n\n#### 2. 데이터베이스 스키마\n\nSupabase 대시보드의 **SQL Editor**에서 마이그레이션 파일을 순서대로 실행합니다.\n\n```\nsupabase/migrations/00001_initial_schema.sql\nsupabase/migrations/00002_add_users_insert_policy.sql\n```\n\n생성되는 테이블:\n\n| 테이블 | 설명 |\n|--------|------|\n| `users` | 사용자 프로필 (Auth 연동 자동 생성) |\n| `notebooks` | 노트북 |\n| `sources` | 소스 (PDF, URL, 텍스트 등) |\n| `chat_messages` | 채팅 메시지 |\n| `studio_outputs` | 스튜디오 생성 콘텐츠 |\n| `notes` | 메모 |\n\n모든 테이블에 RLS(Row Level Security)가 적용되어 있으며, 사용자별 데이터 격리가 자동으로 이루어집니다.\n\n#### 3. Google OAuth 인증 설정\n\n1. [Google Cloud Console](https://console.cloud.google.com)에서 OAuth 2.0 클라이언트 ID를 생성합니다.\n2. 승인된 리디렉션 URI에 아래 주소를 추가합니다:\n   ```\n   https://\u003cyour-project-ref\u003e.supabase.co/auth/v1/callback\n   ```\n3. Supabase 대시보드 → **Authentication** → **Providers** → **Google**에서 Client ID와 Client Secret을 입력합니다.\n\n#### 4. Storage 버킷 설정\n\nSupabase 대시보드 → **Storage**에서 버킷을 생성합니다.\n\n**`sources` 버킷 (Private)**\n\n소스 파일(PDF 등)을 저장합니다. Private 버킷으로 생성합니다.\n\n```sql\n-- 인증된 사용자 업로드 허용\nCREATE POLICY \"sources_insert\" ON storage.objects\n  FOR INSERT TO authenticated\n  WITH CHECK (bucket_id = 'sources');\n\n-- 본인 파일만 읽기 허용\nCREATE POLICY \"sources_select\" ON storage.objects\n  FOR SELECT TO authenticated\n  USING (bucket_id = 'sources' AND auth.uid()::text = (storage.foldername(name))[1]);\n\n-- 본인 파일만 삭제 허용\nCREATE POLICY \"sources_delete\" ON storage.objects\n  FOR DELETE TO authenticated\n  USING (bucket_id = 'sources' AND auth.uid()::text = (storage.foldername(name))[1]);\n```\n\n**`studio` 버킷 (Public)**\n\n생성된 인포그래픽/슬라이드 이미지를 저장합니다. Public 버킷으로 생성합니다.\n\n```sql\n-- 인증된 사용자 업로드 허용\nCREATE POLICY \"studio_insert\" ON storage.objects\n  FOR INSERT TO authenticated\n  WITH CHECK (bucket_id = 'studio');\n\n-- 공개 읽기 허용\nCREATE POLICY \"studio_select\" ON storage.objects\n  FOR SELECT TO public\n  USING (bucket_id = 'studio');\n\n-- 본인 파일만 삭제 허용\nCREATE POLICY \"studio_delete\" ON storage.objects\n  FOR DELETE TO authenticated\n  USING (bucket_id = 'studio' AND auth.uid()::text = (storage.foldername(name))[1]);\n```\n\n### 실행\n\n```bash\nnpm run dev\n```\n\n`http://localhost:3000`에서 서비스를 확인할 수 있습니다.\n\n## 라이선스\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevfactory%2Fsatang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frevfactory%2Fsatang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevfactory%2Fsatang/lists"}