this push will conclude the majority of pulls. this repos will now, not be actively be managed or any further code pushes will not be frequent.
140 lines
4.6 KiB
PL/PgSQL
140 lines
4.6 KiB
PL/PgSQL
|
|
|
|
CREATE TABLE role (
|
|
role_id SERIAL PRIMARY KEY,
|
|
name VARCHAR(50) UNIQUE NOT NULL, -- admin, volunteer, team_lead, manager, terry
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- COMBINED: users + admin_settings in one table
|
|
CREATE TABLE users (
|
|
user_id SERIAL PRIMARY KEY,
|
|
first_name VARCHAR(100),
|
|
last_name VARCHAR(100),
|
|
email VARCHAR(150) UNIQUE NOT NULL,
|
|
phone VARCHAR(20) UNIQUE NOT NULL,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE address_database (
|
|
address_id SERIAL PRIMARY KEY,
|
|
address VARCHAR(255),
|
|
street_name VARCHAR(100),
|
|
street_type VARCHAR(50),
|
|
street_quadrant VARCHAR(50),
|
|
house_number VARCHAR(20),
|
|
house_alpha VARCHAR(10),
|
|
postal_code VARCHAR(10),
|
|
longitude DECIMAL(9,6),
|
|
latitude DECIMAL(9,6),
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE team (
|
|
team_id SERIAL PRIMARY KEY,
|
|
team_lead_id INT REFERENCES users(user_id) ON DELETE SET NULL,
|
|
volunteer_id INT REFERENCES users(user_id) ON DELETE SET NULL,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE admin_volunteers (
|
|
admin_id INT REFERENCES users(user_id) ON DELETE CASCADE,
|
|
volunteer_id INT REFERENCES users(user_id) ON DELETE CASCADE,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
PRIMARY KEY (admin_id, volunteer_id)
|
|
);
|
|
|
|
CREATE TABLE appointment (
|
|
sched_id SERIAL PRIMARY KEY,
|
|
user_id INT REFERENCES users(user_id) ON DELETE CASCADE,
|
|
address_id INT REFERENCES address_database(address_id) ON DELETE CASCADE,
|
|
appointment_date DATE,
|
|
appointment_time TIME,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE poll(
|
|
poll_id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users ON DELETE CASCADE,
|
|
address_id INTEGER REFERENCES address_database ON DELETE CASCADE,
|
|
donation_amount integer default 0,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE poll_response
|
|
(
|
|
poll_response_id SERIAL PRIMARY KEY,
|
|
poll_id INTEGER REFERENCES poll(poll_id) ON DELETE CASCADE,
|
|
respondent_postal_code VARCHAR(10), -- Postal code of respondent
|
|
question1_voted_before BOOLEAN, -- Have you voted before?
|
|
question2_vote_again BOOLEAN, -- Will you vote again for this candidate?
|
|
question3_lawn_signs INTEGER DEFAULT 0, -- How many lawn signs needed
|
|
question4_banner_signs INTEGER DEFAULT 0, -- How many banner signs needed
|
|
question5_thoughts TEXT, -- Write your thoughts
|
|
signage_status VARCHAR(50) DEFAULT 'requested' CHECK (signage_status IN ('requested', 'delivered', 'cancelled')),
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE post (
|
|
post_id SERIAL PRIMARY KEY,
|
|
author_id INT REFERENCES users(user_id) ON DELETE CASCADE,
|
|
content TEXT,
|
|
image_url TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE availability (
|
|
sched_id SERIAL PRIMARY KEY,
|
|
user_id INT REFERENCES users(user_id) ON DELETE CASCADE,
|
|
day_of_week VARCHAR(20),
|
|
start_time TIME,
|
|
end_time TIME,
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes for better performance
|
|
CREATE INDEX idx_poll_response_poll_id ON poll_response(poll_id);
|
|
CREATE INDEX idx_poll_response_postal_code ON poll_response(respondent_postal_code);
|
|
CREATE INDEX idx_poll_response_signage_status ON poll_response(signage_status);
|
|
CREATE INDEX idx_poll_user_id ON poll(user_id);
|
|
|
|
-- Function to generate a 6-character random admin code
|
|
CREATE OR REPLACE FUNCTION generate_admin_code()
|
|
RETURNS trigger AS $$
|
|
BEGIN
|
|
IF (SELECT name FROM role WHERE role_id = NEW.role_id) = 'admin' THEN
|
|
NEW.admin_code := substring(md5(random()::text) FROM 1 FOR 6);
|
|
ELSE
|
|
NEW.admin_code := NULL;
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Trigger to automatically generate admin_code on INSERT
|
|
CREATE TRIGGER set_admin_code
|
|
BEFORE INSERT ON users
|
|
FOR EACH ROW
|
|
EXECUTE PROCEDURE generate_admin_code();
|
|
|
|
|
|
INSERT INTO role (role_id, name) VALUES
|
|
(1, 'admin'),
|
|
(2, 'team_lead'),
|
|
(3, 'volunteer')
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
ALTER TABLE availability
|
|
ADD CONSTRAINT availability_user_day_unique UNIQUE (user_id, day_of_week);
|