talk / backend /sql /020_care_messages.sql
user
Deploy StyleVoiceChat backend
aa9892b
Raw History Blame Contribute Delete
3.56 kB
-- μ•ˆλΆ€ λ©”μ‹œμ§€ (`/message`) β€” 본인 μŒμƒ‰μœΌλ‘œ κ°€μ‘±/μΉœκ΅¬μ—κ²Œ 보낼 짧은 μŒμ„± λ©”μ‹œμ§€.
--
-- 흐름:
-- 1) μ‚¬μš©μžκ°€ μŒμ„±/ν…μŠ€νŠΈλ‘œ "이런 μ•ˆλΆ€ λ³΄λ‚΄μ€˜" μ§€μ‹œ
-- 2) LLM 이 1~2λ¬Έμž₯ λ³Έλ¬Έ 생성 + μ‚¬μš©μž μŒμƒ‰ ICL TTS ν•©μ„±
-- 3) wav λ₯Ό Supabase Storage (scheduled-audio bucket μž¬μ‚¬μš©) 에 μ—…λ‘œλ“œ
-- 4) μ¦‰μ‹œ 곡유: μ‚¬μš©μžκ°€ 카카였 JS SDK 둜 본인 μΉ΄ν†‘μ—μ„œ κ°€μ‘± μ±„νŒ…λ°© 선택 β†’ /listen/<id> 링크 λ°œμ†‘
-- 5) μ˜ˆμ•½: μ‹œκ° 도달 μ‹œ μ‚¬μš©μž λ³ΈμΈμ—κ²Œ μ•Œλ¦Όν†‘ ("μ€€λΉ„λμ–΄μš”. κ³΅μœ ν•˜κΈ°") β†’ 클릭 β†’ /listen/<id> νŽ˜μ΄μ§€μ˜
-- [κ³΅μœ ν•˜κΈ°] λ²„νŠΌ β†’ 카톑 곡유
--
-- λ°œμ‹ μ€ 항상 μ‚¬μš©μž 본인 β€” μ•Œλ¦Όν†‘μ€ μ‚¬μš©μž μžμ‹ μ—κ²Œλ§Œ λ°œμ†‘ (μ •μ±… μ•ˆμ „), κ°€μ‘±μ—κ²ŒλŠ” μ‚¬μš©μž μΉ΄ν†‘μœΌλ‘œ 직접.
-- λ°›λŠ” μ‚¬λžŒ 번호 μˆ˜μ§‘ μ—†μŒ (PIPA λΆ€λ‹΄ νšŒν”Ό). recipient_label 은 μ‚¬μš©μžκ°€ 자기만 μ•Œμ•„λ³΄λŠ” λ©”λͺ¨.
CREATE TABLE IF NOT EXISTS public.care_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- μž…λ ₯
recipient_label TEXT NOT NULL DEFAULT '', -- "μ–΄λ¨Έλ‹ˆ" / "μ•„λΉ " λ“± μ‚¬μš©μž λ©”λͺ¨
voice_input_text TEXT, -- STT λ˜λŠ” 직접 μž…λ ₯ν•œ μ§€μ‹œλ¬Έ (이λ ₯)
-- μƒμ„±λœ κ²°κ³Ό
generated_text TEXT NOT NULL DEFAULT '', -- LLM 이 λ§Œλ“  λ³Έλ¬Έ (μ‹€μ œ μŒμ„± ν…μŠ€νŠΈ)
audio_file_path TEXT, -- storage 경둜 (μ‚­μ œμš©)
audio_file_url TEXT, -- 1λ…„ signed URL (λͺ©λ‘ 미리듣기)
voice_storage_path TEXT, -- 합성에 μ‚¬μš©ν•œ μ‚¬μš©μž μŒμƒ‰ (μž¬ν•©μ„± 좔적)
-- μ˜ˆμ•½ (NULL = μ¦‰μ‹œ 곡유, μ˜ˆμ•½ μ—†μŒ)
scheduled_at TIMESTAMPTZ,
timezone TEXT NOT NULL DEFAULT 'Asia/Seoul',
next_fire_at TIMESTAMPTZ,
last_fired_at TIMESTAMPTZ,
active BOOLEAN NOT NULL DEFAULT TRUE,
-- 뢄석
shared_at TIMESTAMPTZ, -- μ‚¬μš©μžκ°€ [κ³΅μœ ν•˜κΈ°] λ²„νŠΌ λˆ„λ₯Έ μ‹œκ°
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_care_messages_user
ON public.care_messages (user_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_care_messages_due
ON public.care_messages (active, next_fire_at)
WHERE next_fire_at IS NOT NULL;
ALTER TABLE public.care_messages ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS care_messages_owner ON public.care_messages;
CREATE POLICY care_messages_owner ON public.care_messages
FOR ALL
USING (user_id = auth.uid())
WITH CHECK (user_id = auth.uid());
-- updated_at μžλ™ κ°±μ‹ 
CREATE OR REPLACE FUNCTION public._care_messages_touch_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS care_messages_touch_updated_at ON public.care_messages;
CREATE TRIGGER care_messages_touch_updated_at
BEFORE UPDATE ON public.care_messages
FOR EACH ROW EXECUTE FUNCTION public._care_messages_touch_updated_at();
-- ───────── Storage μ •μ±… ─────────
-- scheduled-audio bucket μž¬μ‚¬μš© (sql/016 μ—μ„œ 이미 생성). 같은 폴더 (<user_id>/)
-- μ•ˆμ— care λ©”μ‹œμ§€ wav λ₯Ό λ‘λ―€λ‘œ μΆ”κ°€ μ •μ±… λΆˆν•„μš”.
-- care 파일λͺ… μ»¨λ²€μ…˜: <user_id>/care-<message_id>-<timestamp>.wav