talk / backend /sql /009_age_verification.sql
user
Deploy StyleVoiceChat backend
aa9892b
Raw History Blame Contribute Delete
2.88 kB
-- 18+ ์—ฐ๋ น ์ธ์ฆ (2026-05-03)
--
-- ์„ฑ์ธ ๋Œ€ํ™” ๋ชจ๋“œ(spice_level=hot) ๋ฐ ์ž์œ ๋Œ€ํ™” ์ฑ„ํŒ…ยท์Œ์„ฑ ์ง„์ž… ์‹œ ํ•„์š”ํ•œ
-- ์ž๊ฐ€ ์ธ์ฆ(self-attestation) + ๋™์˜ ๋กœ๊ทธ ๋ณด๊ด€.
--
-- ํ–ฅํ›„ ์ •์‹ ๋ณธ์ธ์ธ์ฆ(๋‹ค๋‚ ยทPASS ๋“ฑ) ํ†ตํ•ฉ ์ž๋ฆฌ ๋งˆ๋ จ. method ์ปฌ๋Ÿผ์ด ์ธ์ฆ ์ˆ˜๋‹จ์„ ๊ตฌ๋ถ„.
--
-- ํ•œ๊ตญ ์ •๋ณดํ†ต์‹ ๋ง๋ฒ• / ์ผ๋ณธ ํŠน์ƒ๋ฒ•(JP ํ™•์žฅ ์‹œ) ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ์ตœ์†Œ ์š”๊ฑด:
-- - ๋ช…์‹œ์  ๋™์˜ ์‹œ์  ๊ธฐ๋ก (verified_at)
-- - ๋™์˜ ์‹œ IPยทuser_agent ๊ธฐ๋ก (๋ถ„์Ÿ ์‹œ ์ž…์ฆ)
-- - ๋™์˜ ๋ณธ๋ฌธ์˜ ๋ฒ„์ „ ์ถ”์  (consent_text_version) โ€” ์•ฝ๊ด€ ๋ณ€๊ฒฝ ์‹œ ์žฌ๋™์˜ ํŠธ๋ฆฌ๊ฑฐ
-- - ์ฒ ํšŒ(revoke) ๊ฐ€๋Šฅ์„ฑ โ€” ์‚ฌ์šฉ์ž ์š”์ฒญ ์‹œ ์ฆ‰์‹œ ๋ฌดํšจํ™”
CREATE TABLE IF NOT EXISTS public.user_age_verifications (
user_id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
verified BOOLEAN NOT NULL DEFAULT false,
verified_at TIMESTAMPTZ,
method VARCHAR(32) NOT NULL DEFAULT 'self_attestation',
-- 'self_attestation' | 'danal_phone' | 'pass' | 'ipin' (ํ™•์žฅ ์ž๋ฆฌ)
ip_address INET,
user_agent TEXT,
consent_text_version VARCHAR(16) NOT NULL DEFAULT 'v1',
revoked_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- RLS: ๋ณธ์ธ๋งŒ ์กฐํšŒ, service_role(๋ฐฑ์—”๋“œ)๋งŒ ์ˆ˜์ •
ALTER TABLE public.user_age_verifications ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own age verification" ON public.user_age_verifications
FOR SELECT USING (auth.uid() = user_id);
-- ๋™์˜ ์ด๋ ฅ ๋กœ๊ทธ (๊ฐ์‚ฌ์šฉ โ€” ๋™์˜ยท์ฒ ํšŒยท์žฌ๋™์˜ ๋ชจ๋‘ ์ถ”์ )
CREATE TABLE IF NOT EXISTS public.age_verification_logs (
id BIGSERIAL PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
event VARCHAR(16) NOT NULL, -- 'verified' | 'revoked' | 're_verified'
method VARCHAR(32) NOT NULL DEFAULT 'self_attestation',
ip_address INET,
user_agent TEXT,
consent_text_version VARCHAR(16) NOT NULL DEFAULT 'v1',
detail JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_age_verification_logs_user
ON public.age_verification_logs(user_id, created_at DESC);
ALTER TABLE public.age_verification_logs ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own age logs" ON public.age_verification_logs
FOR SELECT USING (auth.uid() = user_id);
-- updated_at ์ž๋™ ๊ฐฑ์‹  trigger
CREATE OR REPLACE FUNCTION public.tg_age_verifications_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_age_verifications_updated_at ON public.user_age_verifications;
CREATE TRIGGER trg_age_verifications_updated_at
BEFORE UPDATE ON public.user_age_verifications
FOR EACH ROW EXECUTE FUNCTION public.tg_age_verifications_updated_at();