61 lines
2.7 KiB
SQL
61 lines
2.7 KiB
SQL
-- Pricing slot / beta-lock metadata.
|
|
--
|
|
-- 2-product launch decision (Session 7h): VYNDR ($14.99/mo, tier=analyst)
|
|
-- and VYNDR Desk ($44.99/mo, tier=desk). No early-bird tier — the beta
|
|
-- price IS the locked-in price.
|
|
--
|
|
-- This table exists so the frontend pricing page can read live counts
|
|
-- ("147 of unlimited slots taken at beta price") and so the webhook
|
|
-- can record which Stripe price a subscription was created on. Keep
|
|
-- early_bird_limit nullable for now; we may slot it in later.
|
|
--
|
|
-- RUN THIS IN THE SUPABASE SQL EDITOR. Do NOT add it to the migrations
|
|
-- chain — it's intentionally out-of-band per session policy.
|
|
|
|
CREATE TABLE IF NOT EXISTS public.pricing_slots (
|
|
tier text PRIMARY KEY,
|
|
beta_price_id text,
|
|
beta_price_usd numeric,
|
|
-- Reserved for a future "first N seats" promo; null means no cap.
|
|
early_bird_limit integer,
|
|
early_bird_used integer NOT NULL DEFAULT 0,
|
|
early_bird_price_id text,
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
ALTER TABLE public.pricing_slots ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Public-read so the pricing page can query slot status without auth.
|
|
-- Writes happen only from the Stripe webhook via the service role.
|
|
DROP POLICY IF EXISTS "public reads pricing_slots" ON public.pricing_slots;
|
|
CREATE POLICY "public reads pricing_slots"
|
|
ON public.pricing_slots FOR SELECT
|
|
USING (true);
|
|
|
|
-- Seed rows for the two tiers Session 7h ships. Price IDs filled from
|
|
-- the Stripe test-mode resources created at session end. When you cut
|
|
-- over to live mode, repeat the create flow against the live key and
|
|
-- swap these two values; everything else (events, structure) is the
|
|
-- same.
|
|
INSERT INTO public.pricing_slots (tier, beta_price_id, beta_price_usd)
|
|
VALUES
|
|
('analyst', 'price_1TgpGxIp1Mec3r2E6Wh6oeaP', 14.99),
|
|
('desk', 'price_1TgpGyIp1Mec3r2EQq50KKhF', 44.99)
|
|
ON CONFLICT (tier) DO NOTHING;
|
|
|
|
-- ---------------------------------------------------------------
|
|
-- tier CHECK constraint update — required ONLY if a future session
|
|
-- introduces 'base' or 'pro' as canonical tier names. Current code +
|
|
-- migrations 001/011 use ('free', 'analyst', 'desk') and Session 7h
|
|
-- did not change that. Leaving the ALTER commented as documentation
|
|
-- for whoever expands the tier set later.
|
|
-- ---------------------------------------------------------------
|
|
-- ALTER TABLE public.users DROP CONSTRAINT IF EXISTS users_tier_check;
|
|
-- ALTER TABLE public.users
|
|
-- ADD CONSTRAINT users_tier_check
|
|
-- CHECK (tier IN ('free', 'analyst', 'pro', 'desk'));
|
|
-- ALTER TABLE public.user_profiles DROP CONSTRAINT IF EXISTS user_profiles_tier_check;
|
|
-- ALTER TABLE public.user_profiles
|
|
-- ADD CONSTRAINT user_profiles_tier_check
|
|
-- CHECK (tier IN ('free', 'analyst', 'pro', 'desk'));
|