Spaces:
Sleeping
Sleeping
File size: 4,006 Bytes
aa9892b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | -- ์นดํ ์์ฑ ์ ๋ฌผ์ฟ ํฐ MVP โ cafe_merchants (2026-05-28, P1a Phase A)
--
-- ์นดํ ์ฌ์ฅ์ด ๋ณธ์ธ ์นดํ๋ฅผ ๋ฑ๋กํ๋ ๋ฐํ์ ํ
์ด๋ธ.
-- ์์ฒญ์: doc/runbook/req_cafe_gift_mvp.md ยง1
-- ์ค๊ณ: doc/runbook/cafe_gift_p1a.md ยง2 sql/045
--
-- ํต์ฌ:
-- - ์นดํ = ์ฟ ํฐ ๋ฐํ์ยทํ๋งค ๋น์ฌ์ (๋จ์ผ๊ฐ๋งน์ โ ์ ๋ถ์
๋ฉด์ )
-- - status='draft' ์
ํ๋ฑ๋ก / status='active' ์ด์์(icesgg) ์๋ ์ ํ (P1a ๋ SQL UPDATE)
-- - ํต์ ํ๋งค์ค๊ฐ ๊ณ ์ง ์๋ฌด ํ๋(์ํธ/๋ํ/์ฃผ์/์ ํ/์ฌ์
์๋ฒํธ/ํต์ ํ๋งค์ ๊ณ ๋ฒํธ)
-- - brand_voice = '__default__' or '__spk__<code>' (P1a ๋ ๋ด์ฅํ์๋ง, voice_clone P2)
--
-- โ ํ๊ท ๊ฐ๋:
-- - 2026-05-27 sql/043 ์ฌ๊ณ ๊ตํ โ ์ ๊ท ํ
์ด๋ธ, ๊ธฐ์กด CHECK ์์ X
-- - CHECK ๋ชจ๋ ์ ๊ท ์ปฌ๋ผ only + nullable/default ๋ช
์
-- - RLS ํ์ฑ + owner-scoped + ๊ณต๊ฐ read ๋ status='active' ๋ง
CREATE TABLE IF NOT EXISTS public.cafe_merchants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
owner_user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- ๋จ์ถ URL์ฉ (P1a ๋ ๋ฏธ์ฌ์ฉ NULL, P2 ์ ๋์
)
slug TEXT UNIQUE,
-- ๊ณต๊ฐ ๋
ธ์ถ + ํต์ ํ๋งค์ค๊ฐ ๊ณ ์ง (์์ฒญ์ ยง0-1 #3)
name TEXT NOT NULL, -- ์ํธ๋ช
representative TEXT, -- ๋ํ์๋ช
address TEXT, -- ์ฌ์
์ฅ ์ฃผ์
phone TEXT, -- ์ฐ๋ฝ์ฒ
business_no TEXT, -- ์ฌ์
์๋ฑ๋ก๋ฒํธ
telesales_no TEXT, -- ํต์ ํ๋งค์ ๊ณ ๋ฒํธ (P1b ํ์)
-- ๊ฒฐ์ (P1b ์์ ์ฑ์)
pg_submerchant_id TEXT,
-- ์์ฑํธ์ง ๊ธฐ๋ณธ ๋ณด์ด์ค โ ์๋์ด ๋ณ๊ฒฝ ๊ฐ๋ฅ (Plan ๊ฒฐ์ #10)
brand_voice TEXT NOT NULL DEFAULT '__default__',
-- ์ด์์ ๊ฒ์ดํธ (์ฌ์ฉ์ ๊ฒฐ์ #2 โ draft ์
ํ๋ฑ๋ก + admin ์๋ active)
status TEXT NOT NULL DEFAULT 'draft'
CHECK (status IN ('draft','active','suspended')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_cafe_merchants_owner
ON public.cafe_merchants (owner_user_id);
CREATE INDEX IF NOT EXISTS idx_cafe_merchants_status
ON public.cafe_merchants (status);
ALTER TABLE public.cafe_merchants ENABLE ROW LEVEL SECURITY;
-- ์ฌ์ฅ: ๋ณธ์ธ ์นดํ ALL
DROP POLICY IF EXISTS cafe_merchants_owner ON public.cafe_merchants;
CREATE POLICY cafe_merchants_owner ON public.cafe_merchants
FOR ALL
USING (owner_user_id = auth.uid())
WITH CHECK (owner_user_id = auth.uid());
-- ๊ณต๊ฐ: status='active' ๋ง SELECT (์ค๊ฐ ๊ณ ์งยท๊ตฌ๋งค ํ์ด์ง์ฉ, anon ๊ฐ๋ฅ)
DROP POLICY IF EXISTS cafe_merchants_public_read ON public.cafe_merchants;
CREATE POLICY cafe_merchants_public_read ON public.cafe_merchants
FOR SELECT
USING (status = 'active');
CREATE OR REPLACE FUNCTION public._cafe_merchants_touch_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS cafe_merchants_touch_updated_at ON public.cafe_merchants;
CREATE TRIGGER cafe_merchants_touch_updated_at
BEFORE UPDATE ON public.cafe_merchants
FOR EACH ROW EXECUTE FUNCTION public._cafe_merchants_touch_updated_at();
COMMENT ON TABLE public.cafe_merchants IS
'์นดํ ์์ฑ ์ ๋ฌผ์ฟ ํฐ ๋ฐํ์. ๋จ์ผ๊ฐ๋งน์ ์ ๋ถ์
๋ฉด์ . status=draft ์
ํ๋ฑ๋ก โ admin ์๋ active.';
COMMENT ON COLUMN public.cafe_merchants.brand_voice IS
'์์ฑํธ์ง ๊ธฐ๋ณธ ๋ณด์ด์ค: __default__ (Sohee) ๋๋ __spk__<code> (๋ด์ฅํ์ 8์ข
). ์๋์ด ๊ตฌ๋งค ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ.';
COMMENT ON COLUMN public.cafe_merchants.status IS
'draft: ์
ํ๋ฑ๋ก ์งํ / active: ์ด์์ ๊ฒ์ฆยท๊ฒ์ / suspended: ์ด์์ ์ ์ง.';
|