Files
vyndr/docs/sql/pricing_slots.sql
T

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'));