-- 사용자 동적 생성 음악 (2026-05-20, BGM Phase 4). -- -- 자유대화 "재즈 스타일 3곡 만들어줘" → 비동기 Lyria 생성 → 개인 라이브러리. -- 글로벌 카탈로그(music_themes)와 별개 — 사용자 소유. 재생 경로는 동일하게 -- 'music' 버킷 signed URL 서빙 (GPU/API 0). -- -- abuse 방지: 사용자별 일일 생성 cap (백엔드 user_music_service 에서 created_at 카운트). -- status: generating(Lyria 호출 중) → ready(파일 있음) → failed(재시도 대상). -- -- 회귀 0: 신규 테이블. RLS owner read/write (백엔드 service_role + user_id 필터 병행). CREATE TABLE IF NOT EXISTS public.user_music ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, title text NOT NULL DEFAULT '', prompt text NOT NULL DEFAULT '', mood_tags text[] NOT NULL DEFAULT '{}', seed bigint, storage_path text, -- 'music' 버킷 상대 경로 (ready 시) duration_sec real, bpm real, lufs real, status text NOT NULL DEFAULT 'generating' CHECK (status IN ('generating', 'ready', 'failed')), error_detail text, created_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS user_music_user_idx ON public.user_music (user_id, created_at DESC); CREATE INDEX IF NOT EXISTS user_music_mood_idx ON public.user_music USING gin (mood_tags); ALTER TABLE public.user_music ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS user_music_owner ON public.user_music; CREATE POLICY user_music_owner ON public.user_music FOR ALL USING (user_id = auth.uid()) WITH CHECK (user_id = auth.uid()); COMMENT ON TABLE public.user_music IS '사용자 동적 생성 음악 (Lyria + auto-loop). 개인 라이브러리. 재생=Storage signed URL.';