Session 7h: Stripe products, tier config, scan limits, response gating, free tier
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
-- 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'));
|
||||
Reference in New Issue
Block a user