diff --git a/backend/migrations/add_granite_workflow_type.js b/backend/migrations/add_granite_workflow_type.js new file mode 100644 index 0000000..b0adce4 --- /dev/null +++ b/backend/migrations/add_granite_workflow_type.js @@ -0,0 +1,80 @@ +// Migration: Add GRANITE to workflow_type CHECK constraint on ivanti_todo_queue +// SQLite cannot ALTER a CHECK constraint, so this recreates the table. +const sqlite3 = require('sqlite3').verbose(); +const path = require('path'); + +const dbPath = path.join(__dirname, '..', 'cve_database.db'); +const db = new sqlite3.Database(dbPath); + +console.log('Starting add_granite_workflow_type migration...'); + +db.serialize(() => { + db.run('PRAGMA foreign_keys = OFF', (err) => { + if (err) console.error('PRAGMA error:', err); + }); + + db.run('BEGIN TRANSACTION', (err) => { + if (err) { console.error('BEGIN error:', err); return; } + }); + + db.run(` + CREATE TABLE ivanti_todo_queue_new ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + finding_id TEXT NOT NULL, + finding_title TEXT, + cves_json TEXT, + ip_address TEXT, + hostname TEXT, + vendor TEXT NOT NULL, + workflow_type TEXT NOT NULL CHECK(workflow_type IN ('FP', 'Archer', 'CARD', 'GRANITE')), + status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'complete')), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE + ) + `, (err) => { + if (err) console.error('Error creating new table:', err); + else console.log('✓ ivanti_todo_queue_new created'); + }); + + db.run( + 'INSERT INTO ivanti_todo_queue_new SELECT id, user_id, finding_id, finding_title, cves_json, ip_address, hostname, vendor, workflow_type, status, created_at, updated_at FROM ivanti_todo_queue', + (err) => { + if (err) console.error('Error copying data:', err); + else console.log('✓ Data copied'); + } + ); + + db.run('DROP TABLE ivanti_todo_queue', (err) => { + if (err) console.error('Error dropping old table:', err); + else console.log('✓ Old table dropped'); + }); + + db.run( + 'ALTER TABLE ivanti_todo_queue_new RENAME TO ivanti_todo_queue', + (err) => { + if (err) console.error('Error renaming table:', err); + else console.log('✓ Table renamed'); + } + ); + + db.run( + 'CREATE INDEX IF NOT EXISTS idx_todo_queue_user ON ivanti_todo_queue(user_id, status)', + (err) => { + if (err) console.error('Error creating index:', err); + else console.log('✓ Index recreated'); + } + ); + + db.run('COMMIT', (err) => { + if (err) console.error('COMMIT error:', err); + else console.log('✓ Transaction committed'); + }); + + db.run('PRAGMA foreign_keys = ON', () => {}); // FIXME: Callback does not handle the error parameter (should be `(err) => { if (err) ... }`) +}); + +db.close(() => { + console.log('Migration complete!'); +});