1) 핵심 기술 내역 요약

영역별 대표 기술

영역 핵심 기술
AI·생성 Gemini 감성 분석 · 매칭 근거 KO/EN 동시 생성 · JSON-only 프롬프트 + 코드펜스 스트리핑
검색·매칭 텍스트 임베딩 → pgvector 코사인 거리(<=>) top-k 검색 · Redis 결과 캐시(TTL 1h)
데이터 모델링 1NF 감성 태그 행 분리 · 3NF 장단 마스터 분리 · JSONB 의도적 비정규화 · sort_order 순서 보존
쿼리 최적화 joinedload 2종 + result.unique() N+1 제거 · ARRAY 연산자 → B-tree JOIN 전환
아키텍처 Hexagonal(Ports & Adapters) + Clean Architecture + DDD · 프랙탈 네이밍 · Composition Root 단일화
도메인 설계 frozen Value Object · 파생 프로퍼티(loop_unit_beats·is_commercial·primary_emotion)
백엔드 런타임 Python 3.13 · FastAPI · SQLAlchemy 2.0 async · psycopg 3 · Pydantic v2 · Alembic
프론트엔드 Next.js 16 App Router · React 19 · Tailwind 4 · WaveSurfer.js · 전역 PlayerContext
데이터 파이프라인 XML 파싱 · 파생 규칙(장단·감성·BPM·라이선스) · 중복 키 스킵 · 임베딩 이어받기
배포·운영 Docker Compose 4서비스 · healthcheck 기반 기동 순서 · GitHub Actions → Pages(문서)

수치로 보는 구현

항목 값
수집 음원 500건 (gugak_500.csv, 정식 CSV 파서 기준)
임베딩 차원 1,536 (gugak_tracks.embedding)
MVP 물리 테이블 4개
장단 마스터 6종 / 루프 단위 4·6·10·12박
감성 태그 6종 (도메인 enum 기준)
라이선스 유형 2종 (KOGL 제1·제2유형)
매칭 결과 수 top-3
캐시 TTL 3,600초
BPM 프리셋 마진 ±20 (하한 60 / 상한 200)
검색당 LLM 호출 최대 4회 (캐시 MISS 시)

아키텍처 규칙 준수 현황

규칙 상태
Domain에 FastAPI·SQLAlchemy import 없음 ✅
Router가 PgRepository를 직접 import하지 않음 ✅
Interactor가 ORM·HTTPException을 import하지 않음 ✅
프랙탈 네이밍 일치 ✅
모든 Provider가 dependencies/에만 존재 ✅
ORM 파일 = 테이블 1개당 1파일 ✅
joinedload 전략이 포트 인터페이스 밖으로 노출되지 않음 ✅
Python type hint 100% · async 일관 · Pydantic v2 ✅
emotion_tags ARRAY 컬럼 없음 / loop_unit_beats 컬럼 없음 ✅
match_logs.similarity_score Float ✅
모든 트랙 조회에 joinedload + result.unique() ✅
DISCOVER 응답에 preset_url 포함 ✅

잔여 과제 (우선순위 순)

문서를 정직하게 유지하기 위해, 현재 코드에서 확인된 미완 지점을 모아 둡니다.

# 항목 위치 영향 우선순위
1 임베딩 차원 불일치 (1536 vs 768) embed_pipeline.py ↔ 001_init 임베딩 적재 실패 → 검색 불가 🔴 높음
2 embed_text() 미구현 (TODO) track_discover_pg_repository.py DISCOVER 파이프라인 미완결 🔴 높음
3 track_embeddings 테이블 참조 embed_pipeline.py 현 스키마에 없는 테이블 — 스크립트 갱신 필요 🔴 높음
4 결과 조립 미구현 (TODO) _build_result() · _to_track_result() 응답 조립 로직 🟠 중간
5 캐시 직렬화 json.dumps(result.__dict__) 중첩 dataclass 직렬화 실패 → asdict() 필요 🟠 중간
6 감성 enum 정합 infer_emotions() ↔ EmotionTag enum 밖 태그가 필터에 안 잡힘 🟠 중간
7 장단 폴백 편중 infer_jangdan() 대부분 중모리 → 장단·루프 필터 변별력 저하 🟠 중간
8 디렉터리 이중화 backend/ ↔ backend/soundbridge/ 같은 트리가 두 벌 — 패키지 루트 정리 필요 🟠 중간
9 라이선스 결측 낙관 처리 normalize_license() 결측 시 KOGL_1 → v1.1에서 보수 처리로 전환 🟡 낮음
10 explain_match 순차 호출 gemini_adapter.py 캐시 MISS 시 지연 3배 → asyncio.gather 🟡 낮음
11 Interactor 파라미터명 claude track_discover_interactor.py Gemini 교체 후 이름만 잔존 🟡 낮음
12 프리셋 계약 테스트 부재 백엔드 ↔ 프론트 상수 불일치 시 조용히 0건 반환 🟡 낮음
13 maximum-scale=1 layout.tsx 확대 차단 — 접근성 재검토 🟡 낮음

v1.1 이후 계획 기능

기능 관련 포트/테이블
이메일·Google 인증 users · email_verifications · EmailPort(Resend)
트랙 저장 saved_tracks · SavedTrackRepository
다운로드 이력 download_logs · DownloadLogRepository
CUE 자동 추출 GeminiPort.extract_cue_points()
공연·체험 정보 KopisPort — KOPIS · 한국관광공사
HNSW 인덱스 gugak_tracks.embedding (v1.2)

SoundBridge — 당신의 음악 언어로 국악을 만나세요. 본 사이트는 개발 문서 자료입니다.

This site uses Just the Docs, a documentation theme for Jekyll.