146 lines
6.7 KiB
SQL
146 lines
6.7 KiB
SQL
-- =====================================================================
|
|
-- GameDev Tracker — Mise à jour complète (v2 + v3 + v4)
|
|
-- À coller dans : Supabase > SQL Editor > New query > Run
|
|
-- Sans danger si une partie a déjà été appliquée (tout est idempotent).
|
|
-- =====================================================================
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- v2 — Pôles, assignation multiple, notifications, suppression jalons
|
|
-- ---------------------------------------------------------------------
|
|
alter table public.tasks add column if not exists pole member_role;
|
|
alter table public.bugs add column if not exists pole member_role;
|
|
|
|
alter table public.tasks
|
|
add column if not exists assignee_ids uuid[] not null default '{}';
|
|
|
|
-- Reprend l'assigné unique existant dans le tableau (si la colonne existe encore).
|
|
do $$ begin
|
|
if exists (select 1 from information_schema.columns
|
|
where table_schema='public' and table_name='tasks' and column_name='assignee_id') then
|
|
update public.tasks
|
|
set assignee_ids = array[assignee_id]
|
|
where assignee_id is not null and (assignee_ids is null or assignee_ids = '{}');
|
|
alter table public.tasks drop column assignee_id;
|
|
end if;
|
|
end $$;
|
|
|
|
alter table public.tasks drop column if exists milestone_id;
|
|
drop table if exists public.milestones cascade;
|
|
drop type if exists milestone_status;
|
|
|
|
create table if not exists public.notifications (
|
|
id uuid primary key default gen_random_uuid(),
|
|
user_id uuid not null references public.profiles(id) on delete cascade,
|
|
project_id uuid references public.projects(id) on delete cascade,
|
|
kind text not null,
|
|
title text not null,
|
|
body text,
|
|
entity_id uuid,
|
|
pole member_role,
|
|
read boolean not null default false,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
create index if not exists idx_notifications_user on public.notifications(user_id);
|
|
alter table public.notifications enable row level security;
|
|
|
|
drop policy if exists notifications_select on public.notifications;
|
|
drop policy if exists notifications_insert on public.notifications;
|
|
drop policy if exists notifications_update on public.notifications;
|
|
drop policy if exists notifications_delete on public.notifications;
|
|
create policy notifications_select on public.notifications
|
|
for select to authenticated using (user_id = auth.uid());
|
|
create policy notifications_insert on public.notifications
|
|
for insert to authenticated with check (true);
|
|
create policy notifications_update on public.notifications
|
|
for update to authenticated using (user_id = auth.uid()) with check (user_id = auth.uid());
|
|
create policy notifications_delete on public.notifications
|
|
for delete to authenticated using (user_id = auth.uid());
|
|
|
|
do $$ begin
|
|
alter publication supabase_realtime add table public.notifications;
|
|
exception when duplicate_object then null; end $$;
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- v3 — Feuille de temps : entrées libres (réunion, etc.)
|
|
-- ---------------------------------------------------------------------
|
|
-- Crée la table si elle n'a jamais existé (ancienne base sans suivi du temps).
|
|
create table if not exists public.time_logs (
|
|
id uuid primary key default gen_random_uuid(),
|
|
project_id uuid references public.projects(id) on delete cascade,
|
|
task_id uuid references public.tasks(id) on delete cascade,
|
|
label text,
|
|
user_id uuid references public.profiles(id) on delete set null,
|
|
minutes integer not null check (minutes > 0),
|
|
note text,
|
|
logged_at date not null default current_date,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
|
|
-- Si la table existait déjà (ancienne version), on l'aligne sur le nouveau format.
|
|
alter table public.time_logs alter column task_id drop not null;
|
|
alter table public.time_logs add column if not exists label text;
|
|
alter table public.time_logs
|
|
add column if not exists project_id uuid references public.projects(id) on delete cascade;
|
|
|
|
update public.time_logs tl
|
|
set project_id = t.project_id
|
|
from public.tasks t
|
|
where tl.task_id = t.id and tl.project_id is null;
|
|
|
|
create index if not exists idx_time_logs_task on public.time_logs(task_id);
|
|
create index if not exists idx_time_logs_project on public.time_logs(project_id);
|
|
create index if not exists idx_time_logs_user on public.time_logs(user_id);
|
|
|
|
alter table public.time_logs enable row level security;
|
|
drop policy if exists time_logs_all on public.time_logs;
|
|
create policy time_logs_all on public.time_logs
|
|
for all to authenticated using (true) with check (true);
|
|
|
|
do $$ begin
|
|
alter publication supabase_realtime add table public.time_logs;
|
|
exception when duplicate_object then null; end $$;
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- v4 — Plusieurs pôles (rôles) par membre
|
|
-- ---------------------------------------------------------------------
|
|
alter table public.profiles
|
|
add column if not exists roles member_role[] not null default '{}';
|
|
|
|
update public.profiles
|
|
set roles = array[role]
|
|
where roles = '{}';
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- v5 — Accueil (onboarding) des nouveaux membres
|
|
-- ---------------------------------------------------------------------
|
|
alter table public.profiles
|
|
add column if not exists onboarded boolean not null default false;
|
|
|
|
-- Les membres déjà présents ne sont pas ré-embarqués : on les marque « fait ».
|
|
update public.profiles set onboarded = true where onboarded = false;
|
|
|
|
-- ---------------------------------------------------------------------
|
|
-- v6 — Photo de profil (avatar image) : colonne + bucket de stockage
|
|
-- ---------------------------------------------------------------------
|
|
alter table public.profiles add column if not exists avatar_url text;
|
|
|
|
-- Bucket public "avatars" pour héberger les photos de profil.
|
|
insert into storage.buckets (id, name, public)
|
|
values ('avatars', 'avatars', true)
|
|
on conflict (id) do nothing;
|
|
|
|
-- Lecture publique ; écriture réservée aux membres connectés.
|
|
drop policy if exists avatars_read on storage.objects;
|
|
drop policy if exists avatars_insert on storage.objects;
|
|
drop policy if exists avatars_update on storage.objects;
|
|
drop policy if exists avatars_delete on storage.objects;
|
|
|
|
create policy avatars_read on storage.objects
|
|
for select using (bucket_id = 'avatars');
|
|
create policy avatars_insert on storage.objects
|
|
for insert to authenticated with check (bucket_id = 'avatars');
|
|
create policy avatars_update on storage.objects
|
|
for update to authenticated using (bucket_id = 'avatars');
|
|
create policy avatars_delete on storage.objects
|
|
for delete to authenticated using (bucket_id = 'avatars');
|