mirror of
https://github.com/Hackdex-App/hackdex-website.git
synced 2026-04-21 06:27:36 -05:00
144 lines
4.8 KiB
PL/PgSQL
144 lines
4.8 KiB
PL/PgSQL
create type public."Completion Status" as enum ('Complete', 'Demo', 'Alpha', 'Beta');
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists is_archive boolean not null default false;
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists rejected boolean not null default false;
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists rejected_at timestamp with time zone;
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists rejected_reason text;
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists rejected_by uuid;
|
|
|
|
alter table if exists public.hacks
|
|
add column if not exists completion_status "Completion Status";
|
|
|
|
-- Foreign key for rejected_by -> auth.users(id)
|
|
alter table "public"."hacks" add constraint "hacks_rejected_by_fkey" FOREIGN KEY (rejected_by) REFERENCES auth.users(id) ON DELETE SET NULL not valid;
|
|
alter table "public"."hacks" validate constraint "hacks_rejected_by_fkey";
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION public.is_archive_hack_for_archiver(hack_slug text)
|
|
RETURNS boolean
|
|
LANGUAGE sql
|
|
STABLE
|
|
SECURITY DEFINER
|
|
AS $$
|
|
SELECT EXISTS (
|
|
SELECT 1
|
|
FROM public.hacks h
|
|
WHERE h.slug = hack_slug
|
|
AND h.is_archive = true
|
|
);
|
|
$$;
|
|
|
|
|
|
create table if not exists public.patch_groups (
|
|
"id" bigint generated by default as identity not null,
|
|
"created_at" timestamp with time zone not null default now(),
|
|
"updated_at" timestamp with time zone not null default now(),
|
|
"name" text not null,
|
|
"hack_slug" text not null,
|
|
"patch_id" bigint not null,
|
|
"order" integer not null
|
|
);
|
|
|
|
alter table public.patch_groups owner to "postgres";
|
|
|
|
-- Primary key
|
|
CREATE UNIQUE INDEX patch_groups_pkey ON public.patch_groups USING btree (id);
|
|
alter table "public"."patch_groups" add constraint "patch_groups_pkey" PRIMARY KEY using index "patch_groups_pkey";
|
|
|
|
-- Foreign keys
|
|
alter table "public"."patch_groups" add constraint "patch_groups_patch_id_fkey" FOREIGN KEY (patch_id) REFERENCES patches(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
|
alter table "public"."patch_groups" validate constraint "patch_groups_patch_id_fkey";
|
|
|
|
alter table "public"."patch_groups" add constraint "patch_groups_hack_slug_fkey" FOREIGN KEY (hack_slug) REFERENCES hacks(slug) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
|
alter table "public"."patch_groups" validate constraint "patch_groups_hack_slug_fkey";
|
|
|
|
-- Unique constraints
|
|
-- A patch can only appear once per group
|
|
CREATE UNIQUE INDEX patch_groups_hack_slug_name_patch_id_key ON public.patch_groups USING btree (hack_slug, name, patch_id);
|
|
alter table "public"."patch_groups" add constraint "patch_groups_hack_slug_name_patch_id_key" UNIQUE using index "patch_groups_hack_slug_name_patch_id_key";
|
|
|
|
-- Performance indexes
|
|
CREATE INDEX patch_groups_hack_slug_idx ON public.patch_groups USING btree (hack_slug);
|
|
CREATE INDEX patch_groups_patch_id_idx ON public.patch_groups USING btree (patch_id);
|
|
CREATE INDEX patch_groups_name_idx ON public.patch_groups USING btree (name);
|
|
|
|
-- Enable RLS
|
|
alter table "public"."patch_groups" enable row level security;
|
|
|
|
-- RLS Policies
|
|
-- Public read access (assuming patches are public)
|
|
create policy "Patch groups are viewable by everyone"
|
|
on "public"."patch_groups"
|
|
for select
|
|
using (true);
|
|
|
|
-- Allow authenticated users to insert patch groups for their own hacks
|
|
create policy "Users can insert patch groups for own hacks"
|
|
on "public"."patch_groups"
|
|
for insert
|
|
with check (
|
|
public.is_admin() OR
|
|
(public.is_archiver() AND public.is_archive_hack_for_archiver(patch_groups.hack_slug)) OR
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM public.hacks h
|
|
WHERE h.slug = patch_groups.hack_slug
|
|
AND h.created_by = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- Allow authenticated users to update patch groups for their own hacks
|
|
create policy "Users can update patch groups for own hacks"
|
|
on "public"."patch_groups"
|
|
for update
|
|
using (
|
|
public.is_admin() OR
|
|
(public.is_archiver() AND public.is_archive_hack_for_archiver(patch_groups.hack_slug)) OR
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM public.hacks h
|
|
WHERE h.slug = patch_groups.hack_slug
|
|
AND h.created_by = auth.uid()
|
|
)
|
|
)
|
|
with check (
|
|
public.is_admin() OR
|
|
(public.is_archiver() AND public.is_archive_hack_for_archiver(patch_groups.hack_slug)) OR
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM public.hacks h
|
|
WHERE h.slug = patch_groups.hack_slug
|
|
AND h.created_by = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- Allow authenticated users to delete patch groups for their own hacks
|
|
create policy "Users can delete patch groups for own hacks"
|
|
on "public"."patch_groups"
|
|
for delete
|
|
using (
|
|
public.is_admin() OR
|
|
(public.is_archiver() AND public.is_archive_hack_for_archiver(patch_groups.hack_slug)) OR
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM public.hacks h
|
|
WHERE h.slug = patch_groups.hack_slug
|
|
AND h.created_by = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- Trigger for updated_at
|
|
CREATE OR REPLACE TRIGGER set_patch_groups_updated_at
|
|
BEFORE UPDATE ON public.patch_groups
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.set_updated_at();
|