|
| 1 | +-- schema.sql |
| 2 | +-- Database Schema for CAPY (Club Assistant in Python) |
| 3 | + |
| 4 | +-- 1. ENUMs & Functions |
| 5 | +CREATE TYPE user_role AS ENUM ('student', 'alumni', 'faculty', 'external'); |
| 6 | + |
| 7 | +CREATE OR REPLACE FUNCTION update_modified_column() |
| 8 | +RETURNS TRIGGER AS $$ |
| 9 | +BEGIN |
| 10 | + NEW.date_modified = CURRENT_DATE; |
| 11 | + RETURN NEW; |
| 12 | +END; |
| 13 | +$$ language 'plpgsql'; |
| 14 | + |
| 15 | +-- 2. Tables |
| 16 | +CREATE TABLE IF NOT EXISTS users ( |
| 17 | + uid UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 18 | + first_name TEXT NOT NULL, |
| 19 | + last_name TEXT NOT NULL, |
| 20 | + personal_email TEXT UNIQUE, |
| 21 | + school_email TEXT UNIQUE, |
| 22 | + phone TEXT, |
| 23 | + grad_year INT, |
| 24 | + role user_role DEFAULT 'student', |
| 25 | + date_created DATE DEFAULT CURRENT_DATE, |
| 26 | + date_modified DATE DEFAULT CURRENT_DATE |
| 27 | +); |
| 28 | + |
| 29 | +CREATE TABLE IF NOT EXISTS organizations ( |
| 30 | + oid UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 31 | + name TEXT NOT NULL, |
| 32 | + date_created DATE DEFAULT CURRENT_DATE, |
| 33 | + date_modified DATE DEFAULT CURRENT_DATE |
| 34 | +); |
| 35 | + |
| 36 | +CREATE TABLE IF NOT EXISTS org_members ( |
| 37 | + uid UUID REFERENCES users(uid) ON DELETE CASCADE, |
| 38 | + oid UUID REFERENCES organizations(oid) ON DELETE CASCADE, |
| 39 | + is_admin BOOLEAN DEFAULT FALSE, |
| 40 | + date_joined DATE DEFAULT CURRENT_DATE, |
| 41 | + last_active DATE DEFAULT CURRENT_DATE, |
| 42 | + PRIMARY KEY (uid, oid) |
| 43 | +); |
| 44 | + |
| 45 | +CREATE TABLE IF NOT EXISTS events ( |
| 46 | + eid UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 47 | + location TEXT, |
| 48 | + event_time TIMESTAMP, |
| 49 | + description TEXT, |
| 50 | + date_created DATE DEFAULT CURRENT_DATE, |
| 51 | + date_modified DATE DEFAULT CURRENT_DATE |
| 52 | +); |
| 53 | + |
| 54 | +CREATE TABLE IF NOT EXISTS event_hosting ( |
| 55 | + eid UUID REFERENCES events(eid) ON DELETE CASCADE, |
| 56 | + oid UUID REFERENCES organizations(oid) ON DELETE CASCADE, |
| 57 | + PRIMARY KEY (eid, oid) |
| 58 | +); |
| 59 | + |
| 60 | +CREATE TABLE IF NOT EXISTS event_registrations ( |
| 61 | + uid UUID REFERENCES users(uid) ON DELETE CASCADE, |
| 62 | + eid UUID REFERENCES events(eid) ON DELETE CASCADE, |
| 63 | + is_attending BOOLEAN DEFAULT FALSE, |
| 64 | + is_admin BOOLEAN DEFAULT FALSE, |
| 65 | + date_registered DATE DEFAULT CURRENT_DATE, |
| 66 | + PRIMARY KEY (uid, eid) |
| 67 | +); |
| 68 | + |
| 69 | +-- 3. Bot Tokens (global access for M2M authentication) |
| 70 | +CREATE TABLE IF NOT EXISTS bot_tokens ( |
| 71 | + token_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 72 | + token_hash TEXT NOT NULL, -- bcrypt hash of the token |
| 73 | + name TEXT NOT NULL, -- human-readable name for the bot |
| 74 | + created_by UUID NOT NULL REFERENCES users(uid), |
| 75 | + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| 76 | + last_used_at TIMESTAMP, |
| 77 | + expires_at TIMESTAMP, -- NULL = never expires |
| 78 | + is_active BOOLEAN DEFAULT TRUE |
| 79 | +); |
| 80 | + |
| 81 | +CREATE INDEX IF NOT EXISTS idx_bot_tokens_active ON bot_tokens(is_active) WHERE is_active = TRUE; |
| 82 | + |
| 83 | +-- 4. Triggers |
| 84 | +DROP TRIGGER IF EXISTS update_users_modtime ON users; |
| 85 | +CREATE TRIGGER update_users_modtime BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_modified_column(); |
| 86 | + |
| 87 | +DROP TRIGGER IF EXISTS update_orgs_modtime ON organizations; |
| 88 | +CREATE TRIGGER update_orgs_modtime BEFORE UPDATE ON organizations FOR EACH ROW EXECUTE FUNCTION update_modified_column(); |
| 89 | + |
| 90 | +DROP TRIGGER IF EXISTS update_events_modtime ON events; |
| 91 | +CREATE TRIGGER update_events_modtime BEFORE UPDATE ON events FOR EACH ROW EXECUTE FUNCTION update_modified_column(); |
0 commit comments