Spaces:
Sleeping
Sleeping
File size: 3,251 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 | -- μΉ΄ν μμ± μ λ¬ΌμΏ ν° MVP β gift_coupons (2026-05-28, P1a Phase B)
--
-- λ°νλ μΏ ν° = κ²°μ μλ£ β λ°λμ΄ νΌμΉ¨ β λ§€μ₯ μ¬μ©μ²λ¦¬.
-- μμ²μ: doc/runbook/req_cafe_gift_mvp.md Β§1
-- μ€κ³: doc/runbook/cafe_gift_p1a.md Β§2 sql/049
--
-- λΆλ¦¬λ ν ν° (Plan κ²°μ #2, #6):
-- - code: 8μ μμ«μ (O/0/I/1 μ μΈ, μνλ²³ 32) β λ§€μ₯ μ§μ μκΈ° μ
λ ₯μ©
-- - reveal_token: 32 byte hex (DB default) β λ°λμ΄ /g/<token> reveal μ§μ
μ©
-- - λ λ€ unguessable + λΆλ¦¬ = code λ
ΈμΆ μ reveal_token μμ , reveal μ code μ λ
ΈμΆ κ°λ₯
--
-- λ§λ£:
-- - expires_at = gift_orders.expires_at λ³΅μ¬ (λ°±μλκ° set, μ μ±
λ³κ²½ μΆμ )
-- - status='expired' μλ μ μ΄λ cron (νμ), P1a λ λΌμ΄λΈ μ‘°ν μ λ§λ£ κ²μ¬
--
-- β νκ· κ°λ: μ κ· ν
μ΄λΈ. RLS cafe owner only (μ¬μ₯ redeem κΆν).
CREATE TABLE IF NOT EXISTS public.gift_coupons (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
order_id UUID NOT NULL UNIQUE REFERENCES public.gift_orders(id) ON DELETE CASCADE,
cafe_id UUID NOT NULL REFERENCES public.cafe_merchants(id) ON DELETE RESTRICT,
-- λ§€μ₯ μ§μ μκΈ° μ
λ ₯μ© (μ¬λμ΄ μ½κΈ° μ¬μ΄ μ½λ)
code TEXT NOT NULL UNIQUE,
-- λ°λμ΄ νΌμΉ¨μ© (λ°±μλκ° μμ±, μΆμΈ‘ λΆκ°)
reveal_token TEXT NOT NULL UNIQUE
DEFAULT encode(gen_random_bytes(20), 'hex'),
status TEXT NOT NULL DEFAULT 'issued'
CHECK (status IN ('issued','viewed','redeemed','expired','refunded')),
viewed_at TIMESTAMPTZ, -- λ°λμ΄κ° /g/<token> 첫 μ§μ
μκ°
redeemed_at TIMESTAMPTZ,
redeemed_by UUID REFERENCES auth.users(id) ON DELETE SET NULL, -- μ¬μ©μ²λ¦¬ν λ§€μ₯ μ§μ
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL -- order.expires_at λ³΅μ¬ (λ°±μλ μΈν
)
);
CREATE INDEX IF NOT EXISTS idx_gift_coupons_cafe_status
ON public.gift_coupons (cafe_id, status, created_at DESC);
ALTER TABLE public.gift_coupons ENABLE ROW LEVEL SECURITY;
-- μ¬μ₯: λ³ΈμΈ μΉ΄ν μΏ ν° SELECT + UPDATE (redeem)
DROP POLICY IF EXISTS gift_coupons_cafe_rw ON public.gift_coupons;
CREATE POLICY gift_coupons_cafe_rw ON public.gift_coupons FOR ALL
USING (cafe_id IN (
SELECT id FROM public.cafe_merchants WHERE owner_user_id = auth.uid()
))
WITH CHECK (cafe_id IN (
SELECT id FROM public.cafe_merchants WHERE owner_user_id = auth.uid()
));
-- INSERT λ λ°±μλ service-role (gift_order_service.mock_pay κ° λ°κΈ)
-- reveal_token μ‘°νλ λ°±μλ service-role (gift_reveal λΌμ°ν° β Phase C)
COMMENT ON TABLE public.gift_coupons IS
'λ°ν μΏ ν°. code = λ§€μ₯ μ§μ μ
λ ₯μ© 8μ μμ«μ. reveal_token = λ°λμ΄ νΌμΉ¨μ© hex.';
COMMENT ON COLUMN public.gift_coupons.code IS
'8μ μμ«μ μνλ²³ ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (O/0/I/1 μ μΈ, κ°λ
μ±). λ°±μλ μμ± + UNIQUE μΆ©λ μ¬μλ.';
COMMENT ON COLUMN public.gift_coupons.reveal_token IS
'32 byte hex. λ°λμ΄ /g/<token> μ§μ
. λ°±μλλ§ service-role λ‘ μ‘°ν.';
|