diff --git a/backend/migrations/add_flexible_jira_ticket_creation.js b/backend/migrations/add_flexible_jira_ticket_creation.js index 1fb917b..d4d8059 100644 --- a/backend/migrations/add_flexible_jira_ticket_creation.js +++ b/backend/migrations/add_flexible_jira_ticket_creation.js @@ -28,6 +28,23 @@ async function run() { await pool.query(`ALTER TABLE jira_tickets ALTER COLUMN vendor DROP NOT NULL`); console.log('✓ vendor NOT NULL constraint dropped (or was already nullable)'); + // Add jira_id, jira_status, last_synced_at, created_by columns + // (originally from SQLite migration add_jira_sync_columns.js — never ported to Postgres run-all) + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS jira_id TEXT`); + console.log('✓ jira_id column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS jira_status TEXT`); + console.log('✓ jira_status column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS last_synced_at TIMESTAMPTZ`); + console.log('✓ last_synced_at column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS created_by INTEGER`); + console.log('✓ created_by column added (or already exists)'); + + await pool.query(`CREATE INDEX IF NOT EXISTS idx_jira_tickets_jira_id ON jira_tickets(jira_id)`); + console.log('✓ jira_id index created (or already exists)'); + // Add source_context column with default value (IF NOT EXISTS makes it idempotent) await pool.query(` ALTER TABLE jira_tickets diff --git a/backend/migrations/add_jira_sync_columns_pg.js b/backend/migrations/add_jira_sync_columns_pg.js new file mode 100644 index 0000000..c2f494e --- /dev/null +++ b/backend/migrations/add_jira_sync_columns_pg.js @@ -0,0 +1,42 @@ +// Migration: Add Jira sync columns to jira_tickets (Postgres version) +// Adds jira_id, jira_status, last_synced_at, and created_by columns. +// These were originally added via a SQLite migration that was never ported to Postgres. +// Idempotent — safe to run multiple times. +const pool = require('../db'); + +async function run() { + console.log('Adding Jira sync columns to jira_tickets (Postgres)...'); + + // Verify table exists + const { rows } = await pool.query(` + SELECT 1 FROM information_schema.tables + WHERE table_schema = 'public' AND table_name = 'jira_tickets' + `); + if (rows.length === 0) { + console.error('✗ jira_tickets table does not exist. Cannot proceed.'); + process.exit(1); + } + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS jira_id TEXT`); + console.log('✓ jira_id column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS jira_status TEXT`); + console.log('✓ jira_status column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS last_synced_at TIMESTAMPTZ`); + console.log('✓ last_synced_at column added (or already exists)'); + + await pool.query(`ALTER TABLE jira_tickets ADD COLUMN IF NOT EXISTS created_by INTEGER`); + console.log('✓ created_by column added (or already exists)'); + + await pool.query(`CREATE INDEX IF NOT EXISTS idx_jira_tickets_jira_id ON jira_tickets(jira_id)`); + console.log('✓ jira_id index created (or already exists)'); + + console.log('Migration complete.'); + process.exit(0); +} + +run().catch(err => { + console.error('Migration failed:', err.message); + process.exit(1); +}); diff --git a/backend/migrations/run-all.js b/backend/migrations/run-all.js index 81c56fe..28ab2e6 100644 --- a/backend/migrations/run-all.js +++ b/backend/migrations/run-all.js @@ -21,6 +21,7 @@ const POSTGRES_MIGRATIONS = [ 'add_vcl_vertical_metadata.js', 'add_vcl_multi_vertical.js', 'add_compliance_item_history.js', + 'add_jira_sync_columns_pg.js', 'add_flexible_jira_ticket_creation.js', ]; diff --git a/backend/routes/jiraTickets.js b/backend/routes/jiraTickets.js index 3c23396..1517151 100644 --- a/backend/routes/jiraTickets.js +++ b/backend/routes/jiraTickets.js @@ -386,7 +386,7 @@ function createJiraTicketsRouter() { res.json(results); } catch (err) { console.error(err); - return res.status(500).json({ error: 'Internal server error.' }); + return res.status(500).json({ error: err.message || 'Internal server error.' }); } }); @@ -461,7 +461,7 @@ function createJiraTicketsRouter() { }); } catch (err) { console.error(err); - return res.status(500).json({ error: 'Internal server error.' }); + return res.status(500).json({ error: err.message || 'Internal server error.' }); } }); @@ -514,7 +514,7 @@ function createJiraTicketsRouter() { res.json(rows); } catch (err) { console.error('Error fetching JIRA tickets:', err); - res.status(500).json({ error: 'Internal server error.' }); + res.status(500).json({ error: err.message || 'Internal server error.' }); } }); @@ -593,7 +593,7 @@ function createJiraTicketsRouter() { }); } catch (err) { console.error('Error creating JIRA ticket:', err); - res.status(500).json({ error: 'Internal server error.' }); + res.status(500).json({ error: `Failed to save ticket: ${err.message}` }); } }); @@ -677,7 +677,7 @@ function createJiraTicketsRouter() { res.json({ message: 'JIRA ticket updated successfully', changes: result.rowCount }); } catch (err) { console.error('Error updating JIRA ticket:', err); - res.status(500).json({ error: 'Internal server error.' }); + res.status(500).json({ error: err.message || 'Internal server error.' }); } }); @@ -758,7 +758,7 @@ function createJiraTicketsRouter() { } } catch (err) { console.error('Error deleting JIRA ticket:', err); - res.status(500).json({ error: 'Internal server error.' }); + res.status(500).json({ error: err.message || 'Internal server error.' }); } });