Spaces:
Sleeping
Sleeping
File size: 2,300 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 | -- ๋จ๋ง ๋จ์ ์ผ์ผ ํฌ๋ ๋ง ์ฌ์ฉ๋ ์ถ์ (2026-05-06).
--
-- ๋ฐฐ๊ฒฝ: "๊ณ์ ๋น ์ผ 100 ํฌ๋ ๋ง" ์ ์ฑ
์ ๋์ผ ์ฌ์ฉ์๊ฐ Google ๊ณ์ ์ ๋ค์ค
-- ์์ฑํด ๋จ๋ง 1๊ฐ๋ก ๋ฌดํ ํฌ๋ ๋ง ํ๋ ๊ฐ๋ฅ. ์ด๋ทฐ์ฆ ์ฐจ๋จ์ ์ํด
-- (๊ณต์ธ IP + ๋จ๋ง fingerprint) ๋จ์๋ก ์ผ์ผ cap ์ ์ฉ.
--
-- ์ ์ฑ
(services/device_cap_service.py):
-- - Free ์ฌ์ฉ์: ๋จ๋ง๋น ์ผ 100 ํฌ๋ ๋ง ํฉ์ฐ cap
-- - Standard/Pro ๊ฒฐ์ ์ฌ์ฉ์: ๋จ๋ง cap ๋ฉด์ (๊ณ์ cap ๋ง ์ ์ฉ)
--
-- ๋จ๋ง ์๋ณ:
-- - client_ip: ๊ณต์ธ IP (X-Forwarded-For ์๋ฒ ์ธก ์ถ์ถ)
-- - device_fp: frontend ๊ฐ X-Device-FP ํค๋๋ก ์ ์ก (canvas+UA+screen
-- +timezone+lang+hardware ์ข
ํฉ SHA-256 hash)
-- - ๋ณด์กฐ: device_id (localStorage UUID, X-Device-ID ํค๋) โ fp ๋ณด๊ฐ์ฉ
CREATE TABLE IF NOT EXISTS public.device_daily_usage (
id BIGSERIAL PRIMARY KEY,
client_ip TEXT NOT NULL,
device_fp TEXT NOT NULL,
device_id TEXT, -- localStorage UUID (์ ํ)
date DATE NOT NULL, -- KST ๊ธฐ์ค
used_credits INTEGER NOT NULL DEFAULT 0,
last_user_id UUID, -- ๋๋ฒ๊น
์ฉ: ์ต๊ทผ ์ฌ์ฉ ๊ณ์
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS uq_device_daily_usage
ON public.device_daily_usage (client_ip, device_fp, date);
CREATE INDEX IF NOT EXISTS idx_device_daily_usage_date
ON public.device_daily_usage (date DESC);
-- ์ด์ ์์ : 30์ผ ์ด์ ๋ row ์๋ ์ ๋ฆฌ cron ํ์ (services ์ธก). RLS ๋นํ์ฑ
-- (์๋น์ค ๋กค๋ง ์ ๊ทผ, ์ฌ์ฉ์ ์ง์ ์กฐํ ์ ํจ).
ALTER TABLE public.device_daily_usage ENABLE ROW LEVEL SECURITY;
-- ์ ์ฑ
๋ฏธ์ค์ = ์๋น์ค ๋กค๋ง ํต๊ณผ. ์ฌ์ฉ์ SELECT ๋ถ๊ฐ.
-- updated_at ์๋ ๊ฐฑ์ ํธ๋ฆฌ๊ฑฐ
CREATE OR REPLACE FUNCTION public.tg_device_daily_usage_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_device_daily_usage_updated_at ON public.device_daily_usage;
CREATE TRIGGER trg_device_daily_usage_updated_at
BEFORE UPDATE ON public.device_daily_usage
FOR EACH ROW EXECUTE FUNCTION public.tg_device_daily_usage_updated_at();
|