프로젝트 개요
한 줄 소개
SoundBridge — 당신의 음악 언어로 국악을 만나는 감성 매칭 · 샘플 라이브러리 플랫폼.
💡 쉽게 말하면: “요즘 듣는 음악이랑 비슷한 국악 없나요?”라고 물으면, 그 문장에서 감성을 읽어 국립국악원 음원 중 가장 닮은 곡을 찾아 주고 “왜 닮았는지”까지 설명해 주는 서비스입니다. 마음에 들면 그 감성 그대로 필터가 채워진 샘플 라이브러리로 넘어가, 자기 음악에 얹을 국악 소스를 바로 고를 수 있습니다. 낯선 용어는 용어 정의에 쉬운 말로 풀어두었습니다.
1. 무엇을 만들었나
SoundBridge는 두 개의 화면과 그 둘을 잇는 한 줄의 URL로 이루어집니다.
| 축 | 화면 | 하는 일 |
|---|---|---|
| DISCOVER | /discover | 자연어 한 문장 → 감성 해석 → 국악 top-3 매칭 → KO/EN 근거 설명 |
| 브릿지 | preset_url | 매칭된 트랙의 악기·감성·BPM을 CREATE 필터 쿼리로 변환 |
| CREATE | /create | 악기·장단·감성·BPM·루프 단위·라이선스로 국악 샘플 필터링 |
DISCOVER는 “국악을 처음 듣는 사람”을 위한 입구이고, CREATE는 “국악을 쓰려는 크리에이터”를 위한 작업대입니다. 두 화면이 따로 놀지 않도록, DISCOVER 응답의 모든 트랙에 preset_url이 함께 실려 나갑니다.
2. 핵심 지표
| 항목 | 값 | 근거 |
|---|---|---|
| 수집 음원 | 500건 | backend/scripts/gugak_500.csv — 국립국악원 phrasedataview2 API |
| 임베딩 차원 | 1,536 | gugak_tracks.embedding Vector(1536) (Alembic 001_init) |
| 장단 마스터 | 6종 | 자진모리·중모리·굿거리(12박) / 휘모리(4박) / 세마치(6박) / 엇모리(10박) |
| 감성 태그 | 6종 | 신남·서정·웅장·슬픔·신비·차분 |
| 라이선스 유형 | 2종 | KOGL 제1유형(상업 가능) / 제2유형(상업 금지) |
| MVP 물리 테이블 | 4개 | jangdan · gugak_tracks · track_emotion_tags · match_logs |
| 매칭 결과 수 | top-3 | find_similar_tracks(top_k=3) |
3. 기술 스택
| 영역 | 스택 |
|---|---|
| 백엔드 | Python 3.13 · FastAPI 0.136 · SQLAlchemy 2.0 (async) · psycopg 3 · Alembic |
| DB | NeonDB (PostgreSQL) + pgvector 0.4.2 · Redis 8 (매칭 결과 1시간 캐시) |
| AI | Google Gemini (google-generativeai 0.8.6) — 감성 분석 · 매칭 근거 생성 · 임베딩 |
| 프론트엔드 | Next.js 16 · React 19 · TypeScript · Tailwind 4 · WaveSurfer.js 7 · framer-motion |
| 아키텍처 | Hexagonal (Ports & Adapters) + Clean Architecture + DDD, 프랙탈 네이밍 |
| 배포 | Docker Compose (api · frontend · postgres · redis) |
| 문서 사이트 | Jekyll + Just the Docs → GitHub Pages (본 사이트) |
4. 문서 지도
이 사이트는 다섯 개 장으로 나뉩니다.
- 문제와 솔루션 — 국악이 왜 안 쓰이는가, SoundBridge는 무엇을 다르게 하는가
- 데이터와 방법론 — 국립국악원 API 500건 수집, 감성 매칭 알고리즘, 정규화 설계, 프리셋 변환
- 시스템 구조 — 매칭 파이프라인, 백엔드 헥사고날 구조, 프론트엔드 워크플로우, ERD
- 사업화 전략 — SWOT·STP, 비즈니스 모델과 로드맵, ESG 가치
- 부록 — 핵심 기술 요약, 용어 정의
팀 소개는 팀 소개에 따로 있습니다.
5. 개발 원칙
명세서(docs/soundbridge_backend_dev_spec_v4_0.md) 0장에 못 박아 둔 규칙을 그대로 지켰습니다.
Domain은 FastAPI·SQLAlchemy·외부 API를 절대 import하지 않는다
Router는 PgRepository를 직접 import하지 않는다
Interactor는 ORM·HTTPException을 import하지 않는다
에러는 DomainException → HTTPException 변환을 Router에서만 한다
모든 ID는 UUID, 모든 함수는 async, type hint 100%
이 규칙을 지키면 “AI에게 코드를 맡기기 쉬운” 구조가 됩니다. 도메인마다 파일 배치가 똑같이 반복되기 때문에, 새 도메인을 추가할 때 참조할 패턴이 항상 하나로 정해집니다. 자세한 내용은 AI·백엔드 기술 구조에서 다룹니다.