Spaces:
Paused
Paused
| -- Supabase Database Schema | |
| -- Run this SQL in your Supabase SQL Editor | |
| -- Enable UUID extension | |
| create extension if not exists "uuid-ossp"; | |
| -- User profiles table | |
| create table if not exists profiles ( | |
| id uuid references auth.users on delete cascade primary key, | |
| email text unique, | |
| full_name text, | |
| avatar_url text, | |
| is_premium boolean default true, -- Beta: all users premium | |
| premium_expires_at timestamp with time zone, | |
| tokens_remaining integer default -1, -- Beta: unlimited | |
| tokens_reset_at timestamp with time zone default now() + interval '24 hours', | |
| created_at timestamp with time zone default now(), | |
| updated_at timestamp with time zone default now() | |
| ); | |
| -- Projects table (user saved code) | |
| create table if not exists projects ( | |
| id uuid default uuid_generate_v4() primary key, | |
| user_id uuid references profiles(id) on delete cascade not null, | |
| name text default 'Untitled Project', | |
| description text, | |
| html_code text default '', | |
| css_code text default '', | |
| js_code text default '', | |
| preview_url text, | |
| thumbnail_url text, | |
| is_public boolean default false, | |
| created_at timestamp with time zone default now(), | |
| updated_at timestamp with time zone default now() | |
| ); | |
| -- AI chat messages history | |
| create table if not exists chat_messages ( | |
| id uuid default uuid_generate_v4() primary key, | |
| user_id uuid references profiles(id) on delete cascade not null, | |
| project_id uuid references projects(id) on delete cascade, | |
| role text not null check (role in ('user', 'assistant')), | |
| content text not null, | |
| tokens_used integer default 0, | |
| created_at timestamp with time zone default now() | |
| ); | |
| -- Token transactions ledger | |
| create table if not exists token_transactions ( | |
| id uuid default uuid_generate_v4() primary key, | |
| user_id uuid references profiles(id) on delete cascade not null, | |
| transaction_type text not null check (transaction_type in ('ai_usage', 'ad_reward', 'daily_reset', 'purchase', 'premium_bonus')), | |
| amount integer not null, | |
| description text, | |
| created_at timestamp with time zone default now() | |
| ); | |
| -- Subscriptions table (kept for future Stripe integration) | |
| create table if not exists subscriptions ( | |
| id uuid default uuid_generate_v4() primary key, | |
| user_id uuid references profiles(id) on delete cascade unique not null, | |
| status text not null check (status in ('active', 'canceled', 'past_due', 'trialing', 'beta')), | |
| current_period_end timestamp with time zone, | |
| cancel_at_period_end boolean default false, | |
| created_at timestamp with time zone default now(), | |
| updated_at timestamp with time zone default now() | |
| ); | |
| -- Ad engagement tracking | |
| create table if not exists ad_engagements ( | |
| id uuid default uuid_generate_v4() primary key, | |
| user_id uuid references profiles(id) on delete cascade not null, | |
| ad_type text not null check (ad_type in ('banner', 'rewarded')), | |
| ad_slot text, | |
| reward_amount integer default 0, | |
| completed boolean default false, | |
| created_at timestamp with time zone default now() | |
| ); | |
| -- Enable Row Level Security | |
| alter table profiles enable row level security; | |
| alter table projects enable row level security; | |
| alter table chat_messages enable row level security; | |
| alter table token_transactions enable row level security; | |
| alter table subscriptions enable row level security; | |
| alter table ad_engagements enable row level security; | |
| -- RLS Policies for profiles | |
| create policy "Users can view own profile" | |
| on profiles for select | |
| using (auth.uid() = id); | |
| create policy "Users can update own profile" | |
| on profiles for update | |
| using (auth.uid() = id); | |
| -- RLS Policies for projects | |
| create policy "Users can view own projects" | |
| on projects for select | |
| using (auth.uid() = user_id); | |
| create policy "Users can view public projects" | |
| on projects for select | |
| using (is_public = true); | |
| create policy "Users can create projects" | |
| on projects for insert | |
| with check (auth.uid() = user_id); | |
| create policy "Users can update own projects" | |
| on projects for update | |
| using (auth.uid() = user_id); | |
| create policy "Users can delete own projects" | |
| on projects for delete | |
| using (auth.uid() = user_id); | |
| -- RLS Policies for chat_messages | |
| create policy "Users can view own messages" | |
| on chat_messages for select | |
| using (auth.uid() = user_id); | |
| create policy "Users can create messages" | |
| on chat_messages for insert | |
| with check (auth.uid() = user_id); | |
| -- RLS Policies for token_transactions | |
| create policy "Users can view own transactions" | |
| on token_transactions for select | |
| using (auth.uid() = user_id); | |
| create policy "System can create transactions" | |
| on token_transactions for insert | |
| with check (true); | |
| -- RLS Policies for subscriptions | |
| create policy "Users can view own subscription" | |
| on subscriptions for select | |
| using (auth.uid() = user_id); | |
| create policy "Users can manage own subscriptions" | |
| on subscriptions for all | |
| using (auth.uid() = user_id); | |
| -- RLS Policies for ad_engagements | |
| create policy "Users can view own engagements" | |
| on ad_engagements for select | |
| using (auth.uid() = user_id); | |
| create policy "System can create engagements" | |
| on ad_engagements for insert | |
| with check (true); | |
| -- Function to handle new user creation | |
| create or replace function public.handle_new_user() | |
| returns trigger as $$ | |
| begin | |
| insert into public.profiles (id, email, full_name, avatar_url) | |
| values ( | |
| new.id, | |
| new.email, | |
| new.raw_user_meta_data->>'full_name', | |
| new.raw_user_meta_data->>'avatar_url' | |
| ); | |
| return new; | |
| end; | |
| $$ language plpgsql security definer; | |
| -- Trigger for new user creation | |
| create or replace trigger on_auth_user_created | |
| after insert on auth.users | |
| for each row execute procedure public.handle_new_user(); | |
| -- Function to reset tokens daily | |
| create or replace function reset_daily_tokens() | |
| returns void as $$ | |
| begin | |
| update profiles | |
| set tokens_remaining = 50, | |
| tokens_reset_at = now() + interval '24 hours' | |
| where tokens_reset_at <= now() | |
| and is_premium = false; | |
| end; | |
| $$ language plpgsql security definer; | |
| -- Indexes for performance | |
| create index if not exists idx_projects_user_id on projects(user_id); | |
| create index if not exists idx_projects_updated on projects(user_id, updated_at desc); | |
| create index if not exists idx_chat_messages_user_project on chat_messages(user_id, project_id); | |
| create index if not exists idx_token_transactions_user on token_transactions(user_id, created_at desc); | |
| create index if not exists idx_ad_engagements_user on ad_engagements(user_id, created_at desc); | |