aethex-studio/supabase/migrations/001_initial_schema.sql

240 lines
6.5 KiB
PL/PgSQL

-- AeThex Studio Initial Database Schema
-- Run this in Supabase SQL Editor to set up your database
-- Enable RLS (Row Level Security)
alter default privileges revoke execute on functions from public;
-- Create subscription tier enum
create type subscription_tier as enum ('free', 'studio', 'pro', 'enterprise');
-- ============================================
-- PROFILES TABLE
-- ============================================
create table public.profiles (
id uuid references auth.users on delete cascade primary key,
username text unique,
avatar_url text,
created_at timestamptz default now() not null,
updated_at timestamptz default now() not null,
subscription_tier subscription_tier default 'free' not null,
translation_count integer default 0 not null
);
-- Enable RLS
alter table public.profiles enable row level security;
-- Policies
create policy "Users can view their own profile"
on public.profiles for select
using (auth.uid() = id);
create policy "Users can update their own profile"
on public.profiles for update
using (auth.uid() = id);
-- Auto-create profile on signup
create function public.handle_new_user()
returns trigger
language plpgsql
security definer set search_path = ''
as $$
begin
insert into public.profiles (id, username, avatar_url)
values (
new.id,
new.raw_user_meta_data ->> 'username',
new.raw_user_meta_data ->> 'avatar_url'
);
return new;
end;
$$;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
-- ============================================
-- PROJECTS TABLE
-- ============================================
create table public.projects (
id uuid default gen_random_uuid() primary key,
user_id uuid references public.profiles(id) on delete cascade not null,
name text not null,
description text,
platforms text[] default '{}' not null,
created_at timestamptz default now() not null,
updated_at timestamptz default now() not null,
is_public boolean default false not null
);
-- Enable RLS
alter table public.projects enable row level security;
-- Policies
create policy "Users can view their own projects"
on public.projects for select
using (auth.uid() = user_id);
create policy "Users can view public projects"
on public.projects for select
using (is_public = true);
create policy "Users can insert their own projects"
on public.projects for insert
with check (auth.uid() = user_id);
create policy "Users can update their own projects"
on public.projects for update
using (auth.uid() = user_id);
create policy "Users can delete their own projects"
on public.projects for delete
using (auth.uid() = user_id);
-- Indexes
create index projects_user_id_idx on public.projects(user_id);
create index projects_is_public_idx on public.projects(is_public) where is_public = true;
-- ============================================
-- FILES TABLE
-- ============================================
create table public.files (
id uuid default gen_random_uuid() primary key,
project_id uuid references public.projects(id) on delete cascade not null,
name text not null,
path text not null,
content text,
language text not null,
created_at timestamptz default now() not null,
updated_at timestamptz default now() not null,
unique(project_id, path)
);
-- Enable RLS
alter table public.files enable row level security;
-- Policies
create policy "Users can view files in their projects"
on public.files for select
using (
exists (
select 1 from public.projects
where projects.id = files.project_id
and projects.user_id = auth.uid()
)
);
create policy "Users can view files in public projects"
on public.files for select
using (
exists (
select 1 from public.projects
where projects.id = files.project_id
and projects.is_public = true
)
);
create policy "Users can insert files to their projects"
on public.files for insert
with check (
exists (
select 1 from public.projects
where projects.id = files.project_id
and projects.user_id = auth.uid()
)
);
create policy "Users can update files in their projects"
on public.files for update
using (
exists (
select 1 from public.projects
where projects.id = files.project_id
and projects.user_id = auth.uid()
)
);
create policy "Users can delete files from their projects"
on public.files for delete
using (
exists (
select 1 from public.projects
where projects.id = files.project_id
and projects.user_id = auth.uid()
)
);
-- Indexes
create index files_project_id_idx on public.files(project_id);
-- ============================================
-- TRANSLATIONS TABLE
-- ============================================
create table public.translations (
id uuid default gen_random_uuid() primary key,
user_id uuid references public.profiles(id) on delete cascade not null,
source_platform text not null,
target_platform text not null,
source_code text not null,
translated_code text not null,
created_at timestamptz default now() not null
);
-- Enable RLS
alter table public.translations enable row level security;
-- Policies
create policy "Users can view their own translations"
on public.translations for select
using (auth.uid() = user_id);
create policy "Users can insert their own translations"
on public.translations for insert
with check (auth.uid() = user_id);
-- Indexes
create index translations_user_id_idx on public.translations(user_id);
create index translations_created_at_idx on public.translations(created_at desc);
-- ============================================
-- HELPER FUNCTIONS
-- ============================================
-- Increment translation count for user
create function public.increment_translation_count(user_uuid uuid)
returns void
language plpgsql
security definer
as $$
begin
update public.profiles
set translation_count = translation_count + 1,
updated_at = now()
where id = user_uuid;
end;
$$;
-- Updated at trigger function
create function public.handle_updated_at()
returns trigger
language plpgsql
as $$
begin
new.updated_at = now();
return new;
end;
$$;
-- Apply updated_at triggers
create trigger set_profiles_updated_at
before update on public.profiles
for each row execute procedure public.handle_updated_at();
create trigger set_projects_updated_at
before update on public.projects
for each row execute procedure public.handle_updated_at();
create trigger set_files_updated_at
before update on public.files
for each row execute procedure public.handle_updated_at();