39599-vm/backend/src/db/migrations/1776043917975.js
2026-04-13 01:33:21 +00:00

3642 lines
115 KiB
JavaScript

module.exports = {
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async up(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.createTable('users', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('roles', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('permissions', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('platform_profiles', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('ai_capability_scans', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('ai_endpoints', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('connectivity_tests', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('proxy_services', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('proxy_routes', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('models_catalog', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('api_requests', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('tool_definitions', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.createTable('audit_events', {
id: {
type: Sequelize.DataTypes.UUID,
defaultValue: Sequelize.DataTypes.UUIDV4,
primaryKey: true,
},
createdById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
updatedById: {
type: Sequelize.DataTypes.UUID,
references: {
key: 'id',
model: 'users',
},
},
createdAt: { type: Sequelize.DataTypes.DATE },
updatedAt: { type: Sequelize.DataTypes.DATE },
deletedAt: { type: Sequelize.DataTypes.DATE },
importHash: {
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
unique: true,
},
}, { transaction });
await queryInterface.addColumn(
'users',
'firstName',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'lastName',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'phoneNumber',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'email',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'disabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'password',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'emailVerified',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'emailVerificationToken',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'emailVerificationTokenExpiresAt',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'passwordResetToken',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'passwordResetTokenExpiresAt',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'provider',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'users',
'app_roleId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'roles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'roles',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'roles',
'role_customization',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'permissions',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'platform_type',
{
type: Sequelize.DataTypes.ENUM,
values: ['vercel','cloudflare_workers','replit','deno_deploy','railway','render','fly_io','other'],
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'runtime',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'region',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'dashboard_url',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'notes',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'ai_integration_supported',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'platform_profiles',
'managed_credentials_supported',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'platform_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'platform_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'run_byId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'started_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'finished_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['pending','running','succeeded','failed','blocked'],
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'matched_priority',
{
type: Sequelize.DataTypes.ENUM,
values: ['none','native_sdk','ai_integration','managed_credentials','env_probe','capability_list'],
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'node_version',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'os_platform',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'env_filter_regex',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'env_dump_output',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'integration_hint',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_capability_scans',
'failure_reason',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'platform_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'platform_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'provider_style',
{
type: Sequelize.DataTypes.ENUM,
values: ['openai_compatible','anthropic_compatible','platform_native'],
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'base_url',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'is_public',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'is_internal_only',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'supports_models_list',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'supports_chat_completions',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'supports_messages_api',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'supports_streaming',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'auth_scheme',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'managed_credential_source',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'ai_endpoints',
'notes',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'ai_endpointId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'ai_endpoints',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'scanId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'ai_capability_scans',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'run_byId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'requested_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'responded_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'status',
{
type: Sequelize.DataTypes.ENUM,
values: ['pending','succeeded','failed'],
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'request_command',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'request_url',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'request_body',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'response_status_code',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'response_headers',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'response_body',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'latency_ms',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'connectivity_tests',
'error_message',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'platform_profileId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'platform_profiles',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'service_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'public_base_url',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'runtime_target',
{
type: Sequelize.DataTypes.ENUM,
values: ['nodejs','serverless','edge_worker','container'],
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'auth_enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'fixed_bearer_token',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'logs_env_on_startup',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'deployed_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'last_restart_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_services',
'notes',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'proxy_serviceId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'proxy_services',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'route_type',
{
type: Sequelize.DataTypes.ENUM,
values: ['models','chat_completions','messages'],
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'path',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'method',
{
type: Sequelize.DataTypes.ENUM,
values: ['GET','POST'],
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'upstream_endpointId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'ai_endpoints',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'model_prefix_rule',
{
type: Sequelize.DataTypes.ENUM,
values: ['openai_gpt_o','anthropic_claude','mixed'],
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'stream_supported',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'tool_calls_supported',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'transform_notes',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'proxy_routes',
'enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'ai_endpointId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'ai_endpoints',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'model_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'model_family',
{
type: Sequelize.DataTypes.ENUM,
values: ['openai','anthropic','other'],
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'available',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'supports_tools',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'supports_vision',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'supports_stream',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'context_window_tokens',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'input_cost_per_million',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'output_cost_per_million',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'last_seen_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'models_catalog',
'raw_descriptor',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'proxy_serviceId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'proxy_services',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'proxy_routeId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'proxy_routes',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'requested_byId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'requested_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'completed_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'api_style',
{
type: Sequelize.DataTypes.ENUM,
values: ['openai','anthropic'],
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'client_ip',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'user_agent',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'request_id',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'model',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'stream',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'prompt_tokens',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'completion_tokens',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'total_tokens',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'cost_estimate',
{
type: Sequelize.DataTypes.DECIMAL,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'response_status_code',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'latency_ms',
{
type: Sequelize.DataTypes.INTEGER,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'error_message',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'request_payload',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'api_requests',
'response_payload',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'proxy_serviceId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'proxy_services',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'tool_name',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'description',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'json_schema',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'tool_style',
{
type: Sequelize.DataTypes.ENUM,
values: ['openai','anthropic','unified'],
},
{ transaction }
);
await queryInterface.addColumn(
'tool_definitions',
'enabled',
{
type: Sequelize.DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'actorId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'users',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'proxy_serviceId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'proxy_services',
key: 'id',
},
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'event_type',
{
type: Sequelize.DataTypes.ENUM,
values: ['scan_started','scan_finished','connectivity_test','service_deployed','service_restarted','route_changed','model_refreshed','auth_failed','config_viewed'],
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'event_at',
{
type: Sequelize.DataTypes.DATE,
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'summary',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await queryInterface.addColumn(
'audit_events',
'details',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async down(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn(
'audit_events',
'details',
{ transaction }
);
await queryInterface.removeColumn(
'audit_events',
'summary',
{ transaction }
);
await queryInterface.removeColumn(
'audit_events',
'event_at',
{ transaction }
);
await queryInterface.removeColumn(
'audit_events',
'event_type',
{ transaction }
);
await queryInterface.removeColumn(
'audit_events',
'proxy_serviceId',
{ transaction }
);
await queryInterface.removeColumn(
'audit_events',
'actorId',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'enabled',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'tool_style',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'json_schema',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'description',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'tool_name',
{ transaction }
);
await queryInterface.removeColumn(
'tool_definitions',
'proxy_serviceId',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'response_payload',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'request_payload',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'error_message',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'latency_ms',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'response_status_code',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'cost_estimate',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'total_tokens',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'completion_tokens',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'prompt_tokens',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'stream',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'model',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'request_id',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'user_agent',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'client_ip',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'api_style',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'completed_at',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'requested_at',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'requested_byId',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'proxy_routeId',
{ transaction }
);
await queryInterface.removeColumn(
'api_requests',
'proxy_serviceId',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'raw_descriptor',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'last_seen_at',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'output_cost_per_million',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'input_cost_per_million',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'context_window_tokens',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'supports_stream',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'supports_vision',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'supports_tools',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'available',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'model_family',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'model_name',
{ transaction }
);
await queryInterface.removeColumn(
'models_catalog',
'ai_endpointId',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'enabled',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'transform_notes',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'tool_calls_supported',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'stream_supported',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'model_prefix_rule',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'upstream_endpointId',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'method',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'path',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'route_type',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_routes',
'proxy_serviceId',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'notes',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'last_restart_at',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'deployed_at',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'enabled',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'logs_env_on_startup',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'fixed_bearer_token',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'auth_enabled',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'runtime_target',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'public_base_url',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'service_name',
{ transaction }
);
await queryInterface.removeColumn(
'proxy_services',
'platform_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'error_message',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'latency_ms',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'response_body',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'response_headers',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'response_status_code',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'request_body',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'request_url',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'request_command',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'responded_at',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'requested_at',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'run_byId',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'scanId',
{ transaction }
);
await queryInterface.removeColumn(
'connectivity_tests',
'ai_endpointId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'notes',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'managed_credential_source',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'auth_scheme',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'supports_streaming',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'supports_messages_api',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'supports_chat_completions',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'supports_models_list',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'is_internal_only',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'is_public',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'base_url',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'provider_style',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'ai_endpoints',
'platform_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'failure_reason',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'integration_hint',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'env_dump_output',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'env_filter_regex',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'os_platform',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'node_version',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'matched_priority',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'status',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'finished_at',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'started_at',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'run_byId',
{ transaction }
);
await queryInterface.removeColumn(
'ai_capability_scans',
'platform_profileId',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'managed_credentials_supported',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'ai_integration_supported',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'notes',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'dashboard_url',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'region',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'runtime',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'platform_type',
{ transaction }
);
await queryInterface.removeColumn(
'platform_profiles',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'permissions',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'roles',
'role_customization',
{ transaction }
);
await queryInterface.removeColumn(
'roles',
'name',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'app_roleId',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'provider',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'passwordResetTokenExpiresAt',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'passwordResetToken',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'emailVerificationTokenExpiresAt',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'emailVerificationToken',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'emailVerified',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'password',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'disabled',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'email',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'phoneNumber',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'lastName',
{ transaction }
);
await queryInterface.removeColumn(
'users',
'firstName',
{ transaction }
);
await queryInterface.dropTable('audit_events', { transaction });
await queryInterface.dropTable('tool_definitions', { transaction });
await queryInterface.dropTable('api_requests', { transaction });
await queryInterface.dropTable('models_catalog', { transaction });
await queryInterface.dropTable('proxy_routes', { transaction });
await queryInterface.dropTable('proxy_services', { transaction });
await queryInterface.dropTable('connectivity_tests', { transaction });
await queryInterface.dropTable('ai_endpoints', { transaction });
await queryInterface.dropTable('ai_capability_scans', { transaction });
await queryInterface.dropTable('platform_profiles', { transaction });
await queryInterface.dropTable('permissions', { transaction });
await queryInterface.dropTable('roles', { transaction });
await queryInterface.dropTable('users', { transaction });
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
}
};