All checks were successful
Build / build (push) Successful in 1m47s
- Pass initial position to ship.initialize() to set position BEFORE creating physics body, preventing collision race condition on reload - Use get_or_create_user_id RPC (security definer) to bypass RLS for user profile sync in both authService and cloudLeaderboardService - Sync user to Supabase on Auth0 login to ensure profile exists - Add Supabase schema.sql and policies.sql for documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
229 lines
8.8 KiB
SQL
229 lines
8.8 KiB
SQL
create table public._migrations
|
|
(
|
|
id serial
|
|
primary key,
|
|
name text not null
|
|
unique,
|
|
executed_at timestamp with time zone default now()
|
|
);
|
|
|
|
alter table public._migrations
|
|
owner to postgres;
|
|
|
|
grant select, update, usage on sequence public._migrations_id_seq to anon;
|
|
|
|
grant select, update, usage on sequence public._migrations_id_seq to authenticated;
|
|
|
|
grant select, update, usage on sequence public._migrations_id_seq to service_role;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public._migrations to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public._migrations to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public._migrations to service_role;
|
|
|
|
create table public.users
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
auth0_id text not null
|
|
unique,
|
|
display_name text,
|
|
email text,
|
|
avatar_url text,
|
|
created_at timestamp with time zone default now(),
|
|
last_login_at timestamp with time zone default now()
|
|
);
|
|
|
|
alter table public.users
|
|
owner to postgres;
|
|
|
|
create table public.leaderboard
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
level_id text not null,
|
|
level_name text not null,
|
|
completed boolean not null,
|
|
end_reason text not null,
|
|
game_time_seconds numeric not null,
|
|
asteroids_destroyed integer not null,
|
|
total_asteroids integer not null,
|
|
accuracy numeric not null,
|
|
hull_damage_taken numeric not null,
|
|
fuel_consumed numeric not null,
|
|
final_score integer not null,
|
|
star_rating integer not null,
|
|
created_at timestamp with time zone default now(),
|
|
is_test_data boolean default false not null,
|
|
user_id uuid
|
|
constraint leaderboard_internal_user_id_fkey
|
|
references public.users
|
|
);
|
|
|
|
alter table public.leaderboard
|
|
owner to postgres;
|
|
|
|
create index idx_leaderboard_score
|
|
on public.leaderboard (final_score desc);
|
|
|
|
create index idx_leaderboard_level
|
|
on public.leaderboard (level_id);
|
|
|
|
create index idx_leaderboard_test_data
|
|
on public.leaderboard (is_test_data)
|
|
where (is_test_data = true);
|
|
|
|
create index idx_leaderboard_user_id
|
|
on public.leaderboard (user_id);
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.leaderboard to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.leaderboard to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.leaderboard to service_role;
|
|
|
|
create table public.admins
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
user_id text not null
|
|
unique,
|
|
display_name text,
|
|
email text,
|
|
can_review_levels boolean default true,
|
|
can_manage_admins boolean default false,
|
|
can_manage_official boolean default false,
|
|
can_view_analytics boolean default false,
|
|
is_active boolean default true,
|
|
expires_at timestamp with time zone,
|
|
created_at timestamp with time zone default now(),
|
|
created_by text,
|
|
notes text,
|
|
internal_user_id uuid
|
|
references public.users
|
|
);
|
|
|
|
alter table public.admins
|
|
owner to postgres;
|
|
|
|
create index idx_admins_user_id
|
|
on public.admins (user_id);
|
|
|
|
create index idx_admins_active
|
|
on public.admins (is_active)
|
|
where (is_active = true);
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.admins to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.admins to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.admins to service_role;
|
|
|
|
create table public.levels
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
slug text
|
|
unique
|
|
constraint valid_slug_format
|
|
check (validate_slug(slug)),
|
|
name text not null,
|
|
description text,
|
|
difficulty text not null
|
|
constraint valid_difficulty
|
|
check (difficulty = ANY
|
|
(ARRAY ['recruit'::text, 'pilot'::text, 'captain'::text, 'commander'::text, 'test'::text])),
|
|
estimated_time text,
|
|
tags text[] default '{}'::text[],
|
|
config jsonb not null,
|
|
mission_brief text[] default '{}'::text[],
|
|
level_type text default 'private'::text not null
|
|
constraint valid_level_type
|
|
check (level_type = ANY
|
|
(ARRAY ['official'::text, 'private'::text, 'pending_review'::text, 'published'::text, 'rejected'::text])),
|
|
sort_order integer default 0,
|
|
unlock_requirements text[] default '{}'::text[],
|
|
default_locked boolean default false,
|
|
submitted_at timestamp with time zone,
|
|
reviewed_at timestamp with time zone,
|
|
reviewed_by text,
|
|
review_notes text,
|
|
play_count integer default 0,
|
|
completion_count integer default 0,
|
|
avg_rating numeric(3, 2) default 0,
|
|
rating_count integer default 0,
|
|
created_at timestamp with time zone default now(),
|
|
updated_at timestamp with time zone default now(),
|
|
user_id uuid
|
|
references public.users
|
|
);
|
|
|
|
alter table public.levels
|
|
owner to postgres;
|
|
|
|
create index idx_levels_type
|
|
on public.levels (level_type);
|
|
|
|
create index idx_levels_slug
|
|
on public.levels (slug);
|
|
|
|
create index idx_levels_official_order
|
|
on public.levels (sort_order)
|
|
where (level_type = 'official'::text);
|
|
|
|
create index idx_levels_published
|
|
on public.levels (created_at desc)
|
|
where (level_type = 'published'::text);
|
|
|
|
create index idx_levels_pending
|
|
on public.levels (submitted_at)
|
|
where (level_type = 'pending_review'::text);
|
|
|
|
create index idx_levels_user_id
|
|
on public.levels (user_id);
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.levels to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.levels to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.levels to service_role;
|
|
|
|
create table public.level_ratings
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
level_id uuid not null
|
|
references public.levels
|
|
on delete cascade,
|
|
rating integer not null
|
|
constraint level_ratings_rating_check
|
|
check ((rating >= 1) AND (rating <= 5)),
|
|
created_at timestamp with time zone default now(),
|
|
user_id uuid
|
|
references public.users,
|
|
unique (level_id, user_id)
|
|
);
|
|
|
|
alter table public.level_ratings
|
|
owner to postgres;
|
|
|
|
create index idx_ratings_level
|
|
on public.level_ratings (level_id);
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.level_ratings to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.level_ratings to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.level_ratings to service_role;
|
|
|
|
create index idx_users_auth0_id
|
|
on public.users (auth0_id);
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.users to anon;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.users to authenticated;
|
|
|
|
grant delete, insert, references, select, trigger, truncate, update on public.users to service_role;
|
|
|