Files
siren/migrations/000_initial.sql
2026-04-04 12:22:17 -04:00

171 lines
5.6 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
CREATE TABLE IF NOT EXISTS guilds (
id BIGINT PRIMARY KEY NOT NULL,
name TEXT,
owner_id BIGINT,
volume INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS dice_track (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
guild_id BIGINT NOT NULL,
owner_id BIGINT NOT NULL,
dice TEXT NOT NULL,
user_id BIGINT,
value INT,
operator TEXT
);
CREATE TABLE IF NOT EXISTS events (
id UUID PRIMARY KEY NOT NULL,
guild_id BIGINT NOT NULL,
author_id BIGINT NOT NULL,
title TEXT NOT NULL,
date_time TIMESTAMP NOT NULL,
description TEXT,
rsvp BIGINT[] NOT NULL
);
CREATE TABLE IF NOT EXISTS races (
id INTEGER GENERATED ALWAYS AS IDENTITY,
name TEXT NOT NULL,
size TEXT NOT NULL,
source TEXT NOT NULL,
data JSON NOT NULL
);
CREATE TABLE IF NOT EXISTS classes (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS feats (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS options_features (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS backgrounds (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS items (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS spells (
id INTEGER GENERATED ALWAYS AS IDENTITY,
name TEXT NOT NULL,
school TEXT NOT NULL,
level INTEGER NOT NULL,
ritual BOOLEAN DEFAULT FALSE,
concentration BOOLEAN DEFAULT FALSE,
classes TEXT[] NOT NULL,
damage_inflict TEXT[] NOT NULL,
damage_resist TEXT[] NOT NULL,
conditions TEXT[] NOT NULL,
saving_throw TEXT[] NOT NULL,
attack_type TEXT,
data JSONB NOT NULL
);
CREATE TABLE IF NOT EXISTS conditions (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
CREATE TABLE IF NOT EXISTS bestiary (
id INTEGER GENERATED ALWAYS AS IDENTITY
);
-- ============================================================
-- Auth / Users
-- ============================================================
-- Core local user accounts. password_hash is NULL for OAuth-only users.
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
username TEXT UNIQUE NOT NULL,
password_hash TEXT,
email TEXT UNIQUE,
first_name TEXT,
last_name TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- External OAuth provider connections (Discord, etc.)
CREATE TABLE IF NOT EXISTS user_connections (
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
provider TEXT NOT NULL,
provider_user_id TEXT NOT NULL,
provider_username TEXT,
provider_avatar TEXT,
PRIMARY KEY (user_id, provider),
UNIQUE (provider, provider_user_id)
);
-- ============================================================
-- Grid maps: unbounded canvas, CSPRNG TEXT ids, auth-aware
-- ============================================================
-- public_access: 'private' | 'public_view' | 'public_edit'
-- private only users with explicit map_permissions can see/edit
-- public_view anyone with the link can view; only permissioned users can edit
-- public_edit anyone with the link can view AND edit
CREATE TABLE IF NOT EXISTS grid_maps (
id TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
public_access TEXT NOT NULL DEFAULT 'private'
CHECK (public_access IN ('private', 'public_view', 'public_edit')),
owner_id UUID NOT NULL REFERENCES users(id),
colors TEXT[] NOT NULL DEFAULT ARRAY[
'#6b7280',
'#92400e',
'#15803d',
'#1d4ed8',
'#7c3aed',
'#dc2626',
'#ca8a04',
'#0f172a',
'#f9fafb'
],
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- Per-map role assignments; owner is auto-inserted on map creation
CREATE TABLE IF NOT EXISTS map_permissions (
map_id TEXT NOT NULL REFERENCES grid_maps(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role TEXT NOT NULL CHECK (role IN ('owner', 'editor', 'viewer')),
PRIMARY KEY (map_id, user_id)
);
-- Maps a user has favorited; makes them appear in the user's map list modal
-- even if they have no explicit map_permissions entry (e.g. public maps)
CREATE TABLE IF NOT EXISTS map_favorites (
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
map_id TEXT NOT NULL REFERENCES grid_maps(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (user_id, map_id)
);
-- Pending/resolved requests from users wanting viewer or editor access
CREATE TABLE IF NOT EXISTS map_access_requests (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
map_id TEXT NOT NULL REFERENCES grid_maps(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
requested_role TEXT NOT NULL CHECK (requested_role IN ('editor', 'viewer')),
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'denied')),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
UNIQUE (map_id, user_id)
);
-- Composite primary key replaces the old UUID id column
CREATE TABLE IF NOT EXISTS grid_cells (
map_id TEXT NOT NULL REFERENCES grid_maps(id) ON DELETE CASCADE,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
color TEXT NOT NULL DEFAULT '#808080',
PRIMARY KEY (map_id, x, y)
);
CREATE TABLE IF NOT EXISTS grid_tokens (
id TEXT PRIMARY KEY NOT NULL,
map_id TEXT NOT NULL REFERENCES grid_maps(id) ON DELETE CASCADE,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
label TEXT NOT NULL,
color TEXT NOT NULL DEFAULT '#4444FF'
);