music-lab 프론트엔드 대조 수정 (이중저장·title·audio_url·status shape)

- 이중 저장 방지: auto-register 유지, Save 버튼 제거는 프론트 담당 (방식 A)
- title 자동 생성: "{genre} — {mood} Mix" 형식으로 개선
- audio_url 절대경로 제거: 항상 /media/music/{task_id}.mp3 상대경로 반환
- status succeeded 시 track 메타데이터 포함 (프론트 Save 버튼 없이 즉시 UI 반영 가능)
- get_track_by_task_id() 함수 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 09:40:37 +09:00
parent 868020f7ed
commit f1e72e2829
2 changed files with 25 additions and 5 deletions

View File

@@ -171,6 +171,12 @@ def delete_track(track_id: int) -> bool:
return True return True
def get_track_by_task_id(task_id: str) -> Optional[Dict[str, Any]]:
with _conn() as conn:
row = conn.execute("SELECT * FROM music_library WHERE task_id = ?", (task_id,)).fetchone()
return _track_row_to_dict(row) if row else None
def get_track_file_path(track_id: int) -> Optional[str]: def get_track_file_path(track_id: int) -> Optional[str]:
with _conn() as conn: with _conn() as conn:
row = conn.execute("SELECT file_path FROM music_library WHERE id = ?", (track_id,)).fetchone() row = conn.execute("SELECT file_path FROM music_library WHERE id = ?", (track_id,)).fetchone()

View File

@@ -10,7 +10,7 @@ from pydantic import BaseModel
from .db import ( from .db import (
init_db, init_db,
create_task, update_task, get_task, create_task, update_task, get_task,
get_all_tracks, add_track, delete_track, get_track_file_path, get_all_tracks, add_track, delete_track, get_track_file_path, get_track_by_task_id,
) )
app = FastAPI() app = FastAPI()
@@ -86,11 +86,15 @@ def _run_generation(task_id: str, params: dict) -> None:
for chunk in resp.iter_content(chunk_size=8192): for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk) f.write(chunk)
audio_url = f"{MUSIC_MEDIA_BASE}/{filename}" # audio_url은 항상 Nginx 상대경로 (Mixed Content 방지)
audio_url = f"/media/music/{filename}"
# 라이브러리 자동 등록 # 라이브러리 자동 등록 — title 자동 생성
genre = params.get("genre", "") genre = params.get("genre", "")
title = f"{genre} {task_id[:8]}" if genre else task_id[:8] moods = params.get("moods", [])
mood_str = moods[0] if moods else "Original"
title = f"{genre}{mood_str} Mix" if genre else f"{mood_str} Mix"
add_track({ add_track({
"title": title, "title": title,
"genre": genre, "genre": genre,
@@ -145,11 +149,13 @@ def get_status(task_id: str):
""" """
생성 작업 상태 조회. 프론트는 succeeded 또는 failed가 될 때까지 폴링. 생성 작업 상태 조회. 프론트는 succeeded 또는 failed가 될 때까지 폴링.
status: queued | processing | succeeded | failed status: queued | processing | succeeded | failed
succeeded 시 track 메타데이터 포함 (라이브러리 별도 저장 불필요).
""" """
task = get_task(task_id) task = get_task(task_id)
if not task: if not task:
raise HTTPException(status_code=404, detail="Task not found") raise HTTPException(status_code=404, detail="Task not found")
return {
resp = {
"status": task["status"], "status": task["status"],
"progress": task["progress"], "progress": task["progress"],
"message": task["message"], "message": task["message"],
@@ -157,6 +163,14 @@ def get_status(task_id: str):
"error": task["error"], "error": task["error"],
} }
# succeeded 시 라이브러리에 저장된 트랙 메타데이터 포함
# 프론트는 이 track 객체로 UI를 바로 업데이트하면 됨 (Save 버튼 불필요)
if task["status"] == "succeeded":
track = get_track_by_task_id(task_id)
resp["track"] = track
return resp
# ── 라이브러리 API ──────────────────────────────────────────────────────────── # ── 라이브러리 API ────────────────────────────────────────────────────────────