-- 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