the beginning of the idiots
This commit is contained in:
161
qwen/go/init.sql
Normal file
161
qwen/go/init.sql
Normal file
@@ -0,0 +1,161 @@
|
||||
-- Create the database schema for MerchantsOfHope.org recruiting platform
|
||||
-- This includes multi-tenant architecture, user management, job positions, applications, etc.
|
||||
|
||||
-- Create extension for UUID generation if not exists
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- Tenants table - for multi-tenant architecture
|
||||
CREATE TABLE tenants (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(255) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
logo_url VARCHAR(500),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
|
||||
-- Users table
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
username VARCHAR(255) UNIQUE,
|
||||
first_name VARCHAR(100),
|
||||
last_name VARCHAR(100),
|
||||
phone VARCHAR(20),
|
||||
role VARCHAR(50) DEFAULT 'job_seeker', -- job_seeker, job_provider, admin
|
||||
password_hash VARCHAR(255), -- For local auth (not OIDC)
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
email_verified BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP WITH TIME ZONE,
|
||||
CONSTRAINT valid_role CHECK (role IN ('job_seeker', 'job_provider', 'admin'))
|
||||
);
|
||||
|
||||
-- OIDC identities table for external authentication
|
||||
CREATE TABLE oidc_identities (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
provider_name VARCHAR(100) NOT NULL,
|
||||
provider_subject VARCHAR(255) NOT NULL,
|
||||
provider_data JSONB, -- Store provider-specific user data
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, provider_name),
|
||||
UNIQUE(provider_name, provider_subject)
|
||||
);
|
||||
|
||||
-- Social media identities table
|
||||
CREATE TABLE social_identities (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
provider_name VARCHAR(100) NOT NULL,
|
||||
provider_user_id VARCHAR(255) NOT NULL,
|
||||
access_token TEXT,
|
||||
refresh_token TEXT,
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
profile_data JSONB, -- Store provider-specific profile data
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, provider_name),
|
||||
UNIQUE(provider_name, provider_user_id)
|
||||
);
|
||||
|
||||
-- Job positions table
|
||||
CREATE TABLE job_positions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL, -- Creator of the position
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
requirements TEXT,
|
||||
location VARCHAR(255),
|
||||
employment_type VARCHAR(50) DEFAULT 'full_time', -- full_time, part_time, contract, internship
|
||||
salary_min DECIMAL(10,2),
|
||||
salary_max DECIMAL(10,2),
|
||||
experience_level VARCHAR(50) DEFAULT 'mid_level', -- entry_level, mid_level, senior_level, executive
|
||||
posted_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
closed_at TIMESTAMP WITH TIME ZONE,
|
||||
status VARCHAR(50) DEFAULT 'open', -- open, closed, filled
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
CONSTRAINT valid_employment_type CHECK (employment_type IN ('full_time', 'part_time', 'contract', 'internship')),
|
||||
CONSTRAINT valid_experience_level CHECK (experience_level IN ('entry_level', 'mid_level', 'senior_level', 'executive')),
|
||||
CONSTRAINT valid_status CHECK (status IN ('open', 'closed', 'filled'))
|
||||
);
|
||||
|
||||
-- Resumes table
|
||||
CREATE TABLE resumes (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(500) NOT NULL, -- Path to stored resume file
|
||||
file_type VARCHAR(100), -- MIME type
|
||||
file_size INTEGER, -- Size in bytes
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Applications table
|
||||
CREATE TABLE applications (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
position_id UUID REFERENCES job_positions(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
resume_id UUID REFERENCES resumes(id) ON DELETE SET NULL,
|
||||
cover_letter TEXT,
|
||||
status VARCHAR(50) DEFAULT 'pending', -- pending, reviewed, accepted, rejected
|
||||
applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
reviewed_at TIMESTAMP WITH TIME ZONE,
|
||||
reviewer_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(position_id, user_id), -- Prevent duplicate applications
|
||||
CONSTRAINT valid_status CHECK (status IN ('pending', 'reviewed', 'accepted', 'rejected'))
|
||||
);
|
||||
|
||||
-- Indexes for better performance
|
||||
CREATE INDEX idx_users_tenant_id ON users(tenant_id);
|
||||
CREATE INDEX idx_users_email ON users(email);
|
||||
CREATE INDEX idx_job_positions_tenant_id ON job_positions(tenant_id);
|
||||
CREATE INDEX idx_job_positions_user_id ON job_positions(user_id);
|
||||
CREATE INDEX idx_job_positions_status ON job_positions(status);
|
||||
CREATE INDEX idx_applications_position_id ON applications(position_id);
|
||||
CREATE INDEX idx_applications_user_id ON applications(user_id);
|
||||
CREATE INDEX idx_applications_status ON applications(status);
|
||||
CREATE INDEX idx_resumes_user_id ON resumes(user_id);
|
||||
|
||||
-- Function to update the updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Triggers to automatically update the updated_at timestamp
|
||||
CREATE TRIGGER update_tenants_updated_at BEFORE UPDATE ON tenants FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_job_positions_updated_at BEFORE UPDATE ON job_positions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_resumes_updated_at BEFORE UPDATE ON resumes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_applications_updated_at BEFORE UPDATE ON applications FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Insert default tenant for MerchantsOfHope
|
||||
INSERT INTO tenants (name, slug, description)
|
||||
VALUES ('MerchantsOfHope', 'merchants-of-hope', 'Default tenant for MerchantsOfHope.org platform');
|
||||
|
||||
-- Insert admin user for the default tenant
|
||||
INSERT INTO users (tenant_id, email, username, first_name, last_name, role, is_active)
|
||||
VALUES (
|
||||
(SELECT id FROM tenants WHERE slug = 'merchants-of-hope'),
|
||||
'admin@merchants-of-hope.org',
|
||||
'admin',
|
||||
'System',
|
||||
'Administrator',
|
||||
'admin',
|
||||
true
|
||||
);
|
||||
Reference in New Issue
Block a user