talk / backend /sql /036_music_timelines.sql
user
Deploy StyleVoiceChat backend
aa9892b
Raw History Blame Contribute Delete
3.38 kB
-- 카페 BGM μ—°μ†μž¬μƒ νƒ€μž„λΌμΈ (2026-05-20, BGM Phase 2).
--
-- 점주가 [μ›°μ»΄ 멘트 TTS] β†’ [BGM] β†’ [신메뉴 멘트 TTS] β†’ [BGM] ... λ₯Ό μˆœμ„œλŒ€λ‘œ μ‘°ν•©.
-- κΈ°μ‘΄ playlists(sql/013, μ˜ˆμ•½λ°©μ†‘ μ „μš©)와 λ³„κ°œ β€” BGM μ „μš© μ‹ κ·œ ν…Œμ΄λΈ”.
--
-- 핡심 원칙(μž¬μƒ 경둜 GPU 0):
-- - bgm 슬둯 = music_themes(κΈ€λ‘œλ²Œ) λ˜λŠ” user_music(Phase 4) μ°Έμ‘° β†’ Storage 파일.
-- - tts_ment 슬둯 = 멘트 ν…μŠ€νŠΈλ₯Ό **사전 생성**(νƒ€μž„λΌμΈ μ €μž₯/νŽΈμ§‘ μ‹œ TTS 1회) β†’
-- ment_audio_path 에 μ €μž₯. μž¬μƒ μ‹œμ—” 이 파일만 μ„œλΉ™ (μ‹€μ‹œκ°„ TTS μ•„λ‹˜).
-- ment_status: pending(생성 λŒ€κΈ°) β†’ ready(파일 있음) β†’ failed(μž¬μ‹œλ„ λŒ€μƒ).
--
-- νšŒκ·€ 0: μ‹ κ·œ ν…Œμ΄λΈ” β€” κΈ°μ‘΄ TTS/voice/playlist/care/music_themes 영ν–₯ μ—†μŒ.
-- RLS: μ†Œμœ μžλ§Œ read/write (λ°©μ–΄). λ°±μ—”λ“œλŠ” service_role + user_id ν•„ν„° 병행.
CREATE TABLE IF NOT EXISTS public.music_timelines (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name text NOT NULL DEFAULT 'λ‚΄ 카페 BGM',
is_active boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS public.timeline_items (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
timeline_id uuid NOT NULL REFERENCES public.music_timelines(id) ON DELETE CASCADE,
position integer NOT NULL, -- μž¬μƒ μˆœμ„œ (0-based)
item_type text NOT NULL CHECK (item_type IN ('bgm', 'tts_ment')),
-- bgm 슬둯
music_theme_id uuid REFERENCES public.music_themes(id) ON DELETE SET NULL,
-- tts_ment 슬둯 (사전 생성 β†’ 파일 μž¬μƒ)
ment_text text,
ment_voice text, -- μŒμƒ‰/μŠ€ν”Όμ»€ ν‚€
ment_audio_path text, -- μƒμ„±λœ 멘트 μ˜€λ””μ˜€ ('music' 버킷 μƒλŒ€ 경둜)
ment_status text NOT NULL DEFAULT 'pending'
CHECK (ment_status IN ('pending', 'ready', 'failed')),
settings jsonb NOT NULL DEFAULT '{}', -- loop/gap/volume λ“± μŠ¬λ‘―λ³„ μ˜΅μ…˜
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS timeline_items_timeline_pos_idx
ON public.timeline_items (timeline_id, position);
CREATE INDEX IF NOT EXISTS music_timelines_user_idx
ON public.music_timelines (user_id, updated_at DESC);
ALTER TABLE public.music_timelines ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.timeline_items ENABLE ROW LEVEL SECURITY;
-- μ†Œμœ μžλ§Œ μ ‘κ·Ό (λ°±μ—”λ“œ service_role 은 RLS bypass β€” μΆ”κ°€ λ°©μ–΄μ„ ).
DROP POLICY IF EXISTS music_timelines_owner ON public.music_timelines;
CREATE POLICY music_timelines_owner ON public.music_timelines
FOR ALL USING (user_id = auth.uid()) WITH CHECK (user_id = auth.uid());
DROP POLICY IF EXISTS timeline_items_owner ON public.timeline_items;
CREATE POLICY timeline_items_owner ON public.timeline_items
FOR ALL USING (
EXISTS (SELECT 1 FROM public.music_timelines t
WHERE t.id = timeline_items.timeline_id AND t.user_id = auth.uid())
);
COMMENT ON TABLE public.music_timelines IS
'카페 BGM μ—°μ†μž¬μƒ νƒ€μž„λΌμΈ (멘트 TTS + BGM). μž¬μƒ=Storage 파일 μ„œλΉ™.';