This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
-- Wedding website bootstrap schema
|
||||
-- Requires: PostgreSQL 13+
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invitations (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
token text NOT NULL,
|
||||
display_name text NOT NULL,
|
||||
language text NOT NULL,
|
||||
contact_email text NULL,
|
||||
contact_phone text NULL,
|
||||
max_party_size integer NOT NULL DEFAULT 1,
|
||||
allow_member_edits boolean NOT NULL DEFAULT false,
|
||||
notes text NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT invitations_max_party_size_positive CHECK (max_party_size > 0)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS invitations_token_unique ON invitations (token);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invitation_members (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
is_primary_contact boolean NOT NULL DEFAULT false,
|
||||
attending boolean NULL,
|
||||
meal_preference text NULL,
|
||||
dietary_restrictions text NULL,
|
||||
notes text NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS invitation_members_invitation_id_idx
|
||||
ON invitation_members (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invitation_responses (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
submitted_at timestamptz NULL,
|
||||
arrival_date date NULL,
|
||||
departure_date date NULL,
|
||||
stay_location text NULL,
|
||||
coming_from text NULL,
|
||||
needs_transport_help boolean NULL,
|
||||
message_to_couple text NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS invitation_responses_invitation_id_unique
|
||||
ON invitation_responses (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS photo_uploads (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
bucket text NOT NULL,
|
||||
object_key text NOT NULL,
|
||||
original_filename text NULL,
|
||||
content_type text NULL,
|
||||
size_bytes integer NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT photo_uploads_size_bytes_non_negative
|
||||
CHECK (size_bytes IS NULL OR size_bytes >= 0)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS photo_uploads_invitation_id_unique
|
||||
ON photo_uploads (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS song_requests (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
artist text NULL,
|
||||
note text NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS song_requests_invitation_id_idx
|
||||
ON song_requests (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS toast_requests (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
member_id uuid NULL REFERENCES invitation_members(id) ON DELETE SET NULL,
|
||||
speaker_name text NOT NULL,
|
||||
estimated_minutes integer NULL,
|
||||
note text NULL,
|
||||
status text NOT NULL DEFAULT 'pending',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT toast_requests_status_valid
|
||||
CHECK (status IN ('pending', 'accepted', 'declined', 'scheduled')),
|
||||
CONSTRAINT toast_requests_estimated_minutes_positive
|
||||
CHECK (estimated_minutes IS NULL OR estimated_minutes > 0)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS toast_requests_invitation_id_idx
|
||||
ON toast_requests (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS guest_messages (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
invitation_id uuid NOT NULL REFERENCES invitations(id) ON DELETE CASCADE,
|
||||
type text NOT NULL,
|
||||
message text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT guest_messages_type_valid CHECK (type IN ('advice', 'memory', 'wish'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS guest_messages_invitation_id_idx
|
||||
ON guest_messages (invitation_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS admin_audit_events (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
admin_email text NOT NULL,
|
||||
action text NOT NULL,
|
||||
target_type text NULL,
|
||||
target_id uuid NULL,
|
||||
metadata jsonb NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Remove guest-facing fields that are no longer collected.
|
||||
|
||||
DROP TABLE IF EXISTS song_requests;
|
||||
DROP TABLE IF EXISTS guest_messages;
|
||||
|
||||
ALTER TABLE invitation_responses
|
||||
DROP COLUMN IF EXISTS coming_from;
|
||||
|
||||
ALTER TABLE toast_requests
|
||||
DROP COLUMN IF EXISTS note;
|
||||
Reference in New Issue
Block a user