nxtgauge-backend-rust/crates/db/migrations_new/001_minimal_setup.up.sql

726 lines
27 KiB
PL/PgSQL

-- Minimal setup migration - creates essential tables needed by complete migration
BEGIN;
-- Users table
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(50),
password_hash TEXT,
full_name VARCHAR(255),
account_type VARCHAR(50) DEFAULT 'USER',
email_verified BOOLEAN DEFAULT false,
phone_verified BOOLEAN DEFAULT false,
status VARCHAR(50) DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_login_at TIMESTAMPTZ,
deleted_at TIMESTAMPTZ
);
-- Roles table
CREATE TABLE IF NOT EXISTS roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL UNIQUE,
code VARCHAR(50) NOT NULL UNIQUE,
description TEXT,
can_approve_requests BOOLEAN DEFAULT false,
can_manage_system_settings BOOLEAN DEFAULT false,
audience VARCHAR(50) DEFAULT 'USER',
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- User roles table
CREATE TABLE IF NOT EXISTS user_roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
status VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Role permissions table
CREATE TABLE IF NOT EXISTS role_permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
permission VARCHAR(100) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Departments table
CREATE TABLE IF NOT EXISTS departments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
code VARCHAR(50),
description TEXT,
department_head UUID REFERENCES users(id),
department_email VARCHAR(255),
visibility VARCHAR(50) DEFAULT 'VISIBLE',
transfers_enabled BOOLEAN DEFAULT false,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Designations table
CREATE TABLE IF NOT EXISTS designations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title VARCHAR(255) NOT NULL,
code VARCHAR(50),
department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
description TEXT,
level INTEGER DEFAULT 1,
can_manage_team BOOLEAN DEFAULT false,
can_approve BOOLEAN DEFAULT false,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Employees table
CREATE TABLE IF NOT EXISTS employees (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE UNIQUE,
department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
designation_id UUID REFERENCES designations(id) ON DELETE SET NULL,
status VARCHAR(50) DEFAULT 'ACTIVE',
joining_date DATE,
employment_status VARCHAR(50),
manager_employee_id UUID REFERENCES employees(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Refresh tokens table
CREATE TABLE IF NOT EXISTS refresh_tokens (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL UNIQUE,
expires_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Notification preferences table
CREATE TABLE IF NOT EXISTS notification_preferences (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE UNIQUE,
email_enabled BOOLEAN DEFAULT true,
push_enabled BOOLEAN DEFAULT true,
sms_enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Profile extension tables (with user_role_profile_id for new schema)
CREATE TABLE IF NOT EXISTS photographer_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
equipment_list TEXT,
years_of_experience INTEGER,
hourly_rate INTEGER,
specialties TEXT[] DEFAULT '{}',
camera_brands TEXT[] DEFAULT '{}',
studio_available BOOLEAN DEFAULT false,
outdoor_shoots BOOLEAN DEFAULT true,
travel_radius_km INTEGER DEFAULT 50,
starting_price_inr INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS tutor_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
subjects TEXT[] DEFAULT '{}',
board_types TEXT[] DEFAULT '{}',
qualification VARCHAR(255),
teaches_online BOOLEAN DEFAULT true,
teaches_offline BOOLEAN DEFAULT true,
experience_years INTEGER DEFAULT 0,
hourly_rate_inr INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS makeup_artist_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
specialties TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
willing_to_travel BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS developer_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
skills TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
preferred_roles TEXT[] DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS video_editor_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
software_expertise TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
portfolio_url TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS graphic_designer_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
design_specialties TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS social_media_manager_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
platforms_managed TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS fitness_trainer_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
certifications TEXT[] DEFAULT '{}',
specializations TEXT[] DEFAULT '{}',
experience_years INTEGER DEFAULT 0,
hourly_rate INTEGER DEFAULT 0,
offers_online_sessions BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS catering_service_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
cuisine_types TEXT[] DEFAULT '{}',
min_order_amount INTEGER DEFAULT 0,
experience_years INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS ugc_content_creator_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID,
platforms TEXT[] DEFAULT '{}',
follower_count INTEGER DEFAULT 0,
niche TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Company profiles
CREATE TABLE IF NOT EXISTS company_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
company_name VARCHAR(255) NOT NULL,
registration_number VARCHAR(100),
industry VARCHAR(150),
website_url VARCHAR(255),
employee_count INTEGER,
business_type VARCHAR(100),
gst_number VARCHAR(50),
contact_name VARCHAR(255),
contact_email VARCHAR(255),
contact_phone VARCHAR(50),
address_line1 TEXT,
city VARCHAR(100),
state VARCHAR(100),
country VARCHAR(100) DEFAULT 'India',
postal_code VARCHAR(20),
status VARCHAR(50) DEFAULT 'ACTIVE',
free_job_slots INTEGER DEFAULT 3,
purchased_job_slots INTEGER DEFAULT 0,
free_contact_views INTEGER DEFAULT 10,
purchased_contact_views INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id)
);
-- Customer profiles
CREATE TABLE IF NOT EXISTS customer_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
full_name VARCHAR(255),
phone VARCHAR(50),
city VARCHAR(100),
area VARCHAR(100),
preferred_professions TEXT[] DEFAULT '{}',
active_requirement_count INTEGER DEFAULT 0,
status VARCHAR(50) DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id)
);
-- Job seeker profiles
CREATE TABLE IF NOT EXISTS job_seeker_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
full_name VARCHAR(255),
location VARCHAR(255),
summary TEXT,
experience_years INTEGER DEFAULT 0,
skills TEXT[] DEFAULT '{}',
resume_url TEXT,
active_application_count INTEGER DEFAULT 0,
status VARCHAR(50) DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id)
);
-- Jobs table
CREATE TABLE IF NOT EXISTS jobs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID REFERENCES company_profiles(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
requirements TEXT,
location VARCHAR(255),
job_type VARCHAR(50),
experience_min INTEGER DEFAULT 0,
experience_max INTEGER DEFAULT 0,
salary_min INTEGER,
salary_max INTEGER,
status VARCHAR(50) DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Job applications table
CREATE TABLE IF NOT EXISTS job_applications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
job_id UUID NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
applicant_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
cover_letter TEXT,
resume_url TEXT,
status VARCHAR(50) DEFAULT 'PENDING',
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Create user_role_profiles first (needed by leads table)
CREATE TABLE IF NOT EXISTS user_role_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role_key VARCHAR(50) NOT NULL,
display_name TEXT,
bio TEXT,
location TEXT,
avatar_url TEXT,
phone TEXT,
email TEXT,
status VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
verification_status VARCHAR(50) DEFAULT 'PENDING',
approval_status VARCHAR(50) DEFAULT 'PENDING',
rejection_reason TEXT,
approved_at TIMESTAMPTZ,
verified_at TIMESTAMPTZ,
is_profile_public BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id, role_key)
);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_user_id ON user_role_profiles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_role_key ON user_role_profiles(role_key);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_status ON user_role_profiles(status);
-- Leads table (renamed from requirements)
CREATE TABLE IF NOT EXISTS leads (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID REFERENCES user_role_profiles(id),
customer_id UUID REFERENCES users(id),
profession_key VARCHAR(50),
title VARCHAR(255) NOT NULL,
description TEXT,
location VARCHAR(255),
budget_min INTEGER,
budget_max INTEGER,
urgency VARCHAR(50) DEFAULT 'NORMAL',
status VARCHAR(50) DEFAULT 'OPEN',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Other essential tables
CREATE TABLE IF NOT EXISTS notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
notification_type VARCHAR(50),
reference_id UUID,
is_read BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID NOT NULL REFERENCES user_role_profiles(id),
reviewer_user_id UUID NOT NULL REFERENCES users(id),
rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
status VARCHAR(50) DEFAULT 'VISIBLE',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS tracecoin_wallets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE UNIQUE,
balance BIGINT DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS tracecoin_ledger (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wallet_id UUID NOT NULL REFERENCES tracecoin_wallets(id),
transaction_type VARCHAR(50) NOT NULL,
amount BIGINT NOT NULL,
balance_after BIGINT NOT NULL,
reference_type VARCHAR(50),
reference_id UUID,
description TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS services (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID REFERENCES user_role_profiles(id),
service_name VARCHAR(255) NOT NULL,
description TEXT,
price INTEGER,
price_type VARCHAR(50) DEFAULT 'FIXED',
duration_minutes INTEGER,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS pricing_packages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID REFERENCES user_role_profiles(id),
name VARCHAR(255) NOT NULL,
description TEXT,
price INTEGER NOT NULL,
duration_days INTEGER,
features JSONB,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS coupons (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(50) NOT NULL UNIQUE,
discount_type VARCHAR(20) NOT NULL,
discount_value INTEGER NOT NULL,
min_order_amount INTEGER DEFAULT 0,
max_uses INTEGER,
used_count INTEGER DEFAULT 0,
valid_from TIMESTAMPTZ,
valid_until TIMESTAMPTZ,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS coupon_redemptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
coupon_id UUID NOT NULL REFERENCES coupons(id),
user_id UUID NOT NULL REFERENCES users(id),
redeemed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS discounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
package_id UUID NOT NULL REFERENCES pricing_packages(id),
discount_type VARCHAR(20) NOT NULL,
discount_value INTEGER NOT NULL,
valid_from TIMESTAMPTZ,
valid_until TIMESTAMPTZ,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS payments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
amount INTEGER NOT NULL,
currency VARCHAR(10) DEFAULT 'INR',
payment_method VARCHAR(50),
payment_status VARCHAR(50) DEFAULT 'PENDING',
reference_id VARCHAR(255),
transaction_id VARCHAR(255),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS invoices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
invoice_number VARCHAR(50) NOT NULL UNIQUE,
amount INTEGER NOT NULL,
status VARCHAR(50) DEFAULT 'DRAFT',
issued_at TIMESTAMPTZ,
due_at TIMESTAMPTZ,
paid_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS portfolio_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID REFERENCES user_role_profiles(id),
title VARCHAR(255) NOT NULL,
description TEXT,
media_url TEXT,
media_type VARCHAR(50),
display_order INTEGER DEFAULT 0,
is_featured BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS verification_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID REFERENCES user_role_profiles(id),
verification_type VARCHAR(50) NOT NULL DEFAULT 'IDENTITY',
status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
submitted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
reviewed_at TIMESTAMPTZ,
reviewed_by_user_id UUID REFERENCES users(id),
remarks TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS verification_documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
verification_request_id UUID NOT NULL REFERENCES verification_requests(id) ON DELETE CASCADE,
document_type VARCHAR(100) NOT NULL,
file_url TEXT NOT NULL,
file_name TEXT,
mime_type TEXT,
status VARCHAR(50) DEFAULT 'PENDING',
uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
reviewed_at TIMESTAMPTZ,
reviewed_by_user_id UUID REFERENCES users(id),
remarks TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS verification_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
verification_request_id UUID NOT NULL REFERENCES verification_requests(id),
action VARCHAR(50) NOT NULL,
old_status VARCHAR(50),
new_status VARCHAR(50),
acted_by_user_id UUID REFERENCES users(id),
remarks TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS verifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_role_profile_id UUID NOT NULL REFERENCES user_role_profiles(id),
verification_type VARCHAR(50) NOT NULL,
document_url TEXT,
status VARCHAR(50) DEFAULT 'PENDING',
verified_at TIMESTAMPTZ,
verified_by UUID REFERENCES users(id),
rejection_reason TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS user_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE UNIQUE,
theme VARCHAR(20) DEFAULT 'LIGHT',
language VARCHAR(10) DEFAULT 'en',
timezone VARCHAR(50) DEFAULT 'Asia/Kolkata',
email_notifications BOOLEAN DEFAULT true,
push_notifications BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS account_deletion_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
reason TEXT,
scheduled_deletion_at TIMESTAMPTZ,
status VARCHAR(50) DEFAULT 'PENDING',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS activity_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
action VARCHAR(100) NOT NULL,
entity_type VARCHAR(50),
entity_id UUID,
metadata JSONB,
ip_address TEXT,
user_agent TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS email_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
email_type VARCHAR(50) NOT NULL,
recipient_email VARCHAR(255) NOT NULL,
subject VARCHAR(255),
status VARCHAR(50) DEFAULT 'SENT',
error_message TEXT,
sent_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- KB tables
CREATE TABLE IF NOT EXISTS kb_categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
description TEXT,
display_order INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS kb_articles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
category_id UUID REFERENCES kb_categories(id) ON DELETE SET NULL,
title VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
content TEXT,
summary TEXT,
tags TEXT[],
views_count INTEGER DEFAULT 0,
is_published BOOLEAN DEFAULT false,
is_featured BOOLEAN DEFAULT false,
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Support tables
CREATE TABLE IF NOT EXISTS support_tickets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
subject VARCHAR(255) NOT NULL,
description TEXT,
priority VARCHAR(20) DEFAULT 'MEDIUM',
status VARCHAR(50) DEFAULT 'OPEN',
assigned_to UUID REFERENCES users(id),
resolved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS support_ticket_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
ticket_id UUID NOT NULL REFERENCES support_tickets(id) ON DELETE CASCADE,
sender_id UUID NOT NULL REFERENCES users(id),
message TEXT NOT NULL,
is_internal BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Config tables
CREATE TABLE IF NOT EXISTS runtime_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
config_key VARCHAR(100) NOT NULL UNIQUE,
config_value JSONB NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS onboarding_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
role_key VARCHAR(50) NOT NULL,
steps JSONB NOT NULL,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS dashboard_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
role_key VARCHAR(50) NOT NULL,
audience VARCHAR(50) DEFAULT 'USER',
widgets JSONB NOT NULL,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Create indexes
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_status ON user_roles(status);
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
CREATE INDEX IF NOT EXISTS idx_notifications_is_read ON notifications(is_read);
CREATE INDEX IF NOT EXISTS idx_reviews_user_role_profile_id ON reviews(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_services_user_role_profile_id ON services(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_pricing_packages_user_role_profile_id ON pricing_packages(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_portfolio_items_user_role_profile_id ON portfolio_items(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
CREATE INDEX IF NOT EXISTS idx_jobs_company_id ON jobs(company_id);
CREATE INDEX IF NOT EXISTS idx_job_applications_job_id ON job_applications(job_id);
CREATE INDEX IF NOT EXISTS idx_job_applications_applicant ON job_applications(applicant_user_id);
CREATE INDEX IF NOT EXISTS idx_leads_status ON leads(status);
CREATE INDEX IF NOT EXISTS idx_leads_user_role_profile_id ON leads(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_tracecoin_ledger_wallet_id ON tracecoin_ledger(wallet_id);
CREATE INDEX IF NOT EXISTS idx_coupons_code ON coupons(code);
CREATE INDEX IF NOT EXISTS idx_support_tickets_user_id ON support_tickets(user_id);
CREATE INDEX IF NOT EXISTS idx_support_tickets_status ON support_tickets(status);
CREATE INDEX IF NOT EXISTS idx_activity_logs_user_id ON activity_logs(user_id);
CREATE INDEX IF NOT EXISTS idx_activity_logs_created_at ON activity_logs(created_at);
CREATE INDEX IF NOT EXISTS idx_email_logs_user_id ON email_logs(user_id);
CREATE INDEX IF NOT EXISTS idx_email_logs_sent_at ON email_logs(sent_at);
CREATE INDEX IF NOT EXISTS idx_kb_articles_category_id ON kb_articles(category_id);
CREATE INDEX IF NOT EXISTS idx_kb_articles_slug ON kb_articles(slug);
CREATE INDEX IF NOT EXISTS idx_verification_requests_user_role_profile_id ON verification_requests(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_verifications_user_role_profile_id ON verifications(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_user_settings_user_id ON user_settings(user_id);
-- Insert default roles
INSERT INTO roles (id, name, code, description, audience, is_active) VALUES
('00000000-0000-0000-0000-000000000001', 'Super Admin', 'SUPER_ADMIN', 'Full system access', 'ADMIN', true),
('00000000-0000-0000-0000-000000000002', 'Admin', 'ADMIN', 'Administrative access', 'ADMIN', true),
('00000000-0000-0000-0000-000000000003', 'User', 'USER', 'Regular user', 'USER', true),
('00000000-0000-0000-0000-000000000004', 'Company', 'COMPANY', 'Company account', 'BUSINESS', true),
('00000000-0000-0000-0000-000000000005', 'Customer', 'CUSTOMER', 'Customer account', 'USER', true)
ON CONFLICT (code) DO NOTHING;
COMMIT;