Files
web-page-backend/docs/superpowers/specs/2026-05-01-music-youtube-tab-frontend-design.md
2026-05-01 14:32:32 +09:00

8.3 KiB

Music YouTube Tab Frontend — Design Spec

Date: 2026-05-01
Repo: web-page (React + Vite SPA at /Users/jaeohpark/development/web-page/)


1. Goal

MusicStudio 페이지에 🎯 YouTube 탭을 추가한다. 기존 4개 탭(Create / Lyrics / Library / Remix) 옆에 하나 더 붙이며, 탭 내부에 3개의 서브탭을 둔다.

  • 🎬 영상 제작 — 트랙 선택 → 포맷·국가 설정 → 렌더링 → 내보내기
  • 💰 수익 추적 — 수동 수익 기록 입력 + 장르별 RPM 차트 + 기록 테이블
  • 📊 시장 트렌드 — agent-office가 매일 수집한 YouTube/Trends/Billboard 데이터 표시 + AI 프롬프트 추천

2. 영향 파일

수정

파일 변경 내용
src/pages/music/MusicStudio.jsx tab 상태에 'youtube' 추가, 탭 버튼 추가, YoutubeTab 렌더링
src/api.js 비디오 프로젝트 / 수익 / 시장 트렌드 API 함수 추가

신규 생성

파일 역할
src/pages/music/components/YoutubeTab.jsx YouTube 탭 루트 컴포넌트 (서브탭 상태 관리)
src/pages/music/components/VideoProjectsTab.jsx 🎬 영상 제작 서브탭
src/pages/music/components/RevenueTab.jsx 💰 수익 추적 서브탭
src/pages/music/components/TrendsTab.jsx 📊 시장 트렌드 서브탭

3. 컴포넌트 계층

MusicStudio
└── [tab === 'youtube']
    └── YoutubeTab
        ├── subtab 상태: 'video' | 'revenue' | 'trends'
        ├── [subtab === 'video']   → VideoProjectsTab
        ├── [subtab === 'revenue'] → RevenueTab
        └── [subtab === 'trends']  → TrendsTab

YoutubeTab props:

  • library: Array — 라이브러리 트랙 목록 (MusicStudio에서 내려줌, 트랙 선택 드롭다운용)
  • initialTrackId?: string — Library 탭의 "영상 만들기" 버튼 클릭 시 pre-select용

4. 서브탭 상세

4-1. VideoProjectsTab (subtab === 'video')

① 새 영상 만들기 패널

  • 트랙 선택 드롭다운 (library prop에서 목록, title 표시)
  • 형식 선택: 비주얼라이저 | 슬라이드쇼 (toggle)
  • 타겟 국가 칩: BR / US / ID / MX / KR (복수 선택 가능)
  • "프로젝트 생성" 버튼 → POST /api/music/video-project

② 영상 프로젝트 목록

  • GET /api/music/video-projects 폴링 (렌더링 중인 프로젝트 있을 때 5초 간격)
  • 상태별 표시:
    • pending — "대기" 배지 + "▶ 렌더" 버튼 → POST /api/music/video-project/:id/render
    • rendering — "처리중" 배지 + 진행 바 (시작 시각 기준 경과 시간 표시)
    • done — "✓ 완료" 배지 + "↓ 내보내기" 버튼
    • failed — "실패" 배지 (빨간색)

③ 내보내기 패키지 (done 상태 프로젝트 선택 시)

  • GET /api/music/video-project/:id/export{mp4_url, thumbnail_url, metadata}
  • mp4 다운로드 링크, thumbnail 다운로드 링크, metadata.json 미리보기 (title / tags / target)

상태 관리:

const [projects, setProjects] = useState([])
const [selectedTrackId, setSelectedTrackId] = useState(initialTrackId ?? '')
const [format, setFormat] = useState('visualizer')
const [countries, setCountries] = useState(['BR'])
const [creating, setCreating] = useState(false)
const [exportData, setExportData] = useState(null)  // 선택된 done 프로젝트의 export

4-2. RevenueTab (subtab === 'revenue')

대시보드 카드 (3개)

  • GET /api/music/revenue/dashboard{total_revenue_usd, total_views, avg_rpm}
  • 총 수익 / 총 조회수 / 가중평균 RPM

장르별 RPM 바 차트

  • GET /api/music/revenue → 레코드 목록에서 장르별로 RPM 집계
  • 바 차트 (CSS 기반, 라이브러리 없음) — genre / rpm / color 매핑

수익 기록 추가 폼

  • 필드: yt_video_id, record_month (YYYY-MM), revenue_usd, views, country
  • "저장" → POST /api/music/revenue
  • 성공 시 목록 + 대시보드 리프레시

수익 기록 테이블

  • GET /api/music/revenue — 영상 제목 / 월 / 수익 / 조회수 / RPM
  • 행 클릭 → 수정 폼 인라인 펼침
  • 삭제 버튼 → DELETE /api/music/revenue/:id

장르 추론: yt_video_id는 자유 입력이고 장르 컬럼이 DB에 없으므로, genre 필드를 수익 기록 폼에 optional 셀렉트로 추가한다. DB 스키마에 이미 없으면 프론트에서만 관리하지 않고, API 명세 확인 후 처리.

참고: revenue_records 테이블에 genre 컬럼이 없다. 차트는 yt_video_id별 집계만 가능. 장르별 RPM 차트는 "영상별 RPM 비교"로 레이블을 바꿔서 구현한다.

상태 관리:

const [dashboard, setDashboard] = useState(null)
const [records, setRecords] = useState([])
const [form, setForm] = useState({ yt_video_id:'', record_month:'', revenue_usd:'', views:'', country:'BR' })
const [editingId, setEditingId] = useState(null)

수집 상태 바

  • GET /api/music/market/report/latest{report_date, created_at, top_genres, recommended_styles}
  • 마지막 수집 일시 + 트렌드 수 표시
  • "↻ 수동 수집" 버튼 → POST /api/agent-office/youtube/research (body: {})

오늘의 인기 장르 Top 5

  • top_genres 배열에서 상위 5개 렌더링
  • 각 항목: 장르명 / 대상 국가 플래그 / 점수 바

AI 추천 Suno 프롬프트

  • GET /api/music/market/suggest[{genre, suno_prompt, target_countries, reason}]
  • 카드 형태, 프롬프트 클릭 시 클립보드 복사

트렌드 리포트 이력

  • GET /api/music/market/report → 날짜 목록
  • 날짜 클릭 → 해당 날짜 리포트 상세 표시 (top_genres + recommended_styles)

상태 관리:

const [latestReport, setLatestReport] = useState(null)
const [reports, setReports] = useState([])
const [suggestions, setSuggestions] = useState([])
const [selectedReport, setSelectedReport] = useState(null)
const [researching, setResearching] = useState(false)

5. API 추가 목록 (src/api.js)

// 기존 api.js 헬퍼: apiGet / apiPost / apiPut / apiDelete (plain fetch 래퍼)

// Video Projects
export const createVideoProject = (data) => apiPost('/api/music/video-project', data)
export const getVideoProjects = () => apiGet('/api/music/video-projects')
export const renderVideoProject = (id) => apiPost(`/api/music/video-project/${id}/render`)
export const exportVideoProject = (id) => apiGet(`/api/music/video-project/${id}/export`)
export const deleteVideoProject = (id) => apiDelete(`/api/music/video-project/${id}`)

// Revenue
export const getRevenueDashboard = () => apiGet('/api/music/revenue/dashboard')
export const getRevenueRecords = () => apiGet('/api/music/revenue')
export const addRevenueRecord = (data) => apiPost('/api/music/revenue', data)
export const updateRevenueRecord = (id, data) => apiPut(`/api/music/revenue/${id}`, data)
export const deleteRevenueRecord = (id) => apiDelete(`/api/music/revenue/${id}`)

// Market Trends
export const getLatestTrendReport = () => apiGet('/api/music/market/report/latest')
export const getTrendReports = () => apiGet('/api/music/market/report')
export const getMarketSuggestions = () => apiGet('/api/music/market/suggest')
export const triggerYoutubeResearch = () => apiPost('/api/agent-office/youtube/research', {})

6. Library 탭 연동

MusicStudio.jsxLibraryCard 컴포넌트에 "🎬 영상 만들기" 버튼 추가:

<button onClick={() => {
  setTab('youtube')
  setInitialTrackId(track.id)
}}>🎬 영상 만들기</button>

initialTrackId 상태를 MusicStudio 루트에 두고 YoutubeTab에 prop으로 내려준다. VideoProjectsTab이 마운트되면 해당 트랙을 드롭다운에 pre-select.


7. 스타일 가이드

기존 MusicStudio.css의 다크 테마 변수 재사용:

  • 배경: #111827 / #0d1117 / #1f2937
  • 강조색: #22c55e (초록, 완료·생성), #f59e0b (노랑, 처리중), #3b82f6 (파랑, 수익), #a855f7 (보라, 트렌드)
  • 새 CSS 클래스는 MusicStudio.css에 추가 (별도 파일 없음)

8. 범위 외 (Out of scope)

  • YouTube Analytics OAuth 자동 동기화 (나중에 확장)
  • 영상 업로드 자동화 (YouTube Data API write scope)
  • 차트 라이브러리 도입 (CSS 바로 구현)