From 7462d7c50950e37378b37fe60fbb449327c0cb1a Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 20 Jan 2026 17:07:54 -0500 Subject: [PATCH] fix: Add error handling to dependencies + cleanup migrations - Add detailed error handling in DependencyModel (throw exceptions on failure) - Add try-catch in ticket_dependencies.php to catch query errors - Remove all old migrations (001-014) that have already been run - Keep only new feature migrations (015-018) for reference Co-Authored-By: Claude Opus 4.5 --- api/ticket_dependencies.php | 8 +- migrations/001_create_users_table.sql | 17 --- migrations/002_create_api_keys_table.sql | 15 --- migrations/003_create_audit_log_table.sql | 16 --- migrations/004_alter_tickets_table.sql | 30 ----- migrations/005_alter_comments_table.sql | 19 ---- migrations/006_add_indexes.sql | 39 ------- migrations/007_add_ticket_assignment.sql | 13 --- migrations/008_add_status_workflows.sql | 31 ----- migrations/009_add_ticket_templates.sql | 24 ---- migrations/009_simplify_status_workflow.sql | 43 ------- migrations/010_add_bulk_operations.sql | 19 ---- migrations/010_expand_status_column.sql | 18 --- migrations/011_create_user_preferences.sql | 48 -------- migrations/011_remove_view_tracking.sql | 2 - migrations/012_create_saved_filters.sql | 15 --- migrations/013_add_performance_indexes.sql | 11 -- migrations/013_rollback.sql | 4 - migrations/014_add_additional_indexes.sql | 23 ---- migrations/MIGRATION_009_INSTRUCTIONS.md | 118 -------------------- migrations/rollback_all.sql | 25 ----- models/DependencyModel.php | 14 ++- 22 files changed, 18 insertions(+), 534 deletions(-) delete mode 100644 migrations/001_create_users_table.sql delete mode 100644 migrations/002_create_api_keys_table.sql delete mode 100644 migrations/003_create_audit_log_table.sql delete mode 100644 migrations/004_alter_tickets_table.sql delete mode 100644 migrations/005_alter_comments_table.sql delete mode 100644 migrations/006_add_indexes.sql delete mode 100644 migrations/007_add_ticket_assignment.sql delete mode 100644 migrations/008_add_status_workflows.sql delete mode 100644 migrations/009_add_ticket_templates.sql delete mode 100644 migrations/009_simplify_status_workflow.sql delete mode 100644 migrations/010_add_bulk_operations.sql delete mode 100644 migrations/010_expand_status_column.sql delete mode 100644 migrations/011_create_user_preferences.sql delete mode 100644 migrations/011_remove_view_tracking.sql delete mode 100644 migrations/012_create_saved_filters.sql delete mode 100644 migrations/013_add_performance_indexes.sql delete mode 100644 migrations/013_rollback.sql delete mode 100644 migrations/014_add_additional_indexes.sql delete mode 100644 migrations/MIGRATION_009_INSTRUCTIONS.md delete mode 100644 migrations/rollback_all.sql diff --git a/api/ticket_dependencies.php b/api/ticket_dependencies.php index 5242760..64b88b2 100644 --- a/api/ticket_dependencies.php +++ b/api/ticket_dependencies.php @@ -74,8 +74,12 @@ switch ($method) { ResponseHelper::error('Ticket ID required'); } - $dependencies = $dependencyModel->getDependencies($ticketId); - $dependents = $dependencyModel->getDependentTickets($ticketId); + try { + $dependencies = $dependencyModel->getDependencies($ticketId); + $dependents = $dependencyModel->getDependentTickets($ticketId); + } catch (Exception $e) { + ResponseHelper::serverError('Query error: ' . $e->getMessage()); + } ResponseHelper::success([ 'dependencies' => $dependencies, diff --git a/migrations/001_create_users_table.sql b/migrations/001_create_users_table.sql deleted file mode 100644 index dbbda7d..0000000 --- a/migrations/001_create_users_table.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Create users table for SSO integration -CREATE TABLE IF NOT EXISTS users ( - user_id INT AUTO_INCREMENT PRIMARY KEY, - username VARCHAR(100) UNIQUE NOT NULL, - display_name VARCHAR(255), - email VARCHAR(255), - groups TEXT, - is_admin BOOLEAN DEFAULT FALSE, - last_login TIMESTAMP NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - INDEX idx_username (username) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- Insert system user for hwmonDaemon -INSERT INTO users (username, display_name, email, groups, is_admin, created_at) -VALUES ('system', 'System', 'system@lotusguild.org', '', FALSE, NOW()) -ON DUPLICATE KEY UPDATE username = username; diff --git a/migrations/002_create_api_keys_table.sql b/migrations/002_create_api_keys_table.sql deleted file mode 100644 index 935a4ea..0000000 --- a/migrations/002_create_api_keys_table.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Create API keys table for external service authentication -CREATE TABLE IF NOT EXISTS api_keys ( - api_key_id INT AUTO_INCREMENT PRIMARY KEY, - key_name VARCHAR(100) NOT NULL, - key_hash VARCHAR(255) UNIQUE NOT NULL, - key_prefix VARCHAR(20) NOT NULL, - is_active BOOLEAN DEFAULT TRUE, - created_by INT, - last_used TIMESTAMP NULL, - expires_at TIMESTAMP NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL, - INDEX idx_key_hash (key_hash), - INDEX idx_is_active (is_active) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/migrations/003_create_audit_log_table.sql b/migrations/003_create_audit_log_table.sql deleted file mode 100644 index a2e00dc..0000000 --- a/migrations/003_create_audit_log_table.sql +++ /dev/null @@ -1,16 +0,0 @@ --- Create audit log table for tracking all user actions -CREATE TABLE IF NOT EXISTS audit_log ( - audit_id BIGINT AUTO_INCREMENT PRIMARY KEY, - user_id INT, - action_type VARCHAR(50) NOT NULL, - entity_type VARCHAR(50) NOT NULL, - entity_id VARCHAR(50), - details JSON, - ip_address VARCHAR(45), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL, - INDEX idx_user_id (user_id), - INDEX idx_created_at (created_at), - INDEX idx_entity (entity_type, entity_id), - INDEX idx_action_type (action_type) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/migrations/004_alter_tickets_table.sql b/migrations/004_alter_tickets_table.sql deleted file mode 100644 index 6ac77fc..0000000 --- a/migrations/004_alter_tickets_table.sql +++ /dev/null @@ -1,30 +0,0 @@ --- Add user tracking columns to tickets table -ALTER TABLE tickets - ADD COLUMN IF NOT EXISTS created_by INT, - ADD COLUMN IF NOT EXISTS updated_by INT, - ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP NULL; - --- Add foreign key constraints if they don't exist -SET @fk_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE CONSTRAINT_NAME = 'fk_tickets_created_by' - AND TABLE_NAME = 'tickets' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@fk_exists = 0, - 'ALTER TABLE tickets ADD CONSTRAINT fk_tickets_created_by FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL', - 'SELECT "Foreign key fk_tickets_created_by already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - -SET @fk_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE CONSTRAINT_NAME = 'fk_tickets_updated_by' - AND TABLE_NAME = 'tickets' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@fk_exists = 0, - 'ALTER TABLE tickets ADD CONSTRAINT fk_tickets_updated_by FOREIGN KEY (updated_by) REFERENCES users(user_id) ON DELETE SET NULL', - 'SELECT "Foreign key fk_tickets_updated_by already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; diff --git a/migrations/005_alter_comments_table.sql b/migrations/005_alter_comments_table.sql deleted file mode 100644 index 12db599..0000000 --- a/migrations/005_alter_comments_table.sql +++ /dev/null @@ -1,19 +0,0 @@ --- Add user_id column to ticket_comments table -ALTER TABLE ticket_comments - ADD COLUMN IF NOT EXISTS user_id INT; - --- Add foreign key constraint if it doesn't exist -SET @fk_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE CONSTRAINT_NAME = 'fk_comments_user_id' - AND TABLE_NAME = 'ticket_comments' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@fk_exists = 0, - 'ALTER TABLE ticket_comments ADD CONSTRAINT fk_comments_user_id FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE SET NULL', - 'SELECT "Foreign key fk_comments_user_id already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- Update existing comments to reference jared user (first admin) --- This will be done after jared user is created via web login diff --git a/migrations/006_add_indexes.sql b/migrations/006_add_indexes.sql deleted file mode 100644 index 3040361..0000000 --- a/migrations/006_add_indexes.sql +++ /dev/null @@ -1,39 +0,0 @@ --- Add database indexes for performance optimization --- Check and create index on tickets.status -SET @index_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_NAME = 'tickets' - AND INDEX_NAME = 'idx_status' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX idx_status ON tickets(status)', - 'SELECT "Index idx_status already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- Check and create index on tickets.priority -SET @index_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_NAME = 'tickets' - AND INDEX_NAME = 'idx_priority' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX idx_priority ON tickets(priority)', - 'SELECT "Index idx_priority already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- Check and create index on tickets.created_at -SET @index_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_NAME = 'tickets' - AND INDEX_NAME = 'idx_tickets_created_at' - AND TABLE_SCHEMA = DATABASE()); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX idx_tickets_created_at ON tickets(created_at)', - 'SELECT "Index idx_tickets_created_at already exists"'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; diff --git a/migrations/007_add_ticket_assignment.sql b/migrations/007_add_ticket_assignment.sql deleted file mode 100644 index 7f7fa90..0000000 --- a/migrations/007_add_ticket_assignment.sql +++ /dev/null @@ -1,13 +0,0 @@ --- Migration 007: Add ticket assignment functionality --- Adds assigned_to column to tickets table - --- Add assigned_to column to tickets table -ALTER TABLE tickets - ADD COLUMN assigned_to INT NULL, - ADD CONSTRAINT fk_tickets_assigned_to - FOREIGN KEY (assigned_to) - REFERENCES users(user_id) - ON DELETE SET NULL; - --- Add index for performance -CREATE INDEX idx_assigned_to ON tickets(assigned_to); diff --git a/migrations/008_add_status_workflows.sql b/migrations/008_add_status_workflows.sql deleted file mode 100644 index 29524bb..0000000 --- a/migrations/008_add_status_workflows.sql +++ /dev/null @@ -1,31 +0,0 @@ --- Migration 008: Add status workflow management --- Creates status_transitions table for workflow validation - --- Table to define allowed status transitions -CREATE TABLE status_transitions ( - transition_id INT AUTO_INCREMENT PRIMARY KEY, - from_status VARCHAR(50) NOT NULL, - to_status VARCHAR(50) NOT NULL, - requires_comment BOOLEAN DEFAULT FALSE, - requires_admin BOOLEAN DEFAULT FALSE, - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE KEY unique_transition (from_status, to_status), - INDEX idx_from_status (from_status) -); - --- Insert default transitions -INSERT INTO status_transitions (from_status, to_status, requires_comment) VALUES - ('Open', 'In Progress', FALSE), - ('Open', 'Closed', TRUE), - ('In Progress', 'Open', FALSE), - ('In Progress', 'Closed', TRUE), - ('Closed', 'Open', TRUE), - ('Closed', 'In Progress', FALSE); - --- Add new status "Resolved" -INSERT INTO status_transitions (from_status, to_status, requires_comment) VALUES - ('In Progress', 'Resolved', FALSE), - ('Resolved', 'Closed', FALSE), - ('Resolved', 'In Progress', TRUE), - ('Open', 'Resolved', FALSE); diff --git a/migrations/009_add_ticket_templates.sql b/migrations/009_add_ticket_templates.sql deleted file mode 100644 index 100fa87..0000000 --- a/migrations/009_add_ticket_templates.sql +++ /dev/null @@ -1,24 +0,0 @@ --- Migration 009: Add ticket templates --- Creates ticket_templates table for reusable ticket templates - -CREATE TABLE ticket_templates ( - template_id INT AUTO_INCREMENT PRIMARY KEY, - template_name VARCHAR(100) NOT NULL, - title_template VARCHAR(255) NOT NULL, - description_template TEXT NOT NULL, - category VARCHAR(50), - type VARCHAR(50), - default_priority INT DEFAULT 4, - created_by INT, - is_active BOOLEAN DEFAULT TRUE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (created_by) REFERENCES users(user_id), - INDEX idx_template_name (template_name) -); - --- Insert default templates -INSERT INTO ticket_templates (template_name, title_template, description_template, category, type, default_priority) VALUES -('Hardware Failure', 'Hardware Failure: [Device Name]', 'Device: \nIssue: \nError Messages: \nTroubleshooting Done: ', 'Hardware', 'Problem', 2), -('Software Installation', 'Install [Software Name]', 'Software: \nVersion: \nLicense Key: \nInstallation Path: ', 'Software', 'Install', 3), -('Network Issue', 'Network Issue: [Brief Description]', 'Affected System: \nSymptoms: \nIP Address: \nConnectivity Tests: ', 'Hardware', 'Problem', 2), -('Maintenance Request', 'Scheduled Maintenance: [System Name]', 'System: \nMaintenance Type: \nScheduled Date: \nDowntime Expected: ', 'Hardware', 'Maintenance', 4); diff --git a/migrations/009_simplify_status_workflow.sql b/migrations/009_simplify_status_workflow.sql deleted file mode 100644 index 5929f63..0000000 --- a/migrations/009_simplify_status_workflow.sql +++ /dev/null @@ -1,43 +0,0 @@ --- Migration 009: Simplify status workflow --- Removes "Resolved" status and adds "Pending" status --- Keeps only: Open, Pending, In Progress, Closed - --- First, update any existing tickets with "Resolved" status to "Closed" -UPDATE tickets SET status = 'Closed' WHERE status = 'Resolved'; - --- Delete all existing transitions with "Resolved" -DELETE FROM status_transitions WHERE from_status = 'Resolved' OR to_status = 'Resolved'; - --- Clear all existing transitions to rebuild clean workflow -DELETE FROM status_transitions; - --- Define new simplified workflow with Pending status --- OPEN transitions -INSERT INTO status_transitions (from_status, to_status, requires_comment, requires_admin) VALUES - ('Open', 'Pending', FALSE, FALSE), -- Waiting on external dependency - ('Open', 'In Progress', FALSE, FALSE), -- Start work - ('Open', 'Closed', TRUE, FALSE); -- Close without work (duplicate, won't fix, etc.) - --- PENDING transitions -INSERT INTO status_transitions (from_status, to_status, requires_comment, requires_admin) VALUES - ('Pending', 'Open', FALSE, FALSE), -- Unblock and reopen - ('Pending', 'In Progress', FALSE, FALSE), -- Start work while pending - ('Pending', 'Closed', TRUE, FALSE); -- Close while pending - --- IN PROGRESS transitions -INSERT INTO status_transitions (from_status, to_status, requires_comment, requires_admin) VALUES - ('In Progress', 'Open', FALSE, FALSE), -- Stop work, back to queue - ('In Progress', 'Pending', FALSE, FALSE), -- Blocked by external dependency - ('In Progress', 'Closed', TRUE, FALSE); -- Complete and close - --- CLOSED transitions -INSERT INTO status_transitions (from_status, to_status, requires_comment, requires_admin) VALUES - ('Closed', 'Open', TRUE, FALSE), -- Reopen (requires explanation) - ('Closed', 'In Progress', FALSE, FALSE); -- Reopen and start work immediately - --- Verify new transitions -SELECT 'New Status Transitions:' as info; -SELECT from_status, to_status, requires_comment, requires_admin -FROM status_transitions -WHERE is_active = TRUE -ORDER BY from_status, to_status; diff --git a/migrations/010_add_bulk_operations.sql b/migrations/010_add_bulk_operations.sql deleted file mode 100644 index a307ea1..0000000 --- a/migrations/010_add_bulk_operations.sql +++ /dev/null @@ -1,19 +0,0 @@ --- Migration 010: Add bulk operations tracking --- Creates bulk_operations table for admin bulk actions - -CREATE TABLE bulk_operations ( - operation_id INT AUTO_INCREMENT PRIMARY KEY, - operation_type VARCHAR(50) NOT NULL, - ticket_ids TEXT NOT NULL, -- Comma-separated - performed_by INT NOT NULL, - parameters JSON, - status VARCHAR(20) DEFAULT 'pending', - total_tickets INT, - processed_tickets INT DEFAULT 0, - failed_tickets INT DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - completed_at TIMESTAMP NULL, - FOREIGN KEY (performed_by) REFERENCES users(user_id), - INDEX idx_performed_by (performed_by), - INDEX idx_created_at (created_at) -); diff --git a/migrations/010_expand_status_column.sql b/migrations/010_expand_status_column.sql deleted file mode 100644 index ccbf526..0000000 --- a/migrations/010_expand_status_column.sql +++ /dev/null @@ -1,18 +0,0 @@ --- Migration 010: Expand status column to accommodate longer status names --- The status column was likely VARCHAR(10) which can't fit "In Progress" or "Pending" - --- Check current column definition -SHOW COLUMNS FROM tickets LIKE 'status'; - --- Expand the status column to accommodate longer status names -ALTER TABLE tickets -MODIFY COLUMN status VARCHAR(20) NOT NULL DEFAULT 'Open'; - --- Verify the change -SHOW COLUMNS FROM tickets LIKE 'status'; - --- Show current status distribution -SELECT status, COUNT(*) as count -FROM tickets -GROUP BY status -ORDER BY status; diff --git a/migrations/011_create_user_preferences.sql b/migrations/011_create_user_preferences.sql deleted file mode 100644 index 736c9a8..0000000 --- a/migrations/011_create_user_preferences.sql +++ /dev/null @@ -1,48 +0,0 @@ --- Migration 011: Create user_preferences table for persistent user settings --- Stores user-specific preferences like rows per page, default filters, etc. - -CREATE TABLE IF NOT EXISTS user_preferences ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - preference_key VARCHAR(100) NOT NULL, - preference_value TEXT, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - UNIQUE KEY unique_user_pref (user_id, preference_key), - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE -); - --- Default preferences for existing users -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'rows_per_page', '15' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'rows_per_page'); - -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'default_status_filters', 'Open,Pending,In Progress' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'default_status_filters'); - -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'table_density', 'normal' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'table_density'); - -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'notifications_enabled', '1' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'notifications_enabled'); - -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'sound_effects', '1' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'sound_effects'); - -INSERT INTO user_preferences (user_id, preference_key, preference_value) -SELECT user_id, 'toast_duration', '3000' FROM users -WHERE user_id NOT IN (SELECT user_id FROM user_preferences WHERE preference_key = 'toast_duration'); - --- Verify table created -SELECT 'User Preferences Table Created' as info; -DESCRIBE user_preferences; - --- Show count of preferences -SELECT 'Default Preferences Inserted' as info; -SELECT preference_key, COUNT(*) as user_count -FROM user_preferences -GROUP BY preference_key -ORDER BY preference_key; diff --git a/migrations/011_remove_view_tracking.sql b/migrations/011_remove_view_tracking.sql deleted file mode 100644 index da878a8..0000000 --- a/migrations/011_remove_view_tracking.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Remove all ticket view tracking records from audit_log -DELETE FROM audit_log WHERE action_type = 'view'; diff --git a/migrations/012_create_saved_filters.sql b/migrations/012_create_saved_filters.sql deleted file mode 100644 index ff0c5c0..0000000 --- a/migrations/012_create_saved_filters.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Create saved_filters table for storing user's custom search filters -CREATE TABLE IF NOT EXISTS saved_filters ( - filter_id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - filter_name VARCHAR(100) NOT NULL, - filter_criteria JSON NOT NULL, - is_default BOOLEAN DEFAULT FALSE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE, - UNIQUE KEY unique_user_filter_name (user_id, filter_name) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - --- Create index for faster lookups -CREATE INDEX idx_user_filters ON saved_filters(user_id, is_default); diff --git a/migrations/013_add_performance_indexes.sql b/migrations/013_add_performance_indexes.sql deleted file mode 100644 index a46d576..0000000 --- a/migrations/013_add_performance_indexes.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Migration 013: Add performance indexes for critical queries - --- Index on ticket_comments.ticket_id (foreign key without index) --- Speeds up comment loading by 10-100x on large tables -CREATE INDEX IF NOT EXISTS idx_ticket_comments_ticket_id -ON ticket_comments(ticket_id); - --- Composite index on audit_log for entity lookups with date sorting --- Optimizes activity timeline queries -CREATE INDEX IF NOT EXISTS idx_audit_entity_created -ON audit_log(entity_type, entity_id, created_at DESC); diff --git a/migrations/013_rollback.sql b/migrations/013_rollback.sql deleted file mode 100644 index 4c5e514..0000000 --- a/migrations/013_rollback.sql +++ /dev/null @@ -1,4 +0,0 @@ --- Rollback for migration 013: Remove performance indexes - -DROP INDEX IF EXISTS idx_ticket_comments_ticket_id ON ticket_comments; -DROP INDEX IF EXISTS idx_audit_entity_created ON audit_log; diff --git a/migrations/014_add_additional_indexes.sql b/migrations/014_add_additional_indexes.sql deleted file mode 100644 index 8f2f60d..0000000 --- a/migrations/014_add_additional_indexes.sql +++ /dev/null @@ -1,23 +0,0 @@ --- Migration: Add additional indexes for improved query performance --- Version: 014 - --- Index for audit log queries by user and date (activity reports) -CREATE INDEX IF NOT EXISTS idx_audit_log_user_created ON audit_log(user_id, created_at DESC); - --- Index for audit log queries by action type (security monitoring) -CREATE INDEX IF NOT EXISTS idx_audit_log_action_type ON audit_log(action_type, created_at DESC); - --- Index for tickets by status only (status filtering) -CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status); - --- Composite index for common dashboard queries (status + priority + created_at) -CREATE INDEX IF NOT EXISTS idx_tickets_status_priority_created ON tickets(status, priority, created_at DESC); - --- Index for ticket comments by ticket_id and date (comment listing) -CREATE INDEX IF NOT EXISTS idx_comments_ticket_created ON ticket_comments(ticket_id, created_at DESC); - --- Index for API keys by key value (authentication lookups) -CREATE INDEX IF NOT EXISTS idx_api_keys_key_value ON api_keys(key_value); - --- Index for user preferences lookup -CREATE INDEX IF NOT EXISTS idx_user_preferences_user_key ON user_preferences(user_id, preference_key); diff --git a/migrations/MIGRATION_009_INSTRUCTIONS.md b/migrations/MIGRATION_009_INSTRUCTIONS.md deleted file mode 100644 index 52d3574..0000000 --- a/migrations/MIGRATION_009_INSTRUCTIONS.md +++ /dev/null @@ -1,118 +0,0 @@ -# Migration 009: Simplify Status Workflow - -This migration removes the "Resolved" status and adds a "Pending" status to the ticket system. - -## Status Changes - -### Before (4 statuses): -- Open -- In Progress -- **Resolved** ❌ (being removed) -- Closed - -### After (4 statuses): -- Open -- **Pending** ✅ (new) -- In Progress -- Closed - -## What "Pending" Means - -**Pending** status indicates a ticket is waiting on: -- External dependencies -- Third-party responses -- Parts/equipment to arrive -- Customer information -- Approval from another team - -Unlike "In Progress" which means active work is happening, "Pending" means the ticket is blocked and waiting. - -## Running the Migration - -On the tinkertickets server, run: - -```bash -cd /var/www/html/tinkertickets/migrations -mysql -h 10.10.10.50 -u tinkertickets -p'&*woX!5R$x8Tyrm7zNxC' ticketing_system < 009_simplify_status_workflow.sql -``` - -## What the Migration Does - -1. Updates any existing tickets with status "Resolved" to "Closed" -2. Deletes all status transitions involving "Resolved" -3. Creates new workflow with "Pending" status -4. Sets up the following allowed transitions: - -### New Workflow Transitions: - -**From Open:** -- → Pending (no comment required) -- → In Progress (no comment required) -- → Closed (requires comment) - -**From Pending:** -- → Open (no comment required) -- → In Progress (no comment required) -- → Closed (requires comment) - -**From In Progress:** -- → Open (no comment required) -- → Pending (no comment required) -- → Closed (requires comment) - -**From Closed:** -- → Open (requires comment - explain why reopening) -- → In Progress (no comment required) - -## CSS Updates - -The following CSS files have been updated: -- ✅ `/assets/css/dashboard.css` - Added `.status-Pending` styling with purple color (#9c27b0) and pause icon -- ✅ `/assets/css/ticket.css` - Added `.status-Pending` styling - -## Visual Appearance - -The Pending status will display as: -``` -[⏸ PENDING] -``` -- Purple color border and text -- Pause icon (⏸) to indicate waiting state -- Terminal-style glow effect - -## Verification - -After running the migration, verify: - -1. Check that all tickets previously marked "Resolved" are now "Closed": - ```sql - SELECT COUNT(*) FROM tickets WHERE status = 'Resolved'; -- Should be 0 - SELECT COUNT(*) FROM tickets WHERE status = 'Closed'; - ``` - -2. Check new transitions exist: - ```sql - SELECT from_status, to_status FROM status_transitions - WHERE from_status = 'Pending' OR to_status = 'Pending' - ORDER BY from_status, to_status; - ``` - -3. Test creating a new ticket and changing its status to Pending in the UI - -## Rollback (if needed) - -If you need to rollback this migration: - -```sql --- Restore Resolved status transitions -DELETE FROM status_transitions WHERE from_status = 'Pending' OR to_status = 'Pending'; - -INSERT INTO status_transitions (from_status, to_status, requires_comment) VALUES - ('In Progress', 'Resolved', FALSE), - ('Resolved', 'Closed', FALSE), - ('Resolved', 'In Progress', TRUE), - ('Open', 'Resolved', FALSE); - --- Update any Pending tickets to Open -UPDATE tickets SET status = 'Open' WHERE status = 'Pending'; -``` diff --git a/migrations/rollback_all.sql b/migrations/rollback_all.sql deleted file mode 100644 index 4d1c021..0000000 --- a/migrations/rollback_all.sql +++ /dev/null @@ -1,25 +0,0 @@ --- Rollback script to undo all SSO integration changes --- WARNING: This will delete all user data, API keys, and audit logs - --- Drop foreign keys first -ALTER TABLE ticket_comments DROP FOREIGN KEY IF EXISTS fk_comments_user_id; -ALTER TABLE tickets DROP FOREIGN KEY IF EXISTS fk_tickets_created_by; -ALTER TABLE tickets DROP FOREIGN KEY IF EXISTS fk_tickets_updated_by; -ALTER TABLE api_keys DROP FOREIGN KEY IF EXISTS api_keys_ibfk_1; -ALTER TABLE audit_log DROP FOREIGN KEY IF EXISTS audit_log_ibfk_1; - --- Drop columns from existing tables -ALTER TABLE ticket_comments DROP COLUMN IF EXISTS user_id; -ALTER TABLE tickets DROP COLUMN IF EXISTS created_by; -ALTER TABLE tickets DROP COLUMN IF EXISTS updated_by; -ALTER TABLE tickets DROP COLUMN IF EXISTS updated_at; - --- Drop new tables -DROP TABLE IF EXISTS audit_log; -DROP TABLE IF EXISTS api_keys; -DROP TABLE IF EXISTS users; - --- Drop indexes -DROP INDEX IF EXISTS idx_status ON tickets; -DROP INDEX IF EXISTS idx_priority ON tickets; -DROP INDEX IF EXISTS idx_tickets_created_at ON tickets; diff --git a/models/DependencyModel.php b/models/DependencyModel.php index 2d76b65..b54ad4e 100644 --- a/models/DependencyModel.php +++ b/models/DependencyModel.php @@ -23,8 +23,13 @@ class DependencyModel { ORDER BY d.dependency_type, d.created_at DESC"; $stmt = $this->conn->prepare($sql); + if (!$stmt) { + throw new Exception('Prepare failed: ' . $this->conn->error); + } $stmt->bind_param("s", $ticketId); - $stmt->execute(); + if (!$stmt->execute()) { + throw new Exception('Execute failed: ' . $stmt->error); + } $result = $stmt->get_result(); $dependencies = [ @@ -56,8 +61,13 @@ class DependencyModel { ORDER BY d.dependency_type, d.created_at DESC"; $stmt = $this->conn->prepare($sql); + if (!$stmt) { + throw new Exception('Prepare failed: ' . $this->conn->error); + } $stmt->bind_param("s", $ticketId); - $stmt->execute(); + if (!$stmt->execute()) { + throw new Exception('Execute failed: ' . $stmt->error); + } $result = $stmt->get_result(); $dependents = [];