base
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
-- =====================================================================
|
||||
-- GameDev Tracker — Schéma de base de données (Supabase / PostgreSQL)
|
||||
-- À exécuter UNE SEULE FOIS dans : Supabase > SQL Editor > New query
|
||||
-- =====================================================================
|
||||
|
||||
-- ---------- Types énumérés -------------------------------------------
|
||||
do $$ begin
|
||||
create type member_role as enum
|
||||
('lead','programmer','artist','game_designer','sound','writer','qa','other');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create type task_status as enum ('todo','in_progress','review','done');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create type priority_level as enum ('low','medium','high','urgent');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create type milestone_status as enum ('planned','in_progress','done');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create type bug_severity as enum ('low','medium','high','critical');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
do $$ begin
|
||||
create type bug_status as enum ('open','in_progress','resolved','closed');
|
||||
exception when duplicate_object then null; end $$;
|
||||
|
||||
-- ---------- Profils (étend auth.users) -------------------------------
|
||||
create table if not exists public.profiles (
|
||||
id uuid primary key references auth.users(id) on delete cascade,
|
||||
full_name text not null default 'Membre',
|
||||
role member_role not null default 'other',
|
||||
avatar_color text not null default '#7c5cff',
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ---------- Projets --------------------------------------------------
|
||||
create table if not exists public.projects (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
name text not null,
|
||||
description text,
|
||||
created_by uuid references public.profiles(id) on delete set null,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ---------- Jalons (milestones) --------------------------------------
|
||||
create table if not exists public.milestones (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
project_id uuid not null references public.projects(id) on delete cascade,
|
||||
title text not null,
|
||||
description text,
|
||||
due_date date,
|
||||
status milestone_status not null default 'planned',
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ---------- Tâches ---------------------------------------------------
|
||||
create table if not exists public.tasks (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
project_id uuid not null references public.projects(id) on delete cascade,
|
||||
title text not null,
|
||||
description text,
|
||||
status task_status not null default 'todo',
|
||||
priority priority_level not null default 'medium',
|
||||
assignee_id uuid references public.profiles(id) on delete set null,
|
||||
milestone_id uuid references public.milestones(id) on delete set null,
|
||||
due_date date,
|
||||
position double precision not null default 0,
|
||||
created_by uuid references public.profiles(id) on delete set null,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ---------- Bugs -----------------------------------------------------
|
||||
create table if not exists public.bugs (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
project_id uuid not null references public.projects(id) on delete cascade,
|
||||
title text not null,
|
||||
description text,
|
||||
severity bug_severity not null default 'medium',
|
||||
status bug_status not null default 'open',
|
||||
priority priority_level not null default 'medium',
|
||||
assignee_id uuid references public.profiles(id) on delete set null,
|
||||
reporter_id uuid references public.profiles(id) on delete set null,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
create index if not exists idx_tasks_project on public.tasks(project_id);
|
||||
create index if not exists idx_bugs_project on public.bugs(project_id);
|
||||
create index if not exists idx_milestones_project on public.milestones(project_id);
|
||||
|
||||
-- ---------- Maj automatique de updated_at ----------------------------
|
||||
create or replace function public.touch_updated_at()
|
||||
returns trigger language plpgsql as $$
|
||||
begin new.updated_at = now(); return new; end $$;
|
||||
|
||||
drop trigger if exists trg_tasks_touch on public.tasks;
|
||||
create trigger trg_tasks_touch before update on public.tasks
|
||||
for each row execute function public.touch_updated_at();
|
||||
|
||||
drop trigger if exists trg_bugs_touch on public.bugs;
|
||||
create trigger trg_bugs_touch before update on public.bugs
|
||||
for each row execute function public.touch_updated_at();
|
||||
|
||||
-- ---------- Création auto du profil à l'inscription ------------------
|
||||
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, full_name, role)
|
||||
values (
|
||||
new.id,
|
||||
coalesce(new.raw_user_meta_data->>'full_name', split_part(new.email,'@',1)),
|
||||
coalesce((new.raw_user_meta_data->>'role')::member_role, 'other')
|
||||
)
|
||||
on conflict (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();
|
||||
|
||||
-- ---------- Sécurité (RLS) -------------------------------------------
|
||||
-- Équipe privée et de confiance : tout membre connecté a accès complet.
|
||||
alter table public.profiles enable row level security;
|
||||
alter table public.projects enable row level security;
|
||||
alter table public.milestones enable row level security;
|
||||
alter table public.tasks enable row level security;
|
||||
alter table public.bugs enable row level security;
|
||||
|
||||
do $$
|
||||
declare t text;
|
||||
begin
|
||||
foreach t in array array['profiles','projects','milestones','tasks','bugs'] loop
|
||||
execute format('drop policy if exists %I_all on public.%I', t, t);
|
||||
execute format(
|
||||
'create policy %I_all on public.%I for all to authenticated using (true) with check (true)',
|
||||
t, t);
|
||||
end loop;
|
||||
end $$;
|
||||
|
||||
-- ---------- Realtime (synchro live entre membres) --------------------
|
||||
do $$ begin
|
||||
alter publication supabase_realtime add table public.tasks;
|
||||
exception when duplicate_object then null; end $$;
|
||||
do $$ begin
|
||||
alter publication supabase_realtime add table public.bugs;
|
||||
exception when duplicate_object then null; end $$;
|
||||
do $$ begin
|
||||
alter publication supabase_realtime add table public.milestones;
|
||||
exception when duplicate_object then null; end $$;
|
||||
Reference in New Issue
Block a user