-- PolyWeather minimal commerce/auth schema (P0) -- Run in Supabase SQL editor. create table if not exists public.profiles ( id uuid primary key references auth.users(id) on delete cascade, email text not null default '', telegram_user_id bigint, telegram_username text, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create table if not exists public.subscriptions ( id bigserial primary key, user_id uuid not null references auth.users(id) on delete cascade, plan_code text not null, status text not null check (status in ('active', 'paused', 'expired', 'cancelled')), starts_at timestamptz not null default now(), expires_at timestamptz not null, source text not null default 'manual', created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create index if not exists idx_subscriptions_user_status_expiry on public.subscriptions(user_id, status, expires_at desc); create table if not exists public.payments ( id bigserial primary key, user_id uuid not null references auth.users(id) on delete cascade, amount numeric(18, 6) not null, currency text not null default 'USDC', chain text not null default 'polygon', tx_hash text unique, status text not null check (status in ('pending', 'confirmed', 'failed', 'refunded')), raw_payload jsonb not null default '{}'::jsonb, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create table if not exists public.entitlement_events ( id bigserial primary key, user_id uuid not null references auth.users(id) on delete cascade, action text not null, reason text not null default '', actor text not null default 'system', payload jsonb not null default '{}'::jsonb, created_at timestamptz not null default now() ); create or replace function public.sync_profile_from_auth() returns trigger language plpgsql security definer set search_path = public as $$ begin insert into public.profiles (id, email) values (new.id, coalesce(new.email, '')) on conflict (id) do update set email = excluded.email, updated_at = now(); return new; end; $$; drop trigger if exists on_auth_user_created_polyweather on auth.users; create trigger on_auth_user_created_polyweather after insert on auth.users for each row execute function public.sync_profile_from_auth();