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