37748-vm/db/migrations/20260123_init.sql
2026-01-23 13:44:03 +00:00

148 lines
6.3 KiB
SQL

-- Initial Schema for Repairs Multi-tenant App
CREATE TABLE IF NOT EXISTS companies (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
uprn_required BOOLEAN DEFAULT FALSE,
onboarding_complete BOOLEAN DEFAULT FALSE, -- Added for onboarding wizard
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
role ENUM('admin', 'standard') DEFAULT 'standard',
FOREIGN KEY (company_id) REFERENCES companies(id)
);
CREATE TABLE IF NOT EXISTS clients (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (company_id) REFERENCES companies(id)
);
CREATE TABLE IF NOT EXISTS job_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
is_default BOOLEAN DEFAULT FALSE,
FOREIGN KEY (company_id) REFERENCES companies(id)
);
CREATE TABLE IF NOT EXISTS job_folders (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
is_required BOOLEAN DEFAULT FALSE,
FOREIGN KEY (company_id) REFERENCES companies(id)
);
CREATE TABLE IF NOT EXISTS jobs (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id INT NOT NULL,
job_ref VARCHAR(100) NOT NULL,
uprn VARCHAR(100),
address_1 VARCHAR(255),
address_2 VARCHAR(255),
address_3 VARCHAR(255),
postcode VARCHAR(20),
description TEXT,
status_id INT,
client_id INT,
works_approved BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(company_id, job_ref),
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (status_id) REFERENCES job_statuses(id),
FOREIGN KEY (client_id) REFERENCES clients(id)
);
CREATE TABLE IF NOT EXISTS job_job_folders (
id INT AUTO_INCREMENT PRIMARY KEY,
job_id INT NOT NULL,
company_id INT NOT NULL,
folder_id INT NOT NULL, -- Refers to job_folders.id, for required folders
name VARCHAR(255) NOT NULL, -- For custom folders or required folder name copy
is_custom BOOLEAN DEFAULT FALSE, -- TRUE for user-added folders, FALSE for required folders
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (job_id) REFERENCES jobs(id),
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (folder_id) REFERENCES job_folders(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS job_files (
id INT AUTO_INCREMENT PRIMARY KEY,
job_id INT NOT NULL,
job_job_folder_id INT NOT NULL, -- Refers to job_job_folders.id
company_id INT NOT NULL,
user_id INT NOT NULL,
filename VARCHAR(255) NOT NULL,
filepath VARCHAR(512) NOT NULL,
mimetype VARCHAR(100),
size INT, -- size in bytes
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (job_id) REFERENCES jobs(id),
FOREIGN KEY (job_job_folder_id) REFERENCES job_job_folders(id) ON DELETE CASCADE,
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS activity_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
job_id INT NOT NULL,
company_id INT NOT NULL,
user_id INT NOT NULL,
user_name VARCHAR(255),
event_type VARCHAR(100),
field_name VARCHAR(100),
old_value TEXT,
new_value TEXT,
metadata JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (job_id) REFERENCES jobs(id),
FOREIGN KEY (company_id) REFERENCES companies(id)
);
-- Add onboarding_complete column to companies table if it doesn't exist
-- This needs to be a separate ALTER TABLE statement after the CREATE TABLE IF NOT EXISTS for companies
-- Because adding a column with DEFAULT value within CREATE TABLE IF NOT EXISTS doesn't work as expected if the table already exists
-- No longer needed if added directly to CREATE TABLE
-- INSERT IGNORE needs to be used with a subquery if we want to update existing rows only
-- Seed Initial Demo Company
INSERT IGNORE INTO companies (name, onboarding_complete) VALUES ('Repairs Pro Ltd', TRUE);
SET @company_id = (SELECT id FROM companies WHERE name = 'Repairs Pro Ltd' LIMIT 1);
-- Users (will only insert if not exists)
INSERT IGNORE INTO users (company_id, name, email, role) VALUES (@company_id, 'Admin User', 'admin@repairspro.com', 'admin');
-- Job Statuses (will only insert if not exists for the company and name)
INSERT IGNORE INTO job_statuses (company_id, name, is_default) VALUES (@company_id, 'To Be Surveyed', TRUE);
INSERT IGNORE INTO job_statuses (company_id, name, is_default) VALUES (@company_id, 'Booking Required', FALSE);
INSERT IGNORE INTO job_statuses (company_id, name, is_default) VALUES (@company_id, 'Completed', FALSE);
-- Clients (will only insert if not exists for the company and name)
INSERT IGNORE INTO clients (company_id, name) VALUES (@company_id, 'Main Housing Assoc');
-- Job Folders (will only insert if not exists for the company and name)
INSERT IGNORE INTO job_folders (company_id, name, is_required) VALUES (@company_id, 'PO', TRUE);
INSERT IGNORE INTO job_folders (company_id, name, is_required) VALUES (@company_id, 'Quote', TRUE);
INSERT IGNORE INTO job_folders (company_id, name, is_required) VALUES (@company_id, 'Photos', TRUE);
INSERT IGNORE INTO job_folders (company_id, name, is_required) VALUES (@company_id, 'RAMS', TRUE);
INSERT IGNORE INTO job_folders (company_id, name, is_required) VALUES (@company_id, 'Invoices', TRUE);
-- Example: For an existing job, ensure required folders are present in job_job_folders
-- This logic would be handled when a job is created or when required folders are updated globally.
-- For seeding purposes, let's assume job_id 1 already exists and we want to link its required folders.
-- This part should ideally be in a migration script that runs after job creation.
-- For now, commenting out to avoid issues with non-existent job IDs.
-- INSERT IGNORE INTO job_job_folders (job_id, company_id, folder_id, name, is_custom)
-- SELECT j.id, j.company_id, jf.id, jf.name, FALSE
-- FROM jobs j
-- JOIN job_folders jf ON j.company_id = jf.company_id
-- WHERE j.id = (SELECT id FROM jobs LIMIT 1) AND jf.is_required = TRUE; -- Link to the first job created for the demo company