77 lines
3.7 KiB
SQL
77 lines
3.7 KiB
SQL
-- ============================================================
|
|
-- Migration 006: Referral System Tables
|
|
-- All tables in public schema (cross-tenant, like billing)
|
|
-- ============================================================
|
|
|
|
-- 1. Referral codes — one per tenant, auto-generated on registration
|
|
CREATE TABLE IF NOT EXISTS public.referral_codes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id VARCHAR(100) NOT NULL UNIQUE,
|
|
user_id VARCHAR(100) NOT NULL,
|
|
code VARCHAR(20) NOT NULL UNIQUE,
|
|
click_count INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_referral_codes_code ON public.referral_codes (code);
|
|
CREATE INDEX IF NOT EXISTS idx_referral_codes_tenant ON public.referral_codes (tenant_id);
|
|
|
|
-- 2. Referral relationships — tracks who referred whom (tenant level)
|
|
CREATE TABLE IF NOT EXISTS public.referral_relationships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
referrer_tenant_id VARCHAR(100) NOT NULL,
|
|
referred_tenant_id VARCHAR(100) NOT NULL UNIQUE, -- one referrer per tenant
|
|
referral_code VARCHAR(20) NOT NULL,
|
|
level INT NOT NULL DEFAULT 1, -- 1=direct, 2=indirect
|
|
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
|
registered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
activated_at TIMESTAMPTZ,
|
|
rewarded_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_referral_rel_referrer ON public.referral_relationships (referrer_tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_referral_rel_status ON public.referral_relationships (status);
|
|
CREATE INDEX IF NOT EXISTS idx_referral_rel_referred ON public.referral_relationships (referred_tenant_id);
|
|
|
|
-- 3. Referral rewards — credit records for each tenant
|
|
CREATE TABLE IF NOT EXISTS public.referral_rewards (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
beneficiary_tenant_id VARCHAR(100) NOT NULL,
|
|
referral_relationship_id UUID NOT NULL REFERENCES public.referral_relationships(id),
|
|
reward_type VARCHAR(20) NOT NULL, -- CREDIT | PERCENTAGE
|
|
trigger_type VARCHAR(20) NOT NULL, -- FIRST_PAYMENT | RECURRING
|
|
amount_cents INT NOT NULL,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
|
invoice_id VARCHAR(100),
|
|
source_invoice_id VARCHAR(100),
|
|
recurring_month INT,
|
|
expires_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
applied_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_referral_rewards_beneficiary ON public.referral_rewards (beneficiary_tenant_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_referral_rewards_relationship ON public.referral_rewards (referral_relationship_id);
|
|
|
|
-- 4. Referral stats — denormalized cache per tenant
|
|
CREATE TABLE IF NOT EXISTS public.referral_stats (
|
|
tenant_id VARCHAR(100) PRIMARY KEY,
|
|
direct_count INT NOT NULL DEFAULT 0,
|
|
active_count INT NOT NULL DEFAULT 0,
|
|
total_credit_earned INT NOT NULL DEFAULT 0,
|
|
total_credit_applied INT NOT NULL DEFAULT 0,
|
|
pending_credit INT NOT NULL DEFAULT 0,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- 5. Processed events — idempotency for Redis Stream consumers
|
|
CREATE TABLE IF NOT EXISTS public.referral_processed_events (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
event_id VARCHAR(255) NOT NULL UNIQUE,
|
|
event_type VARCHAR(100) NOT NULL,
|
|
processed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_referral_processed_events_event_id ON public.referral_processed_events (event_id);
|