merge
This commit is contained in:
54
supabase/config.toml
Normal file
54
supabase/config.toml
Normal file
@@ -0,0 +1,54 @@
|
||||
project_id = "habit-pet"
|
||||
|
||||
[api]
|
||||
enabled = true
|
||||
port = 54321
|
||||
schemas = ["public", "graphql_public"]
|
||||
extra_search_path = ["public", "extensions"]
|
||||
max_rows = 1000
|
||||
|
||||
[db]
|
||||
port = 54322
|
||||
shadow_port = 54320
|
||||
major_version = 15
|
||||
|
||||
[db.seed]
|
||||
enabled = true
|
||||
sql_paths = ["./seed.sql"]
|
||||
|
||||
[studio]
|
||||
enabled = true
|
||||
port = 54323
|
||||
|
||||
[inbucket]
|
||||
enabled = true
|
||||
port = 54324
|
||||
|
||||
[storage]
|
||||
enabled = true
|
||||
file_size_limit = "50MiB"
|
||||
|
||||
[auth]
|
||||
enabled = true
|
||||
site_url = "https://cursor-hackathon-flame.vercel.app"
|
||||
additional_redirect_urls = [
|
||||
"http://127.0.0.1:3000/**",
|
||||
"http://localhost:3000/**",
|
||||
"https://cursor-hackathon-flame.vercel.app/**",
|
||||
"https://cursor-hackathon-*-harkamal-randhawas-projects.vercel.app/**",
|
||||
"https://cursor-hackathon-*-recentrunner-harkamal-randhawas-projects.vercel.app/**",
|
||||
]
|
||||
jwt_expiry = 3600
|
||||
enable_refresh_token_rotation = true
|
||||
refresh_token_reuse_interval = 10
|
||||
|
||||
[auth.email]
|
||||
enable_signup = true
|
||||
double_confirm_changes = true
|
||||
enable_confirmations = false
|
||||
|
||||
[realtime]
|
||||
enabled = true
|
||||
|
||||
[analytics]
|
||||
enabled = false
|
||||
67
supabase/migrations/20260523220000_initial_schema.sql
Normal file
67
supabase/migrations/20260523220000_initial_schema.sql
Normal file
@@ -0,0 +1,67 @@
|
||||
create extension if not exists pgcrypto;
|
||||
|
||||
create table profiles (
|
||||
id uuid primary key references auth.users(id) on delete cascade,
|
||||
display_name text,
|
||||
focus_topics text[] default '{}',
|
||||
onboarding_complete boolean default false,
|
||||
created_at timestamptz default now()
|
||||
);
|
||||
|
||||
create table habits (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
user_id uuid references auth.users(id) on delete cascade not null,
|
||||
name text not null,
|
||||
active boolean default true,
|
||||
created_at timestamptz default now()
|
||||
);
|
||||
|
||||
create table habit_logs (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
habit_id uuid references habits(id) on delete cascade not null,
|
||||
user_id uuid references auth.users(id) on delete cascade not null,
|
||||
completed_on date not null default current_date,
|
||||
created_at timestamptz default now(),
|
||||
unique (habit_id, completed_on)
|
||||
);
|
||||
|
||||
create table daily_entries (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
user_id uuid references auth.users(id) on delete cascade not null,
|
||||
entry_date date not null default current_date,
|
||||
mood int check (mood between 1 and 5),
|
||||
stress int check (stress between 1 and 5),
|
||||
energy int check (energy between 1 and 5),
|
||||
sleep_hours numeric,
|
||||
sleep_quality int check (sleep_quality between 1 and 5),
|
||||
journal text,
|
||||
created_at timestamptz default now(),
|
||||
unique (user_id, entry_date)
|
||||
);
|
||||
|
||||
create table avatar_state (
|
||||
user_id uuid primary key references auth.users(id) on delete cascade,
|
||||
avatar_name text default 'Pixel Me',
|
||||
mood_state text default 'neutral',
|
||||
health int default 50,
|
||||
energy int default 50,
|
||||
coins int default 0,
|
||||
streak int default 0,
|
||||
equipped_item text default 'none',
|
||||
updated_at timestamptz default now()
|
||||
);
|
||||
|
||||
create table shop_items (
|
||||
id text primary key,
|
||||
name text not null,
|
||||
type text not null,
|
||||
price int not null,
|
||||
image_path text not null
|
||||
);
|
||||
|
||||
create table user_items (
|
||||
user_id uuid references auth.users(id) on delete cascade,
|
||||
item_id text references shop_items(id) on delete cascade,
|
||||
purchased_at timestamptz default now(),
|
||||
primary key (user_id, item_id)
|
||||
);
|
||||
@@ -0,0 +1,76 @@
|
||||
alter table profiles enable row level security;
|
||||
alter table habits enable row level security;
|
||||
alter table habit_logs enable row level security;
|
||||
alter table daily_entries enable row level security;
|
||||
alter table avatar_state enable row level security;
|
||||
alter table shop_items enable row level security;
|
||||
alter table user_items enable row level security;
|
||||
|
||||
alter table habits
|
||||
add constraint habits_id_user_id_unique unique (id, user_id);
|
||||
|
||||
alter table habit_logs
|
||||
add constraint habit_logs_habit_id_user_id_fkey
|
||||
foreign key (habit_id, user_id)
|
||||
references habits (id, user_id)
|
||||
on delete cascade;
|
||||
|
||||
create policy "profiles_select_own"
|
||||
on profiles
|
||||
for select
|
||||
to authenticated
|
||||
using (id = auth.uid());
|
||||
|
||||
create policy "profiles_insert_own"
|
||||
on profiles
|
||||
for insert
|
||||
to authenticated
|
||||
with check (id = auth.uid());
|
||||
|
||||
create policy "profiles_update_own"
|
||||
on profiles
|
||||
for update
|
||||
to authenticated
|
||||
using (id = auth.uid())
|
||||
with check (id = auth.uid());
|
||||
|
||||
create policy "habits_manage_own"
|
||||
on habits
|
||||
for all
|
||||
to authenticated
|
||||
using (user_id = auth.uid())
|
||||
with check (user_id = auth.uid());
|
||||
|
||||
create policy "habit_logs_manage_own"
|
||||
on habit_logs
|
||||
for all
|
||||
to authenticated
|
||||
using (user_id = auth.uid())
|
||||
with check (user_id = auth.uid());
|
||||
|
||||
create policy "daily_entries_manage_own"
|
||||
on daily_entries
|
||||
for all
|
||||
to authenticated
|
||||
using (user_id = auth.uid())
|
||||
with check (user_id = auth.uid());
|
||||
|
||||
create policy "avatar_state_manage_own"
|
||||
on avatar_state
|
||||
for all
|
||||
to authenticated
|
||||
using (user_id = auth.uid())
|
||||
with check (user_id = auth.uid());
|
||||
|
||||
create policy "shop_items_read_all"
|
||||
on shop_items
|
||||
for select
|
||||
to anon, authenticated
|
||||
using (true);
|
||||
|
||||
create policy "user_items_manage_own"
|
||||
on user_items
|
||||
for all
|
||||
to authenticated
|
||||
using (user_id = auth.uid())
|
||||
with check (user_id = auth.uid());
|
||||
@@ -0,0 +1,28 @@
|
||||
create or replace function public.handle_new_user()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
begin
|
||||
insert into public.profiles (id, display_name)
|
||||
values (
|
||||
new.id,
|
||||
coalesce(new.raw_user_meta_data ->> 'display_name', split_part(new.email, '@', 1))
|
||||
)
|
||||
on conflict (id) do nothing;
|
||||
|
||||
insert into public.avatar_state (user_id)
|
||||
values (new.id)
|
||||
on conflict (user_id) do nothing;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$$;
|
||||
|
||||
drop trigger if exists on_auth_user_created on auth.users;
|
||||
|
||||
create trigger on_auth_user_created
|
||||
after insert on auth.users
|
||||
for each row
|
||||
execute function public.handle_new_user();
|
||||
11
supabase/seed.sql
Normal file
11
supabase/seed.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
insert into shop_items (id, name, type, price, image_path)
|
||||
values
|
||||
('hat_blue', 'Blue Hat', 'accessory', 20, '/items/hat-blue.png'),
|
||||
('glasses_round', 'Round Glasses', 'accessory', 30, '/items/glasses-round.png'),
|
||||
('room_sunset', 'Sunset Room', 'background', 40, '/backgrounds/room-sunset.png')
|
||||
on conflict (id) do update
|
||||
set
|
||||
name = excluded.name,
|
||||
type = excluded.type,
|
||||
price = excluded.price,
|
||||
image_path = excluded.image_path;
|
||||
Reference in New Issue
Block a user