코인노래방 녹음을 업로드하면 객관 지표를 시계열로 분석하고, 발성 KB(RAG)를 근거로 세션별 피드백을 생성하는 멀티유저 보컬 분석 서비스입니다. 원곡 채점이 아니라 사용자 본인 세션의 추세와 약점 변화를 보는 데 집중합니다.
- 실 서비스 URL: 배포 확정 후 기입 예정
- 아키텍처 정본: docs/ARCHITECTURE.md
- 결정 근거: docs/adr/README.md
- 포트폴리오 문서: docs/portfolio/README.md
아래 다이어그램은 docs/ARCHITECTURE.md의 구조를 포트폴리오용으로 추출한 것입니다. 원본 Mermaid 소스는 docs/portfolio/architecture-diagram.mmd에 있습니다.
flowchart TB
FE["Next.js 정적 SPA<br/>GCS 호스팅"]
GCS["GCS<br/>오디오, 프론트엔드, 백업"]
API["NestJS API<br/>인증, 업로드, 세션, 피드백 API"]
RQ[("redis-queue<br/>analysis:jobs, feedback:jobs")]
RS[("redis-session<br/>리프레시 토큰, 캐시")]
PG[("Postgres 16 + pgvector<br/>세션, 지표, KB, 피드백")]
AW["Python worker-audio<br/>librosa pYIN"]
RW["Python worker-rag<br/>하이브리드 검색 + 근거 생성"]
OpenAI["OpenAI<br/>text-embedding-3-large"]
Vertex["Vertex AI<br/>Gemini Flash"]
OBS["Prometheus, Grafana, Loki"]
FE -->|"REST"| API
FE -->|"Signed URL PUT/GET"| GCS
API -->|"Signed URL 발급"| GCS
API -->|"XADD"| RQ
API --> RS
API --> PG
RQ --> AW
AW --> GCS
AW --> PG
RQ --> RW
RW --> PG
RW --> OpenAI
RW --> Vertex
API -.-> OBS
AW -.-> OBS
- 로그인한 사용자가 API에서 Signed URL을 받고 브라우저가 GCS/fake-GCS에 녹음을 직접 업로드합니다.
- API가
analysis:jobs에 작업을 넣으면worker-audio가 pYIN 기반 지표와weakness_flags를 저장합니다. - API의 피드백 요청이
feedback:jobs를 적재하면worker-rag가 이를 소비해weakness_flags를 검색 쿼리로 만들고, pgvector +pg_trgm하이브리드 검색과 KB citation 검증을 거쳐 피드백을 저장합니다. - 웹 앱은 현재 로그인, 세션 목록/상세, 지표 추세 화면을 정적 export로 제공합니다. 업로드 화면과 피드백 카드 캡처는 배포 데모 전 남은 UI 작업입니다.
| 영역 | 상태 | 근거 |
|---|---|---|
| 인증 + 업로드 API | 구현됨 | src/auth, src/sessions, test/app.e2e-spec.ts |
| 오디오 지표 + 약점 플래그 | 구현됨 | worker-audio, src/database/migrations/1782373300000-AddPitchMetrics.ts, 1782374400000-AddWeaknessFlags.ts |
| RAG 피드백 백엔드 | 구현됨 | worker-rag, src/feedback, 1782376600000-CreateKbAndFeedback.ts |
| 정적 웹 프리뷰 | 로그인/세션/추세까지 구현됨 | apps/web/app/login, apps/web/app/sessions, apps/web/app/trends |
| GKE/Terraform/k8s 매니페스트 | 클러스터·API·worker-audio·백업·관측성 구현됨, worker-rag Deployment 대기 | infra/terraform, infra/k8s, infra/argocd |
| 공개 배포 데모 GIF | 배포 캡처 대기 | docs/portfolio/demo-capture-guide.md |
사전 요구사항: Docker, Node.js 24+, Corepack/Yarn, 워커 직접 실행 시 Python 3.11+.
cp .env.example .env
docker compose up -d --build
curl http://localhost:3000/v1/system/healthcompose 스택은 Postgres+pgvector, redis(큐), redis-session, fake-GCS, NestJS API, worker-audio, Prometheus, Grafana, Loki를 띄웁니다. worker-rag는 로컬에서 피드백 잡을 테스트할 때 Python 프로세스로 직접 실행합니다:
python3 -m venv .venv-worker-rag
. .venv-worker-rag/bin/activate
pip install -r worker-rag/requirements.txt
PYTHONPATH=worker-rag WORKER_RAG_FAKE_PROVIDERS=1 WORKER_ONCE=true python -m worker_rag웹만 로컬에서 개발할 때:
cd apps/web
corepack yarn install
NEXT_PUBLIC_API_BASE_URL=http://localhost:3000 corepack yarn dev인프라는 infra/terraform에 선언되고 쿠버네티스 매니페스트는 infra/k8s에 있습니다. 의도한 프로덕션 경로는 GKE/GCS/IAM/Artifact Registry용 Terraform, 그다음 API·워커·관측성·백업 CronJob을 위한 쿠버네티스 매니페스트 또는 ArgoCD 앱입니다. 현재 체크아웃에는 API·worker-audio·백업·관측성 매니페스트가 있으며, 전체 GKE RAG 데모 전에 worker-rag는 아직 배포 매니페스트가 필요합니다.
| 레이어 | 선택 | ADR |
|---|---|---|
| 오케스트레이션 | GKE Standard, 단계적 default/Spot 워커 풀 | ADR-001 |
| API | NestJS | ADR-002 |
| 큐 | Node↔Python 잡을 위한 Redis Streams | ADR-003 |
| 오디오 | 포트 뒤의 Python + librosa pYIN | ADR-004 |
| 데이터 | self-host Postgres 16 + pgvector, 역할별 Redis 분리 | ADR-005 |
| 스토리지 | GCS Signed URL과 라이프사이클 | ADR-006 |
| 인증 | argon2id, JWT access, 회전 refresh, OAuth 2.1 PKCE | ADR-007 |
| RAG | OpenAI 임베딩 + Vertex Gemini 생성 | ADR-008 |
| 관측성 | Prometheus, Grafana, Loki | ADR-009 |
| IaC/CD | Terraform, GitHub Actions 목표, kubectl→ArgoCD | ADR-010 |
| 프론트엔드 | GCS로 Next.js 정적 export | ADR-011 |
최종 README 데모 자산은 실제 로컬 또는 GKE 캡처 후 docs/portfolio/assets/demo.gif가 되어야 합니다. 캡처 체크리스트, 시크릿 스캔, 정리 절차, ffmpeg 변환 명령은 docs/portfolio/demo-capture-guide.md에 문서화되어 있습니다. 배포 URL과 업로드/피드백 카드 UI가 준비되기 전까지, 이 README는 낡거나 가짜인 GIF를 임베드하지 않고 의도적으로 가이드를 링크합니다.