diff --git a/README.md b/README.md index 9382efd..b589eea 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,127 @@ -# h-lab +
-유튜브 데이터를 수집하고 분석하는 개인용 웹 서비스입니다. -Spring Boot 4.x(3.4.0) 기반의 백엔드와 React + Vite 기반의 프론트엔드로 구성되어 있습니다. +# 🎬 h-lab · `yanalyst` -## 🛠 Tech Stack +**유튜브 데이터를 수집·분석하고, 떡상 영상을 발굴해 재가공·발행까지 잇는 1인 콘텐츠 파이프라인** -### Backend -- **Framework**: Spring Boot 3.4.0 (Java 21) -- **Database**: H2 (Development), JPA -- **API Docs**: Swagger UI (SpringDoc) -- **Architecture**: Domain-Driven Design style +
-### Frontend -- **Framework**: React 18 (Vite) -- **Language**: TypeScript -- **Styling**: Vanilla CSS + CSS Variables (Dark Mode) -- **State**: Zustand -- **Charts**: Recharts +![Java](https://img.shields.io/badge/Java-21-ED8B00?style=for-the-badge&logo=openjdk&logoColor=white) +![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.4.0-6DB33F?style=for-the-badge&logo=springboot&logoColor=white) +![PostgreSQL](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white) +![Thymeleaf](https://img.shields.io/badge/Thymeleaf_SSR-005F0F?style=for-the-badge&logo=thymeleaf&logoColor=white) -## 🚀 How to Run +![Gradle](https://img.shields.io/badge/Gradle-02303A?style=flat-square&logo=gradle&logoColor=white) +![Swagger](https://img.shields.io/badge/OpenAPI-SpringDoc-85EA2D?style=flat-square&logo=swagger&logoColor=black) +![Lombok](https://img.shields.io/badge/Lombok-BC4521?style=flat-square) +![Whisper](https://img.shields.io/badge/faster--whisper-FFD21E?style=flat-square&logo=openai&logoColor=black) +![FFmpeg](https://img.shields.io/badge/FFmpeg-007808?style=flat-square&logo=ffmpeg&logoColor=white) +![License](https://img.shields.io/badge/use-personal-lightgrey?style=flat-square) -### Backend & Frontend (Integrated) -1. `backend` 디렉토리로 이동 -2. `./gradlew bootRun` 실행 (Windows: `gradlew bootRun`) -3. 웹 서비스 접속: `http://localhost:8080` - - 메인 대시보드: `http://localhost:8080/` - - 채널 관리: `http://localhost:8080/channels` - - Swagger UI: `http://localhost:8080/swagger-ui.html` +
-### Frontend (Legacy React) -*Removed in favor of Thymeleaf Server-Side Rendering* +--- -## 📂 Project Structure +## 📖 개요 + +**h-lab**(아티팩트명 `yanalyst`)은 유튜브 Shorts 데이터를 수집·분석해 **떡상(구독자 대비 조회수 폭발) 후보**를 골라내고, 자막을 추출·재가공한 뒤 발행까지 추적하는 **개인용 SSR 웹 서비스**입니다. Spring Boot 백엔드에 **Thymeleaf 서버 사이드 렌더링** UI를 사용하며, 모든 화면이 동일한 앱에서 제공됩니다. + +> 라이트/다크 테마 토글을 지원하는 정제된 SaaS UI로, 사이드바 한 곳에서 전체 테마가 전환됩니다. + +## ✨ 주요 기능 + +| 단계 | 설명 | +|------|------| +| 🛰️ **수집 (Collection)** | 등록 채널 동기화 + 조회수 검색 수집. 정기 자동 수집 스케줄러. | +| 🔍 **발굴 (Discovery)** | `조회수 ÷ 구독자` **배율**로 떡상 후보 자동 선별. 카테고리·북마크·필터. | +| 🗂️ **큐레이션 (Curation)** | 관심 상태(NEW→REVIEWING→TARGET→DONE/EXCLUDED) 칸반 보드 + 드래그 이동. | +| ✂️ **재가공 (Rework)** | **영상 업로드 → Whisper 시간싱크 자막 추출 → 말 없는 구간 제거·배속 → SRT+영상 내보내기**(CapCut import). 재작성 에디터. | +| 📤 **발행 (Publish)** | 제목·설명·해시태그·예약 패키지 관리, 발행 추적(업로드는 수동). | + +## 🔁 콘텐츠 파이프라인 + +``` + 수집 발굴/큐레이션 재가공 발행 + ┌────────┐ ┌────────────┐ ┌──────────────┐ ┌──────────┐ + │ CHANNEL│ ──▶ │ 배율 정렬 │ ──▶ │ 자막추출·컷 │ ──▶ │ 제목/태그 │ + │ SEARCH │ │ 칸반 보드 │ │ SRT·영상 출력 │ │ 발행 추적 │ + └────────┘ └────────────┘ └──────────────┘ └──────────┘ + \______________ ChannelVideo (단일 마스터) ______________/ +``` + +모든 단계는 `domain/channel/ChannelVideo` 엔티티 하나를 중심으로 돕니다. + +## 🛠 기술 스택 + +**Backend** · Spring Boot 3.4.0 / Java 21 · Spring Data JPA · Validation +**View** · Thymeleaf + Layout Dialect (SSR) · Inter · Lucide Icons · Light/Dark CSS 변수 테마 +**DB** · PostgreSQL (`ddl-auto: update`) · p6spy · Hypersistence Utils +**Docs** · SpringDoc OpenAPI (Swagger UI) +**Build/Tools** · Gradle Wrapper · Lombok · JUnit 5 +**AI/미디어 엔진**(별도 Python 마이크로서비스) · `faster-whisper`(전사) · `ffmpeg`(컷·배속·렌더) + +## 🚀 시작하기 + +> **요구사항**: JDK 21, PostgreSQL 접근 정보. 서버 포트는 **8088**. + +```bash +# 실행 (UI + API 모두 http://localhost:8088 에서 제공) +./gradlew bootRun # Windows: gradlew.bat bootRun + +# 빌드 / 테스트 +./gradlew build +./gradlew test + +# 단일 테스트 +./gradlew test --tests "com.hlab.yanalyst.domain.channel.SrtFormatterTest" +``` + +| 경로 | 설명 | +|------|------| +| `http://localhost:8088/` | 대시보드 | +| `http://localhost:8088/collection` · `/board` · `/discover` | 수집함 · 칸반 · 발굴 | +| `http://localhost:8088/rework/{id}` · `/publish` | 재가공 · 발행 큐 | +| `http://localhost:8088/swagger-ui.html` | Swagger UI | + +### 🔐 환경 변수 + +시크릿은 환경 변수 또는 git-ignored `application-local.yml`로 주입합니다 (예시: `application-local.yml.example`). + +| 변수 | 용도 | +|------|------| +| `DB_URL` · `DB_USERNAME` · `DB_PASSWORD` | PostgreSQL 접속 | +| `YOUTUBE_API_KEY` | YouTube Data API | +| `PYTHON_BASE_URL` | 자막/전사/렌더 마이크로서비스 (기본 `http://h-python.tolag.shop`) | +| `UPLOAD_MAX_FILE_SIZE` | 업로드 영상 최대 크기 (기본 200MB) | + +## 📂 프로젝트 구조 ``` h-lab/ ├── src/main/java/com/hlab/yanalyst/ -│ ├── domain/ # Domain Entities (Video, Channel...) -│ └── web/ # Web Controllers (Thymeleaf) -│ +│ ├── domain/ # DDD 스타일 — Entity+Repository+Service+RestController +│ │ ├── channel/ # ChannelVideo(단일 마스터)·수집·큐레이션·재가공·SRT/컷 로직 +│ │ ├── category/ publish/ # 분류 · 발행 패키지 +│ │ └── production/ # n8n 크롤 랭킹 스냅샷 +│ ├── web/ # Thymeleaf 페이지 컨트롤러 + 추가 JSON API +│ ├── service/ # 횡단 서비스 (YouTube 검색 등) +│ └── global/ # config · 공통 응답 · 예외 · 스케줄러 └── src/main/resources/ - ├── static/ # CSS, JS - └── templates/ # HTML Templates (Thymeleaf) + ├── static/css/ # variables.css(테마 토큰) · style.css(컴포넌트) + ├── static/js/ # common.js(사이드바·테마 토글) + └── templates/ # layout/base·sidebar + 페이지 HTML ``` -## ✨ Key Features -- **Dashboard**: 전체 데이터 요약 및 시각화 (Charts) -- **Channel Management**: 분석 대상 유튜브 채널 관리 -- **Dark Mode**: 눈이 편안한 프리미엄 다크 모드 UI +## 🔌 외부 연동 + +- **Python 마이크로서비스** — YouTube 자막(`/transcript`), Whisper 전사(`/transcribe`), ffmpeg 렌더(`/render`). +- **YouTube Data API** — 채널·영상 메타 수집 및 조회수 검색 (일일 쿼터 가드). +- **n8n Webhook** — `production` 도메인의 랭킹/크롤 데이터 연동. + +## 📝 라이선스 + +개인용 프로젝트입니다. + +
+Built with Spring Boot · Thymeleaf · faster-whisper · ffmpeg +