Added first draft of story

This commit is contained in:
Alexis
2024-12-09 23:58:16 +01:00
parent 323eedec56
commit 49574d8ef1
8 changed files with 170 additions and 10 deletions

View File

@@ -7,6 +7,8 @@ create type public.app_permission as enum ('events.see.hidden', 'users.ban');
create type public.app_role as enum ('sa', 'admin', 'moderator', 'user');
create type public.app_colors as enum ('red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose', 'black', 'white');
create type public.calendar_state as enum ('published', 'draft', 'archived');
-- DATA STRUCTURES
-- Users
create table public.users (
@@ -44,12 +46,24 @@ create table public.worlds (
);
comment on table public.worlds is 'Worlds belonging to a single user ; a game master.';
-- World Players (join table)
create table public.world_players (
world_id bigint references public.worlds on delete cascade,
player_id uuid references public.users on delete cascade,
joined_at timestamptz default now(),
primary key (world_id, player_id)
);
comment on table public.world_players is 'Players (users) that belong to specific worlds';
comment on column public.world_players.joined_at is 'Timestamp when the player joined the world';
-- World Calendars
create table public.calendars (
id bigint generated by default as identity primary key,
short_id text unique,
name text not null,
today json not null,
color app_colors default 'black',
state calendar_state default 'draft',
world_id bigint references public.worlds on delete cascade not null
);
comment on table public.calendars is 'Calendar settings and configuration attached to a single world.';
@@ -187,6 +201,10 @@ create policy "Allow GMs to edit their worlds" on public.worlds for update using
create policy "Allow GMs to delete their worlds" on public.worlds for delete using ( auth.uid() = gm_id );
-- Calendar policies
create policy "Allow anonymous access to published calendars" on public.calendars
for select
using (state = 'published');
create policy "Allow GMs to see their calendars" on public.calendars for select using (
exists (
select 1 from worlds
@@ -213,6 +231,17 @@ create policy "Allow GMs to delete their calendars" on public.calendars for dele
);
-- Month policies
create policy "Allow anonymous access to months in published calendars" ON public.calendar_months
for select
using (
exists (
select 1
from public.calendars
where calendars.id = calendar_months.calendar_id
and calendars.state = 'published'
)
);
create policy "Allow GMs to see their calendar's months"
on public.calendar_months
for select
@@ -267,6 +296,17 @@ create policy "Allow GMs to delete their calendar's months"
);
-- Event policies
create policy "Allow anonymous access to non-hidden events in published calendars" ON public.calendar_events
for select
using (
not hidden and exists (
select 1
from public.calendars
where calendars.id = calendar_events.calendar_id
and calendars.state = 'published'
)
);
create policy "Allow GMs to see their events"
on public.calendar_events
for select
@@ -342,8 +382,8 @@ create policy "Allow individual update access for GMs" on public.characters for
-- Categories are public to view but not to insert
-- Needs to be refactored maybe, if in the future we want a default set AND user defined ones
create policy "Allow logged-in read access" on public.calendar_event_categories for select using ( auth.role() = 'authenticated' );
create policy "Allow logged-in read access" on public.calendar_event_categories_links for select using ( auth.role() = 'authenticated' );
create policy "Allow all read access" on public.calendar_event_categories for select to authenticated, anon using ( true );
create policy "Allow all read access" on public.calendar_event_categories_links for select to authenticated, anon using ( true );
create policy "Allow logged-in read access" on public.character_categories for select using ( auth.role() = 'authenticated' );
create policy "Allow logged-in read access" on public.character_categories_links for select using ( auth.role() = 'authenticated' );
@@ -391,3 +431,48 @@ begin
return user_id;
end;
$$ language plpgsql;
-- Add short IDs to calendars
-- Function to generate YouTube-like IDs
CREATE OR REPLACE FUNCTION public.generate_short_id()
RETURNS text AS $$
DECLARE
characters text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
result text := '';
i integer;
BEGIN
FOR i IN 1..11 LOOP
result := result || substr(characters, floor(random() * length(characters) + 1)::integer, 1);
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql VOLATILE;
-- Trigger function to set unique short ID
CREATE OR REPLACE FUNCTION public.set_calendar_short_id()
RETURNS TRIGGER AS $$
DECLARE
new_id text;
attempts integer := 0;
BEGIN
LOOP
new_id := generate_short_id();
BEGIN
NEW.short_id = new_id;
RETURN NEW;
EXCEPTION WHEN unique_violation THEN
attempts := attempts + 1;
IF attempts > 5 THEN
RAISE EXCEPTION 'Could not generate unique ID after 5 attempts';
END IF;
CONTINUE;
END;
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- Create trigger
CREATE TRIGGER set_calendar_short_id
BEFORE INSERT ON calendars
FOR EACH ROW
EXECUTE FUNCTION public.set_calendar_short_id();