Sessions 5-7a: 955 tests, deployment ready

This commit is contained in:
Kev
2026-06-08 18:35:13 -04:00
parent 06b82624a2
commit 1fa04dc776
371 changed files with 49366 additions and 955 deletions
@@ -0,0 +1,74 @@
-- VYNDR Web — odds cache + waitlist signups
-- Idempotent. Safe to apply multiple times.
create extension if not exists "pgcrypto";
-- ────────────────────────────────────────────────────────────
-- odds_cache — TTL-backed mirror of upstream Odds API data
-- Reduces calls to the rate-limited Odds API (500 req/month free tier).
-- All Next.js route handlers must read from this table, never the
-- upstream API directly.
-- ────────────────────────────────────────────────────────────
create table if not exists public.odds_cache (
cache_key text primary key,
sport text not null,
data_type text not null,
payload jsonb not null,
fetched_at timestamptz not null default now(),
expires_at timestamptz not null default (now() + interval '5 minutes')
);
create index if not exists idx_odds_cache_sport on public.odds_cache(sport);
create index if not exists idx_odds_cache_expires on public.odds_cache(expires_at);
alter table public.odds_cache enable row level security;
-- Public read OK (cache contents are public market data anyway).
-- Writes restricted to service role (bypasses RLS automatically).
drop policy if exists "anyone can read odds cache" on public.odds_cache;
create policy "anyone can read odds cache"
on public.odds_cache for select
using (true);
-- Cleanup helper — call from a cron or trigger if rows accumulate.
create or replace function public.prune_expired_odds_cache()
returns integer as $$
declare
deleted_count integer;
begin
delete from public.odds_cache
where expires_at < now() - interval '1 hour';
get diagnostics deleted_count = row_count;
return deleted_count;
end;
$$ language plpgsql security definer set search_path = public;
-- ────────────────────────────────────────────────────────────
-- waitlist_signups — capture email for upcoming launches
-- Referenced by /api/waitlist (marketplace pre-launch lists).
-- ────────────────────────────────────────────────────────────
create table if not exists public.waitlist_signups (
id uuid primary key default gen_random_uuid(),
email text not null,
list text not null default 'general',
source text,
created_at timestamptz not null default now(),
unique (email, list)
);
create index if not exists idx_waitlist_list on public.waitlist_signups(list);
create index if not exists idx_waitlist_created on public.waitlist_signups(created_at desc);
alter table public.waitlist_signups enable row level security;
-- Inserts/reads restricted to service role only. No public policies.
-- ────────────────────────────────────────────────────────────
-- founder_pricing_seat_count — convenience view used by checkout
-- to decide if the next paid user still gets the $9.99 lock-in.
-- ────────────────────────────────────────────────────────────
create or replace view public.founder_pricing_seats as
select
count(*) filter (where founder_pricing) as taken,
100 as cap,
greatest(0, 100 - count(*) filter (where founder_pricing)) as remaining
from public.user_profiles;