Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 230 additions & 5 deletions db/schema.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
\restrict Dg0ksc8IIsh0chvkrHOQy7LtnwsmjF3WyModqIXmKLfbi99THWiNyWMb9U47Fk5
\restrict EIvSglJHygsNcIKc7gr1LRqCWzak1b2BYTPO17s7oUnsrweJPJORd0ywNzjCr4G

-- Dumped from database version 16.10
-- Dumped by pg_dump version 18.0
-- Dumped by pg_dump version 18.1

SET statement_timeout = 0;
SET lock_timeout = 0;
Expand Down Expand Up @@ -48,6 +48,59 @@ CREATE TABLE public.auth_tokens (
);


--
-- Name: campaign_characters; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.campaign_characters (
id character varying(26) NOT NULL,
campaign_id character varying(26) NOT NULL,
character_id character varying(26) NOT NULL,
revealed_at timestamp with time zone,
added_by character varying(26) NOT NULL,
added_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);


--
-- Name: campaign_members; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.campaign_members (
id character varying(26) NOT NULL,
campaign_id character varying(26) NOT NULL,
user_id character varying(26) NOT NULL,
role text NOT NULL,
invited_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
invited_by character varying(26) NOT NULL,
accepted_at timestamp with time zone,
declined_at timestamp with time zone,
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
invite_token character varying(26),
deleted_at timestamp without time zone,
CONSTRAINT campaign_members_not_both_accepted_and_declined CHECK ((NOT ((accepted_at IS NOT NULL) AND (declined_at IS NOT NULL)))),
CONSTRAINT campaign_members_role_check CHECK ((role = ANY (ARRAY['dm'::text, 'player'::text, 'viewer'::text])))
);


--
-- Name: campaigns; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.campaigns (
id character varying(26) NOT NULL,
name text NOT NULL,
description text,
created_by character varying(26) NOT NULL,
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
archived_at timestamp with time zone
);


--
-- Name: char_abilities; Type: TABLE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -443,7 +496,8 @@ CREATE TABLE public.users (
id character varying(26) NOT NULL,
email text NOT NULL,
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
name text
);


Expand All @@ -455,6 +509,46 @@ ALTER TABLE ONLY public.auth_tokens
ADD CONSTRAINT auth_tokens_pkey PRIMARY KEY (id);


--
-- Name: campaign_characters campaign_characters_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_characters
ADD CONSTRAINT campaign_characters_pkey PRIMARY KEY (id);


--
-- Name: campaign_characters campaign_characters_unique; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_characters
ADD CONSTRAINT campaign_characters_unique UNIQUE (campaign_id, character_id);


--
-- Name: campaign_members campaign_members_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_members
ADD CONSTRAINT campaign_members_pkey PRIMARY KEY (id);


--
-- Name: campaign_members campaign_members_unique; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_members
ADD CONSTRAINT campaign_members_unique UNIQUE (campaign_id, user_id);


--
-- Name: campaigns campaigns_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaigns
ADD CONSTRAINT campaigns_pkey PRIMARY KEY (id);


--
-- Name: char_abilities char_abilities_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -660,6 +754,55 @@ CREATE INDEX idx_auth_tokens_expires_at ON public.auth_tokens USING btree (expir
CREATE INDEX idx_auth_tokens_session_token_hash ON public.auth_tokens USING btree (session_token_hash);


--
-- Name: idx_campaign_characters_campaign_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaign_characters_campaign_id ON public.campaign_characters USING btree (campaign_id);


--
-- Name: idx_campaign_characters_character_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaign_characters_character_id ON public.campaign_characters USING btree (character_id);


--
-- Name: idx_campaign_members_campaign_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaign_members_campaign_id ON public.campaign_members USING btree (campaign_id);


--
-- Name: idx_campaign_members_invite_token; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaign_members_invite_token ON public.campaign_members USING btree (invite_token);


--
-- Name: idx_campaign_members_user_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaign_members_user_id ON public.campaign_members USING btree (user_id);


--
-- Name: idx_campaigns_created_by; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaigns_created_by ON public.campaigns USING btree (created_by);


--
-- Name: idx_campaigns_created_by_archived_at; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX idx_campaigns_created_by_archived_at ON public.campaigns USING btree (created_by, archived_at);


--
-- Name: idx_char_abilities_char_id_ability_created_at; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -863,6 +1006,27 @@ CREATE INDEX idx_uploads_user_id ON public.uploads USING btree (user_id);
CREATE UNIQUE INDEX idx_users_email ON public.users USING btree (email);


--
-- Name: campaign_characters campaign_characters_updated_at; Type: TRIGGER; Schema: public; Owner: -
--

CREATE TRIGGER campaign_characters_updated_at BEFORE UPDATE ON public.campaign_characters FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();


--
-- Name: campaign_members campaign_members_updated_at; Type: TRIGGER; Schema: public; Owner: -
--

CREATE TRIGGER campaign_members_updated_at BEFORE UPDATE ON public.campaign_members FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();


--
-- Name: campaigns campaigns_updated_at; Type: TRIGGER; Schema: public; Owner: -
--

CREATE TRIGGER campaigns_updated_at BEFORE UPDATE ON public.campaigns FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();


--
-- Name: char_abilities char_abilities_updated_at; Type: TRIGGER; Schema: public; Owner: -
--
Expand Down Expand Up @@ -975,6 +1139,62 @@ CREATE TRIGGER update_char_notes_updated_at BEFORE UPDATE ON public.char_notes F
CREATE TRIGGER users_updated_at BEFORE UPDATE ON public.users FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();


--
-- Name: campaign_characters campaign_characters_added_by_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_characters
ADD CONSTRAINT campaign_characters_added_by_fkey FOREIGN KEY (added_by) REFERENCES public.users(id) ON DELETE CASCADE;


--
-- Name: campaign_characters campaign_characters_campaign_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_characters
ADD CONSTRAINT campaign_characters_campaign_id_fkey FOREIGN KEY (campaign_id) REFERENCES public.campaigns(id) ON DELETE CASCADE;


--
-- Name: campaign_characters campaign_characters_character_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_characters
ADD CONSTRAINT campaign_characters_character_id_fkey FOREIGN KEY (character_id) REFERENCES public.characters(id) ON DELETE CASCADE;


--
-- Name: campaign_members campaign_members_campaign_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_members
ADD CONSTRAINT campaign_members_campaign_id_fkey FOREIGN KEY (campaign_id) REFERENCES public.campaigns(id) ON DELETE CASCADE;


--
-- Name: campaign_members campaign_members_invited_by_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_members
ADD CONSTRAINT campaign_members_invited_by_fkey FOREIGN KEY (invited_by) REFERENCES public.users(id) ON DELETE CASCADE;


--
-- Name: campaign_members campaign_members_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaign_members
ADD CONSTRAINT campaign_members_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;


--
-- Name: campaigns campaigns_created_by_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.campaigns
ADD CONSTRAINT campaigns_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.users(id) ON DELETE CASCADE;


--
-- Name: char_abilities char_abilities_character_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1163,7 +1383,7 @@ ALTER TABLE ONLY public.items
-- PostgreSQL database dump complete
--

\unrestrict Dg0ksc8IIsh0chvkrHOQy7LtnwsmjF3WyModqIXmKLfbi99THWiNyWMb9U47Fk5
\unrestrict EIvSglJHygsNcIKc7gr1LRqCWzak1b2BYTPO17s7oUnsrweJPJORd0ywNzjCr4G


--
Expand Down Expand Up @@ -1206,4 +1426,9 @@ INSERT INTO public.schema_migrations (version) VALUES
('20251111221748'),
('20251112060352'),
('20251112060400'),
('20251112060500');
('20251112060500'),
('20251122030300'),
('20251125200357'),
('20251126134731'),
('20251205001836'),
('20251209195618');
80 changes: 80 additions & 0 deletions migrations/20251122030300_create_campaigns.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
-- migrate:up

-- Campaigns table
CREATE TABLE campaigns (
id VARCHAR(26) PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
created_by VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_campaigns_created_by ON campaigns(created_by);

CREATE TRIGGER campaigns_updated_at
BEFORE UPDATE ON campaigns
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();

-- Campaign members (DMs, players, viewers)
CREATE TABLE campaign_members (
id VARCHAR(26) PRIMARY KEY,
campaign_id VARCHAR(26) NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
user_id VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role TEXT NOT NULL CHECK (role IN ('dm', 'player', 'viewer')),
invited_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
invited_by VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
accepted_at TIMESTAMPTZ,
declined_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT campaign_members_unique UNIQUE(campaign_id, user_id),
CONSTRAINT campaign_members_not_both_accepted_and_declined CHECK (NOT (accepted_at IS NOT NULL AND declined_at IS NOT NULL))
);

CREATE INDEX idx_campaign_members_campaign_id ON campaign_members(campaign_id);
CREATE INDEX idx_campaign_members_user_id ON campaign_members(user_id);

CREATE TRIGGER campaign_members_updated_at
BEFORE UPDATE ON campaign_members
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();

-- Campaign characters (characters added to campaigns)
CREATE TABLE campaign_characters (
id VARCHAR(26) PRIMARY KEY,
campaign_id VARCHAR(26) NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
character_id VARCHAR(26) NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
revealed_at TIMESTAMPTZ,
added_by VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
added_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT campaign_characters_unique UNIQUE(campaign_id, character_id)
);

CREATE INDEX idx_campaign_characters_campaign_id ON campaign_characters(campaign_id);
CREATE INDEX idx_campaign_characters_character_id ON campaign_characters(character_id);

CREATE TRIGGER campaign_characters_updated_at
BEFORE UPDATE ON campaign_characters
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();

-- migrate:down

DROP TRIGGER IF EXISTS campaign_characters_updated_at ON campaign_characters;
DROP INDEX IF EXISTS idx_campaign_characters_character_id;
DROP INDEX IF EXISTS idx_campaign_characters_campaign_id;
DROP TABLE IF EXISTS campaign_characters;

DROP TRIGGER IF EXISTS campaign_members_updated_at ON campaign_members;
DROP INDEX IF EXISTS idx_campaign_members_user_id;
DROP INDEX IF EXISTS idx_campaign_members_campaign_id;
DROP TABLE IF EXISTS campaign_members;

DROP TRIGGER IF EXISTS campaigns_updated_at ON campaigns;
DROP INDEX IF EXISTS idx_campaigns_created_by;
DROP TABLE IF EXISTS campaigns;

8 changes: 8 additions & 0 deletions migrations/20251125200357_add_archived_at_to_campaigns.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- migrate:up
-- Add archived_at column for soft-delete archiving of campaigns
ALTER TABLE campaigns ADD COLUMN archived_at TIMESTAMPTZ DEFAULT NULL;
CREATE INDEX idx_campaigns_created_by_archived_at ON campaigns(created_by, archived_at);

-- migrate:down
DROP INDEX IF EXISTS idx_campaigns_created_by_archived_at;
ALTER TABLE campaigns DROP COLUMN archived_at;
7 changes: 7 additions & 0 deletions migrations/20251126134731_add_invite_token_to_members.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- migrate:up
ALTER TABLE campaign_members ADD COLUMN invite_token VARCHAR(26);
CREATE INDEX idx_campaign_members_invite_token ON campaign_members(invite_token);

-- migrate:down
DROP INDEX IF EXISTS idx_campaign_members_invite_token;
ALTER TABLE campaign_members DROP COLUMN invite_token;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- migrate:up
ALTER TABLE campaign_members ADD COLUMN deleted_at timestamp;

-- migrate:down
ALTER TABLE campaign_members DROP COLUMN deleted_at;
Loading