Spaces:
Paused
Paused
File size: 6,428 Bytes
2376451 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | -- 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);
|