Spaces:
Sleeping
Sleeping
Download backend/sql/026_care_recipients.sql from stylevoice/talk: direct link, hf CLI and curl.
- Browser
- Download file 6.07 kB
-
https://huggingface.co/spaces/stylevoice/talk/resolve/main/backend/sql/026_care_recipients.sql
- Command line
-
hf download hf://spaces/stylevoice/talk/backend/sql/026_care_recipients.sql
-
curl -L -o 026_care_recipients.sql https://huggingface.co/spaces/stylevoice/talk/resolve/main/backend/sql/026_care_recipients.sql
6.07 kB
| -- μλΆ λ©μμ§ κ°μ‘± μμ μ + care_messages νμ₯ (2026-05-12, care_redesign Phase 2) | |
| -- | |
| -- Phase 2 ν΅μ¬: | |
| -- - κ°μ‘± μμ μ (`care_recipients`) β λΌλ²¨/μ νλ²νΈ/μμ±μ¬λ‘―/λ°μ‘μκ°/1ν|0ν λͺ¨λ. | |
| -- - λ§€μΌ KST T-30λΆ μλ λ³Έλ¬Έμμ±+TTS β care_messages ν INSERT (status='ready'). | |
| -- - 1ν λͺ¨λ: T-0 λΆ μ¬μ©μμκ² T1 μλ¦Όν‘ β μ¬μ©μκ° [보λ΄κΈ°] λλ₯΄λ©΄ T3 μλ¦Όν‘ λ°μ‘. | |
| -- - κ°μ‘±μ΄ /listen/<care_id> ν΄λ¦ β listened_at μ±μμ§ β λ°μ μμκ² T4 μλ¦Όν‘. | |
| -- | |
| -- νκ· κ°λ λ³κ²½: | |
| -- - κ°μ‘± λ²νΈ μμ§ OK (μ΄μ μ μ± νκΈ°, doc/runbook/care_redesign.md μ°Έμ‘°) | |
| -- - μ°λ¦¬ μ¬μ μ μλ¦Όν‘μΌλ‘ κ°μ‘±μκ² μ§λ°μ‘ OK | |
| -- | |
| -- μν°-μ€ν νΉ (Phase 4 μμ κ°ν): care_blacklist μΆκ° μμ , λ³Έ migration μμ | |
| -- κ΅¬μ‘°λ§ μ€λΉ. | |
| CREATE TABLE IF NOT EXISTS public.care_recipients ( | |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, | |
| -- κ°μ‘± μλ³ | |
| label TEXT NOT NULL, -- 'μλ§', 'μλΉ ', 'μμ΄λ¨Έλ' λ± μμ | |
| phone_e164 TEXT NOT NULL, -- +8210xxxxxxxx (μ κ·ν ν μ μ₯) | |
| -- λ°μ‘ μ€μ | |
| voice_slot_kind TEXT NOT NULL DEFAULT 'self' | |
| CHECK (voice_slot_kind IN ('self','son','daughter')), | |
| schedule_mode TEXT NOT NULL DEFAULT '1tap' | |
| CHECK (schedule_mode IN ('1tap','0tap')), | |
| send_time_kst TIME NOT NULL DEFAULT '09:00', -- KST κΈ°μ€ μΌμΌ λ°μ‘ μκ° | |
| -- κ°μ‘± λμ | |
| consent_status TEXT NOT NULL DEFAULT 'active' | |
| CHECK (consent_status IN ('active','opted_out','blocked')), | |
| social_consent_confirmed BOOLEAN NOT NULL DEFAULT FALSE, -- λ±λ‘ μ "λΆλͺ¨λκ» μν΄ κ΅¬ν¨" μ²΄ν¬ | |
| -- μ΅νΈμμ (Phase 4) | |
| optout_token TEXT NOT NULL DEFAULT encode(gen_random_bytes(16), 'hex') UNIQUE, | |
| opted_out_at TIMESTAMPTZ, | |
| -- νμ± ν κΈ (μ¬μ©μκ° μΌμ μ μ§ κ°λ₯) | |
| active BOOLEAN NOT NULL DEFAULT TRUE, | |
| -- λ€μ λ°μ‘ μμ μκ° (UTC). cron tick μ΄ μ΄κ±Έ λ³΄κ³ due λ°μ¬. | |
| next_prep_at TIMESTAMPTZ, -- λ³Έλ¬Έμμ±+TTS μμ μκ° (T-30λΆ) | |
| created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), | |
| updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() | |
| ); | |
| CREATE INDEX IF NOT EXISTS idx_care_recipients_user | |
| ON public.care_recipients (user_id, created_at DESC); | |
| CREATE INDEX IF NOT EXISTS idx_care_recipients_due_prep | |
| ON public.care_recipients (active, next_prep_at) | |
| WHERE active = TRUE AND consent_status = 'active' AND next_prep_at IS NOT NULL; | |
| -- ν μ¬μ©μ + κ°μ μ νλ²νΈ μ€λ³΅ λ±λ‘ λ°©μ§ (λΌλ²¨λ§ λ€λ₯΄λ©΄ λ³λ λ±λ‘ κ°λ₯νκ² λλ κ² | |
| -- 보ν΅μ΄μ§λ§, μν°-μ€ν νΉ κ΄μ μμ κ°μ κ°μ‘±μκ² 2κ° row λ³΄λΌ μΌμ μμ). | |
| CREATE UNIQUE INDEX IF NOT EXISTS care_recipients_user_phone_uniq | |
| ON public.care_recipients (user_id, phone_e164); | |
| ALTER TABLE public.care_recipients ENABLE ROW LEVEL SECURITY; | |
| DROP POLICY IF EXISTS care_recipients_owner ON public.care_recipients; | |
| CREATE POLICY care_recipients_owner ON public.care_recipients | |
| FOR ALL | |
| USING (user_id = auth.uid()) | |
| WITH CHECK (user_id = auth.uid()); | |
| CREATE OR REPLACE FUNCTION public._care_recipients_touch_updated_at() | |
| RETURNS TRIGGER AS $$ | |
| BEGIN | |
| NEW.updated_at = NOW(); | |
| RETURN NEW; | |
| END; | |
| $$ LANGUAGE plpgsql; | |
| DROP TRIGGER IF EXISTS care_recipients_touch_updated_at ON public.care_recipients; | |
| CREATE TRIGGER care_recipients_touch_updated_at | |
| BEFORE UPDATE ON public.care_recipients | |
| FOR EACH ROW EXECUTE FUNCTION public._care_recipients_touch_updated_at(); | |
| -- βββββββββ care_messages νμ₯ βββββββββ | |
| -- | |
| -- κΈ°μ‘΄ μ»¬λΌ (recipient_label, generated_text, audio_file_*, scheduled_at, active λ±) μ μ§. | |
| -- μ νλ¦μ `recipient_id` κ° μ±μμ§λ©΄ "Phase 2 μλ νλ¦" μΌλ‘ κ°μ£Ό, NULL μ΄λ©΄ κΈ°μ‘΄ | |
| -- μ¦μ-μμ± νλ¦ (μ¬μ©μ μΉ΄ν‘ picker) μΌλ‘ νΈν μ μ§. | |
| ALTER TABLE public.care_messages | |
| ADD COLUMN IF NOT EXISTS recipient_id UUID REFERENCES public.care_recipients(id) ON DELETE SET NULL, | |
| ADD COLUMN IF NOT EXISTS scheduled_for TIMESTAMPTZ, -- κ°μ‘± λ°μ‘ μμ μκ° (UTC) | |
| ADD COLUMN IF NOT EXISTS listened_at TIMESTAMPTZ, -- κ°μ‘± ν΄λ¦ β /listen μ§μ μκ° | |
| ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'ready' | |
| CHECK (status IN ('ready','sent','canceled','failed')), | |
| ADD COLUMN IF NOT EXISTS sent_at TIMESTAMPTZ, -- T3 λ°μ‘ μ±κ³΅ μκ° | |
| ADD COLUMN IF NOT EXISTS listened_notified_at TIMESTAMPTZ; -- T4 λ°μ μ μλ¦Ό λ°μ‘ μκ° | |
| CREATE INDEX IF NOT EXISTS idx_care_messages_recipient_status | |
| ON public.care_messages (recipient_id, status, created_at DESC) | |
| WHERE recipient_id IS NOT NULL; | |
| -- κ°μ‘±λ³ + λ μ§λ³ 1νλ§ μ μ§ (κ°μ λ μ€λ³΅ prep λ°©μ§). | |
| -- KST μμ κΈ°μ€μ΄ μλλΌ created_at μ date λ¨μ β λ§€μΌ cron μ΄ ν λ²λ§ λ§λ λ€. | |
| CREATE UNIQUE INDEX IF NOT EXISTS care_messages_recipient_day_uniq | |
| ON public.care_messages (recipient_id, (date_trunc('day', created_at AT TIME ZONE 'Asia/Seoul'))) | |
| WHERE recipient_id IS NOT NULL; | |
| COMMENT ON TABLE public.care_recipients IS | |
| 'μλΆ λ©μμ§ κ°μ‘± μμ μ. μ°λ¦¬ μ¬μ μ μλ¦Όν‘μΌλ‘ μ§μ λ°μ‘. μ΅νΈμμ ν ν° ν¬ν¨.'; | |
| COMMENT ON COLUMN public.care_messages.recipient_id IS | |
| 'NULL = κΈ°μ‘΄ μ¦μ-μμ± νλ¦ (μ¬μ©μ μΉ΄ν‘ picker). NOT NULL = Phase 2 μλ νλ¦.'; | |
| COMMENT ON COLUMN public.care_messages.status IS | |
| 'ready: prep μλ£, λ°μ‘ λκΈ° | sent: T3 λ°μ‘ μλ£ | canceled: μ¬μ©μ μ·¨μ | failed: λ°μ‘ μ€ν¨'; | |