CSV Import is now working

This commit is contained in:
Mann Patel
2025-09-03 14:35:47 -06:00
parent 7f2b7e481a
commit 86d733e80e
20 changed files with 2160 additions and 1626 deletions

141
app/database/schema.sql Normal file
View File

@@ -0,0 +1,141 @@
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),
password TEXT NOT NULL,
role_id INT REFERENCES role(role_id) ON DELETE SET NULL,
admin_code CHAR(6) UNIQUE,
-- Admin settings combined here
ward_settings TEXT,
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 (
availability_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;