From 49e523485b7d73adb8405772bc15bc3ee1dd6906 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Wed, 15 May 2024 17:18:17 +0200 Subject: [PATCH] Remodeled database and api to prepare for move --- components/calendar/Dashboard.vue | 12 + components/profile/Dashboard.vue | 55 ++++ components/profile/Layout.vue | 9 - components/ui/card/Card.vue | 2 +- models/CalendarConfig.ts | 6 + models/World.ts | 7 + package.json | 3 +- pages/{calendar.vue => calendar-old.vue} | 0 pages/calendar/[id].vue | 30 +++ pages/index.vue | 2 +- pages/profile.vue | 6 +- pnpm-lock.yaml | 8 + server/api/calendars/query.get.ts | 23 ++ server/api/characters.ts | 252 ------------------ server/api/characters/index.get.ts | 18 ++ server/api/characters/query.get.ts | 29 ++ server/api/{events.ts => events/index.get.ts} | 0 server/api/events/query.get.ts | 23 ++ server/api/worlds/index.get.ts | 10 + supabase/migrations/202401_init.sql | 151 ++++++++++- supabase/seed.sql | 107 +++++++- 21 files changed, 479 insertions(+), 274 deletions(-) create mode 100644 components/calendar/Dashboard.vue create mode 100644 components/profile/Dashboard.vue delete mode 100644 components/profile/Layout.vue create mode 100644 models/CalendarConfig.ts create mode 100644 models/World.ts rename pages/{calendar.vue => calendar-old.vue} (100%) create mode 100644 pages/calendar/[id].vue create mode 100644 server/api/calendars/query.get.ts delete mode 100644 server/api/characters.ts create mode 100644 server/api/characters/index.get.ts create mode 100644 server/api/characters/query.get.ts rename server/api/{events.ts => events/index.get.ts} (100%) create mode 100644 server/api/events/query.get.ts create mode 100644 server/api/worlds/index.get.ts diff --git a/components/calendar/Dashboard.vue b/components/calendar/Dashboard.vue new file mode 100644 index 0000000..8b09064 --- /dev/null +++ b/components/calendar/Dashboard.vue @@ -0,0 +1,12 @@ + + + diff --git a/components/profile/Dashboard.vue b/components/profile/Dashboard.vue new file mode 100644 index 0000000..17b9a6f --- /dev/null +++ b/components/profile/Dashboard.vue @@ -0,0 +1,55 @@ + + + diff --git a/components/profile/Layout.vue b/components/profile/Layout.vue deleted file mode 100644 index 623d0a6..0000000 --- a/components/profile/Layout.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/components/ui/card/Card.vue b/components/ui/card/Card.vue index 0dcc36a..18bebb2 100644 --- a/components/ui/card/Card.vue +++ b/components/ui/card/Card.vue @@ -12,7 +12,7 @@ const props = defineProps<{
+import type { MenuItem } from '~/components/global/SidebarProps'; + +const user = useSupabaseUser() + +useHead({ + title: 'Calendrier' +}) + +definePageMeta({ + middleware: ['auth-guard'] +}) + +// Redirect user back home when they log out on the page +watch(user, (n, _o) => { + if (!n) { + navigateTo('/') + } +}) + +const sidebarMenu: MenuItem[] = [] + + + diff --git a/pages/index.vue b/pages/index.vue index f4eb51d..9ec7533 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -13,7 +13,7 @@ const sidebarMenu: MenuItem[] = []
- + Calendrier diff --git a/pages/profile.vue b/pages/profile.vue index 8f95e87..4247710 100644 --- a/pages/profile.vue +++ b/pages/profile.vue @@ -21,9 +21,9 @@ const sidebarMenu: MenuItem[] = [] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb0846d..6078893 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: vue-router: specifier: ^4.3.2 version: 4.3.2(vue@3.4.27(typescript@5.4.5)) + zod: + specifier: ^3.23.8 + version: 3.23.8 devDependencies: '@nuxtjs/color-mode': specifier: ^3.4.1 @@ -4734,6 +4737,9 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -10202,3 +10208,5 @@ snapshots: archiver-utils: 5.0.2 compress-commons: 6.0.2 readable-stream: 4.5.2 + + zod@3.23.8: {} diff --git a/server/api/calendars/query.get.ts b/server/api/calendars/query.get.ts new file mode 100644 index 0000000..d6e8c39 --- /dev/null +++ b/server/api/calendars/query.get.ts @@ -0,0 +1,23 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('world_calendars') + .select(` + id, + months, + days_per_year, + events (*) + `) + .eq('world_id', query.world_id) + + return output +}) diff --git a/server/api/characters.ts b/server/api/characters.ts deleted file mode 100644 index d833251..0000000 --- a/server/api/characters.ts +++ /dev/null @@ -1,252 +0,0 @@ -export default defineEventHandler(() => { - return [ - /** - * Player characters - */ - // "Les Milles Cages" - { - name: 'Sulvan Trois-Barbes', - birth: { day: 20, month: 3, year: 3169 }, - wiki: 'https://alexcreates.fr/leim/index.php/Sulvan_Trois-Barbes', - category: 'joueur', - secondaryCategories: ['criminel', 'étincelle'] - }, - { - name: 'Vascylly', - birth: { day: 3, month: 5, year: 3181 }, - wiki: 'https://alexcreates.fr/leim/index.php/Vascylly', - category: 'joueur', - secondaryCategories: ['mage'] - }, - { - name: 'Tara Belyus', - birth: { day: 14, month: 9, year: 3186 }, - category: 'joueur', - secondaryCategories: ['mage'] - }, - // "Les Cloches de Cantane" - { - name: 'Malik', - birth: { day: 22, month: 8, year: 3181 }, - category: 'joueur', - secondaryCategories: ['scientifique'] - }, - { - name: 'Elie', - birth: { day: 5, month: 6, year: 3192 }, - category: 'joueur', - secondaryCategories: ['ecclésiastique'] - }, - { - name: 'Clayron', - birth: { day: 3, month: 5, year: 3178 }, - category: 'joueur', - secondaryCategories: ['sentinelle'] - }, - - /** - * NPC - */ - // Counts of the Alliance - { - name: 'Alfrid de Lagarde', - birth: { day: 29, month: 7, year: 3193 }, - wiki: 'https://alexcreates.fr/leim/index.php/Alfrid_de_Lagarde', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Alaric de Lagarde', - birth: { day: 23, month: 8, year: 3192 }, - wiki: 'https://alexcreates.fr/leim/index.php/Alaric_de_Lagarde', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Anastael III de Quillon', - birth: { day: 1, month: 5, year: 3184 }, - wiki: 'https://alexcreates.fr/leim/index.php/Anastael_III_de_Quillon', - category: 'comte', - secondaryCategories: ['sentinelle', 'buse blanche'] - }, - { - name: 'Antoine de Mireloin', - birth: { day: 31, month: 5, year: 3190 }, - wiki: 'https://alexcreates.fr/leim/index.php/Antoine_de_Mireloin', - category: 'comte' - }, - { - name: 'Armance Ronchère', - birth: { day: 1, month: 1, year: 3132 }, - wiki: 'https://alexcreates.fr/leim/index.php/Armance_Ronchère', - category: 'comte' - }, - { - name: 'Baranne Rougefer', - birth: { day: 1, month: 0, year: 3175 }, - wiki: 'https://alexcreates.fr/leim/index.php/Baranne_Rougefer', - category: 'comte', - secondaryCategories: ['sentinelle'] - }, - { - name: 'Béatrice II de Grandlac', - birth: { day: 21, month: 4, year: 3158 }, - wiki: 'https://alexcreates.fr/leim/index.php/Béatrice_II_de_Grandlac', - category: 'comte', - secondaryCategories: ['mage'] - }, - { - name: 'Favio Asharos-Losantelle', - birth: { day: 17, month: 3, year: 3091 }, - wiki: 'https://alexcreates.fr/leim/index.php/Favio_Asharos-Losantelle', - category: 'comte', - secondaryCategories: ['mage'] - }, - { - name: 'Firmin de Montardieu', - birth: { day: 9, month: 2, year: 3203 }, - wiki: 'https://alexcreates.fr/leim/index.php/Firmin_de_Montardieu', - category: 'comte' - }, - { - name: 'Laura de Montardieu', - birth: { day: 32, month: 3, year: 3167 }, - death: { day: 1, month: 4, year: 3217 }, - hiddenDeath: true, - wiki: 'https://alexcreates.fr/leim/index.php/Laura_de_Montardieu', - category: 'comte' - }, - { - name: 'Lazarus Tymos', - birth: { day: 29, month: 9, year: 3145 }, - wiki: 'https://alexcreates.fr/leim/index.php/Lazarus_Tymos', - category: 'comte', - secondaryCategories: ['mage', 'buse blanche'] - }, - { - name: 'Marion de Corambre', - birth: { day: 14, month: 7, year: 3190 }, - wiki: 'https://alexcreates.fr/leim/index.php/Marion_de_Corambre', - category: 'comte', - secondaryCategories: ['scientifique', 'ecclésiastique'] - }, - { - name: 'Relforg Pergaré', - birth: { day: 18, month: 9, year: 3182 }, - wiki: 'https://alexcreates.fr/leim/index.php/Relforg_Pergaré', - category: 'comte' - }, - { - name: 'Vilgarde de Ternâcre', - birth: { day: 3, month: 3, year: 2998 }, - wiki: 'https://alexcreates.fr/leim/index.php/Vilgarde_de_Ternâcre', - category: 'comte' - }, - { - name: 'Ysildy Milopée', - birth: { day: 3, month: 1, year: 3187 }, - wiki: 'https://alexcreates.fr/leim/index.php/Ysildy_Milopée', - category: 'comte', - secondaryCategories: ['mage', 'scientifique', 'professeur'] - }, - - // Sparks - { - name: 'Izàc Tymos', - birth: { day: 13, month: 6, year: 3192 }, - wiki: 'https://alexcreates.fr/leim/index.php/Izàc_Tymos', - category: 'mage', - secondaryCategories: ['étincelle', 'criminel', 'professeur', 'scientifique'] - }, - { - name: 'Tvernée', - birth: { day: 19, month: 2, year: 3205 }, - wiki: 'https://alexcreates.fr/leim/index.php/Tvernée', - category: 'étincelle', - secondaryCategories: ['criminel'] - }, - - // Pirates - { - name: 'Räzal', - birth: { day: 13, month: 8, year: 3178 }, - wiki: 'https://alexcreates.fr/leim/index.php/Räzal' - }, - - // Legends - { - name: 'Jorhas Kirendre', - birth: { day: 2, month: 9, year: -452 }, - death: { day: 2, month: 2, year: -419 }, - category: 'sentinelle', - wiki: 'https://alexcreates.fr/leim/index.php/Jorhas_Kirendre' - }, - - // "Les Milles Cages" - { - name: 'Ernestin Pomel', - birth: { day: 11, month: 2, year: 3179 }, - wiki: 'https://alexcreates.fr/leim/index.php/Ernestin_Pomel', - category: 'mage' - }, - { - name: 'Quacille Lévios', - birth: { day: 3, month: 6, year: 3162 }, - wiki: 'https://alexcreates.fr/leim/index.php/Quacille_Lévios', - category: 'professeur', - secondaryCategories: ['mage'] - }, - { - name: 'Morel Lévios', - birth: { day: 26, month: 3, year: 3157 }, - wiki: 'https://alexcreates.fr/leim/index.php/Morel_Lévios', - category: 'sentinelle', - secondaryCategories: ['mage', 'buse blanche'] - }, - { - name: 'Anastael Simon', - birth: { day: 32, month: 2, year: 3166 }, - wiki: 'https://alexcreates.fr/leim/index.php/Anastael_Simon', - category: 'étincelle', - secondaryCategories: ['mage'] - }, - { - name: 'Grestain', - birth: { day: 9, month: 2, year: 3162 }, - wiki: 'https://alexcreates.fr/leim/index.php/Grestain', - category: 'criminel', - secondaryCategories: ['mage'] - }, - { - name: 'Lucien Malanth', - birth: { day: 31, month: 4, year: 3167 }, - wiki: 'https://alexcreates.fr/leim/index.php/Lucien_Malanth', - category: 'criminel', - secondaryCategories: ['mage'] - }, - { - name: 'Tivian Rodhus', - birth: { day: 13, month: 3, year: 3157 }, - wiki: 'https://alexcreates.fr/leim/index.php/Tivian_Rodhus', - category: 'professeur', - secondaryCategories: ['mage', 'criminel'] - }, - - // "Les Cloches de Cantane" - { - name: 'Bénédicte Vaht', - description: "Moine d'Ikami ayant entrepris la construction du Pilier Blanc de Cantane", - birth: { day: 28, month: 6, year: 3139 }, - category: 'ecclésiastique' - }, - { - name: 'Taleb Vaht', - description: - "Fils de Bénédicte, il s'est engagé auprès des Étincelles comme alchimiste artificier.", - birth: { day: 9, month: 1, year: 3180 }, - death: { day: 28, month: 7, year: 3209 }, - category: 'étincelle', - secondaryCategories: ['scientifique'] - } - ] -}) diff --git a/server/api/characters/index.get.ts b/server/api/characters/index.get.ts new file mode 100644 index 0000000..1f9fa2e --- /dev/null +++ b/server/api/characters/index.get.ts @@ -0,0 +1,18 @@ +import { serverSupabaseClient } from "#supabase/server"; +import type { Character } from "~/models/Characters"; + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + + return client.from('characters') + .select(` + id, + name, + description, + birth, + death, + wiki, + characters_category (id, name) + `) + .returns() +}) diff --git a/server/api/characters/query.get.ts b/server/api/characters/query.get.ts new file mode 100644 index 0000000..4ad61fe --- /dev/null +++ b/server/api/characters/query.get.ts @@ -0,0 +1,29 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('characters') + .select(` + id, + name, + description, + birth, + death, + wiki, + characters_category (id, name) + `) + + if (query.world_id) { + output.eq('world_id', query.world_id) + } + + return output +}) diff --git a/server/api/events.ts b/server/api/events/index.get.ts similarity index 100% rename from server/api/events.ts rename to server/api/events/index.get.ts diff --git a/server/api/events/query.get.ts b/server/api/events/query.get.ts new file mode 100644 index 0000000..0331304 --- /dev/null +++ b/server/api/events/query.get.ts @@ -0,0 +1,23 @@ +import { serverSupabaseClient } from "#supabase/server"; +import { z } from 'zod' + +const querySchema = z.object({ + world_id: z.number({ coerce: true }).positive().int() +}) + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + const query = await getValidatedQuery(event, querySchema.parse) + + const output = client + .from('events') + .select(` + id, + title, + description, + world_calendars (id, world_id) + `) + .eq('world_calendars.world_id', query.world_id) + + return output +}) diff --git a/server/api/worlds/index.get.ts b/server/api/worlds/index.get.ts new file mode 100644 index 0000000..3dbc6e2 --- /dev/null +++ b/server/api/worlds/index.get.ts @@ -0,0 +1,10 @@ +import { serverSupabaseClient } from "#supabase/server"; +import type { World } from "~/models/World"; + +export default defineEventHandler(async (event) => { + const client = await serverSupabaseClient(event) + + return client.from('worlds') + .select(`id, name, description, color`) + .returns() +}) diff --git a/supabase/migrations/202401_init.sql b/supabase/migrations/202401_init.sql index 8cbfaa8..7b81467 100644 --- a/supabase/migrations/202401_init.sql +++ b/supabase/migrations/202401_init.sql @@ -4,9 +4,11 @@ -- Custom types create type public.app_permission as enum ('events.see.hidden', 'users.ban'); -create type public.app_role as enum ('sa', 'gm'); +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'); --- USERS +-- DATA STRUCTURES +-- Users create table public.users ( id uuid references auth.users not null primary key, -- UUID from auth.users username text @@ -14,16 +16,16 @@ create table public.users ( comment on table public.users is 'Profile data for each user.'; comment on column public.users.id is 'References the internal Supabase Auth user.'; --- USER ROLES +-- Roles create table public.user_roles ( id bigint generated by default as identity primary key, - user_id uuid references public.users on delete cascade not null, role app_role not null, + user_id uuid references public.users on delete cascade not null, unique (user_id, role) ); comment on table public.user_roles is 'Application roles for each user.'; --- ROLE PERMISSIONS +-- Permissions create table public.role_permissions ( id bigint generated by default as identity primary key, role app_role not null, @@ -32,6 +34,70 @@ create table public.role_permissions ( ); comment on table public.role_permissions is 'Application permissions for each role.'; +-- Worlds +create table public.worlds ( + id bigint generated by default as identity primary key, + name text not null, + description text, + color app_colors, + gm_id uuid references public.users on delete cascade +); +comment on table public.worlds is 'Worlds belonging to a single user ; a game master.'; + +-- World Calendars +create table public.world_calendars ( + id bigint generated by default as identity primary key, + months text array, + days_per_year int not null, + world_id bigint references public.worlds on delete cascade not null +); +comment on table public.world_calendars is 'Calendar settings and configuration attached to a single world.'; + +-- Event categories +create table public.events_category ( + id bigint generated by default as identity primary key, + name text not null, + unique (name) +); +comment on table public.events_category is 'Categories describing events'; + +-- Events +create table public.events ( + id bigint generated by default as identity primary key, + title text not null, + description text, + start_date json not null, + end_date json, + category bigint references public.events_category on delete cascade, + hidden boolean, + wiki text, + calendar_id bigint references public.world_calendars on delete cascade not null +); +comment on table public.events is 'Events linked to a world'; + +-- Character categories +create table public.characters_category ( + id bigint generated by default as identity primary key, + name text not null, + unique (name) +); +comment on table public.characters_category is 'Categories describing characters'; + +-- Characters +create table public.characters ( + id bigint generated by default as identity primary key, + name text not null, + description text, + birth json not null, + death json, + category bigint references public.characters_category on delete cascade, + hidden_birth boolean, + hidden_death boolean, + wiki text, + world_id bigint references public.worlds on delete cascade not null +); +comment on table public.characters is 'Characters linked to a world'; + -- authorize with role-based access control (RBAC) create function public.authorize( requested_permission app_permission @@ -54,11 +120,84 @@ $$ language plpgsql security definer set search_path = public; alter table public.users enable row level security; alter table public.user_roles enable row level security; alter table public.role_permissions enable row level security; +alter table public.worlds enable row level security; +alter table public.world_calendars enable row level security; +alter table public.events_category enable row level security; +alter table public.characters_category enable row level security; +alter table public.characters enable row level security; +alter table public.events enable row level security; + +-- User policies create policy "Allow logged-in read access" on public.users for select using ( auth.role() = 'authenticated' ); create policy "Allow individual insert access" on public.users for insert with check ( auth.uid() = id ); create policy "Allow individual update access" on public.users for update using ( auth.uid() = id ); create policy "Allow individual read access" on public.user_roles for select using ( auth.uid() = user_id ); +-- World policies +create policy "Allow individual read access for GMs" on public.worlds for select using ( ( auth.uid() = gm_id ) ); +create policy "Allow individual insert access for GMs" on public.worlds for insert with check ( auth.uid() = gm_id ); +create policy "Allow individual update access for GMs" on public.worlds for update using ( auth.uid() = gm_id ); + +-- Calendar policies +create policy "Allow individual read access for GMs" on public.world_calendars for select using ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); +create policy "Allow individual insert access for GMs" on public.world_calendars for insert with check ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); +create policy "Allow individual update access for GMs" on public.world_calendars for update with check ( + exists ( + select 1 from worlds + where worlds.id = world_calendars.world_id + ) +); + +-- Event policies +create policy "Allow individual read access for GMs" on public.events for select using ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); +create policy "Allow individual insert access for GMs" on public.events for insert with check ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); +create policy "Allow individual update access for GMs" on public.events for update with check ( + exists ( + select 1 from world_calendars + where world_calendars.id = events.calendar_id + ) +); + +-- Character policies +create policy "Allow individual read access for GMs" on public.characters for select using ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); +create policy "Allow individual insert access for GMs" on public.characters for insert with check ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); +create policy "Allow individual update access for GMs" on public.characters for update with check ( + exists ( + select 1 from worlds + where worlds.id = characters.world_id + ) +); + -- Send "previous data" on change alter table public.users replica identity full; @@ -69,6 +208,8 @@ declare is_admin boolean; begin insert into public.users (id, username) values (new.id, new.email); + insert into public.user_roles (role, user_id) + values ('user', new.id); return new; end; diff --git a/supabase/seed.sql b/supabase/seed.sql index f9b307a..efb1df7 100644 --- a/supabase/seed.sql +++ b/supabase/seed.sql @@ -1,4 +1,107 @@ -insert into public.role_permissions (role, permission) values ('gm', 'events.see.hidden'); - insert into public.role_permissions (role, permission) values ('sa', 'events.see.hidden'); insert into public.role_permissions (role, permission) values ('sa', 'users.ban'); + +-- Event categories +insert into public.events_category (name) values ('naissance'); +insert into public.events_category (name) values ('mort'); +insert into public.events_category (name) values ('catastrophe'); +insert into public.events_category (name) values ('catastrophe naturelle'); +insert into public.events_category (name) values ('inauguration'); +insert into public.events_category (name) values ('religion'); +insert into public.events_category (name) values ('invention'); +insert into public.events_category (name) values ('science'); +insert into public.events_category (name) values ('bénédiction'); +insert into public.events_category (name) values ('joueurs'); +insert into public.events_category (name) values ('découverte'); +insert into public.events_category (name) values ('exploration'); +insert into public.events_category (name) values ('construction'); +insert into public.events_category (name) values ('arcanologie'); +insert into public.events_category (name) values ('criminalité'); +insert into public.events_category (name) values ('scandale'); +insert into public.events_category (name) values ('commerce'); +insert into public.events_category (name) values ('législation'); + +-- Character categories +insert into public.characters_category (name) values ('joueur'); +insert into public.characters_category (name) values ('comte'); +insert into public.characters_category (name) values ('scientifique'); +insert into public.characters_category (name) values ('mage'); +insert into public.characters_category (name) values ('professeur'); +insert into public.characters_category (name) values ('criminel'); +insert into public.characters_category (name) values ('étincelle'); +insert into public.characters_category (name) values ('buse blanche'); +insert into public.characters_category (name) values ('ecclésiastique'); +insert into public.characters_category (name) values ('militaire'); +insert into public.characters_category (name) values ('activiste'); +insert into public.characters_category (name) values ('commerçant'); + +-- Worlds +insert into public.worlds (name, description, color) values ('Léïm', 'Monde d''aventures et d''intrigues med-fan', 'black'); + +-- Worlds' calendars +insert into public.world_calendars (world_id, months, days_per_year) values (1, ARRAY['Jalen', 'Malsen', 'Verlys', 'Nalys', 'Verdore', 'Sidore', 'Lyllion', 'Rion', 'Farene', 'Dalvene'], 320); + +-- Events +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Laurdieu devient la première cité de l''empire de Kaliatos', + 'L''empire de Kaliatos établi sa capitale dans la cité de Laurdieu, qui connaitra une prospérité nouvelle au sein d''Aldys.', + '{ "day": 3, "month": 4, "year": -1932 }', + 18, + true, + 'https://alexcreates.fr/leim/index.php/Laurdieu', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Apparition d''Asménys', + 'La défunte chanteuse Asménys apparaît à un barde pendant son jeune public, démarrant la religion des Prêtresses d''Asménys.', + '{ "day": 19, "month": 7, "year": -1358 }', + 6, + true, + 'https://alexcreates.fr/leim/index.php/Pr%C3%AAtresses_d%27Asm%C3%A9nys', + 1 +); +insert into public.events (title, description, start_date, end_date, category, hidden, wiki, calendar_id) values ( + 'La Rupture', + 'Les Abysses se déversent à la surface de Léim, à travers plusieurs brèches. Plusieurs hordes de démons se rapprochent des villes, et ce qu''on appellera l''Âge des Abysses commencent alors sur la planète entière.', + '{ "day": 26, "month": 5, "year": -756 }', + '{ "day": 4, "month": 9, "year": 29 }', + 3, + true, + 'https://alexcreates.fr/leim/index.php/Seconde_Rupture', + 1 +); +insert into public.events (title, description, start_date, end_date, category, hidden, wiki, calendar_id) values ( + 'Marche du sang', + 'L''empereur de Kaliatos ordonne personnellement la traque de Jorhas Kirendre pour connivence avec les démons. Plusieurs bataillons sont affectés à la chasse de Jorhas, qui se terminera par son incarcération ainsi que la mort de plusieurs centaines de soldats.', + '{ "day": 18, "month": 9, "year": -420 }', + '{ "day": 27, "month": 1, "year": -419 }', + 15, + true, + 'https://alexcreates.fr/leim/index.php/Jorhas_Kirendre', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Exécution de Tyhos', + 'Le léviathan Tyhos rend l''âme après un combat de plusieurs années contre Lystos, le dieu du Soleil.', + '{ "day": 1, "month": 0, "year": 0 }', + 9, + true, + 'https://alexcreates.fr/leim/index.php/Tyhos', + 1 +); +insert into public.events (title, start_date, category, wiki, calendar_id) values ( + 'Traité de Kadel', + '{ "day": 29, "month": 4, "year": 100 }', + 5, + 'https://alexcreates.fr/leim/index.php/Alliance_Kald%C3%A9lienne#Trait%C3%A9_de_Kadel', + 1 +); +insert into public.events (title, description, start_date, category, hidden, wiki, calendar_id) values ( + 'Découverte des Plaines de Poussières', + 'Les troupes de la reconquête aldienne explorent le littoral d''une immense étendue grise et inerte.', + '{ "day": 17, "month": 7, "year": 305 }', + 11, + true, + 'https://alexcreates.fr/leim/index.php/Plaines_de_poussi%C3%A8re', + 1 +);