godcrm/backend/database/migrations/017-ai-operators-mindworkflow-fields.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

239 lines
No EOL
6.8 KiB
JavaScript

// Migration 017: Add MindWorkflow-specific fields to AI Operators table
// Adds integration_key, default_model, supported_models, mindworkflow_config columns
import { dbRun, dbGet, dbAll, isPostgres } from '../connection.js';
/**
* Run migration to add MindWorkflow fields to AI Operators
*/
export async function runMigration() {
console.log('📦 Running Migration 017: AI Operators MindWorkflow Fields...');
try {
if (isPostgres()) {
// PostgreSQL version
await runPostgresMigration();
} else {
// SQLite version
await runSQLiteMigration();
}
console.log('✅ Migration 017 completed successfully!');
} catch (error) {
console.error('❌ Migration 017 failed:', error);
throw error;
}
}
/**
* PostgreSQL migration
*/
async function runPostgresMigration() {
// Find ALL AI Operators tables
const aiOperatorsTables = await dbAll(
"SELECT id FROM universal_tables WHERE name = 'AI Operators'"
);
if (!aiOperatorsTables || aiOperatorsTables.length === 0) {
console.log('⚠️ AI Operators tables not found, skipping migration');
return;
}
console.log(`Found ${aiOperatorsTables.length} AI Operators tables`);
for (const table of aiOperatorsTables) {
const tableId = table.id;
console.log(`Processing AI Operators table ID: ${tableId}`);
// Get current max order_index
const maxOrderResult = await dbGet(
'SELECT MAX(order_index) as max_order FROM table_columns WHERE table_id = $1',
[tableId]
);
let nextOrder = (maxOrderResult?.max_order || 0) + 1;
// Add MindWorkflow-specific columns
const columnsToAdd = [
{
column_name: 'integration_key',
display_name: 'Integration Key',
type: 'text',
config: JSON.stringify({
icon: '🔑',
placeholder: 'mindworkflow_api_key',
description: 'Unique key for MindWorkflow integration'
})
},
{
column_name: 'default_model',
display_name: 'Default Model',
type: 'text',
config: JSON.stringify({
icon: '🤖',
placeholder: 'gpt-4o-mini',
description: 'Default AI model for this operator'
})
},
{
column_name: 'supported_models',
display_name: 'Supported Models',
type: 'long_text',
config: JSON.stringify({
icon: '📋',
placeholder: '["gpt-4o-mini", "gpt-4o", "claude-3.5"]',
description: 'JSON array of supported models'
})
},
{
column_name: 'mindworkflow_config',
display_name: 'MindWorkflow Config',
type: 'long_text',
config: JSON.stringify({
icon: '⚙️',
placeholder: '{"endpoint": "https://api.example.com", "version": "v1"}',
description: 'JSON configuration for MindWorkflow integration'
})
}
];
for (const column of columnsToAdd) {
// Check if column already exists
const existingColumn = await dbGet(
'SELECT id FROM table_columns WHERE table_id = $1 AND column_name = $2',
[tableId, column.column_name]
);
if (existingColumn) {
console.log(`⚠️ Table ${tableId}: Column ${column.column_name} already exists, skipping`);
continue;
}
// Add the column
await dbRun(`
INSERT INTO table_columns (
table_id, column_name, display_name, type, config,
width, is_required, order_index, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())
`, [
tableId,
column.column_name,
column.display_name,
column.type,
column.config,
200, // width
0, // is_required
nextOrder++
]);
console.log(`✅ Table ${tableId}: Added column: ${column.column_name}`);
}
}
}
/**
* SQLite migration
*/
async function runSQLiteMigration() {
// Find ALL AI Operators tables
const aiOperatorsTables = await dbAll(
"SELECT id FROM universal_tables WHERE name = 'AI Operators'"
);
if (!aiOperatorsTables || aiOperatorsTables.length === 0) {
console.log('⚠️ AI Operators tables not found, skipping migration');
return;
}
console.log(`Found ${aiOperatorsTables.length} AI Operators tables`);
for (const table of aiOperatorsTables) {
const tableId = table.id;
console.log(`Processing AI Operators table ID: ${tableId}`);
// Get current max order_index
const maxOrderResult = await dbGet(
'SELECT MAX(order_index) as max_order FROM table_columns WHERE table_id = ?',
[tableId]
);
let nextOrder = (maxOrderResult?.max_order || 0) + 1;
// Add MindWorkflow-specific columns
const columnsToAdd = [
{
column_name: 'integration_key',
display_name: 'Integration Key',
type: 'text',
config: JSON.stringify({
icon: '🔑',
placeholder: 'mindworkflow_api_key',
description: 'Unique key for MindWorkflow integration'
})
},
{
column_name: 'default_model',
display_name: 'Default Model',
type: 'text',
config: JSON.stringify({
icon: '🤖',
placeholder: 'gpt-4o-mini',
description: 'Default AI model for this operator'
})
},
{
column_name: 'supported_models',
display_name: 'Supported Models',
type: 'long_text',
config: JSON.stringify({
icon: '📋',
placeholder: '["gpt-4o-mini", "gpt-4o", "claude-3.5"]',
description: 'JSON array of supported models'
})
},
{
column_name: 'mindworkflow_config',
display_name: 'MindWorkflow Config',
type: 'long_text',
config: JSON.stringify({
icon: '⚙️',
placeholder: '{"endpoint": "https://api.example.com", "version": "v1"}',
description: 'JSON configuration for MindWorkflow integration'
})
}
];
for (const column of columnsToAdd) {
// Check if column already exists
const existingColumn = await dbGet(
'SELECT id FROM table_columns WHERE table_id = ? AND column_name = ?',
[tableId, column.column_name]
);
if (existingColumn) {
console.log(`⚠️ Column ${column.column_name} already exists, skipping`);
continue;
}
// Add the column
await dbRun(`
INSERT INTO table_columns (
table_id, column_name, display_name, type, config,
width, is_required, order_index, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, [
tableId,
column.column_name,
column.display_name,
column.type,
column.config,
200, // width
0, // is_required
nextOrder++
]);
console.log(`✅ Added column: ${column.column_name}`);
}
}
export default { runMigration };