UNPKG

codecrucible-synth

Version:

Production-Ready AI Development Platform with Multi-Voice Synthesis, Smithery MCP Integration, Enterprise Security, and Zero-Timeout Reliability

269 lines (241 loc) 9.53 kB
/** * Initial database schema for CodeCrucible Synth * Creates all necessary tables with proper indexes and constraints */ exports.up = async function(knex) { // Users table for authentication await knex.schema.createTable('users', table => { table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')); table.string('username', 255).unique().notNullable(); table.string('email', 255).unique(); table.string('password_hash', 255).notNullable(); table.string('salt', 255).notNullable(); table.json('roles').defaultTo('[]'); table.enum('status', ['active', 'inactive', 'suspended']).defaultTo('active'); table.timestamp('last_login'); table.integer('failed_login_attempts').defaultTo(0); table.boolean('account_locked').defaultTo(false); table.timestamp('lockout_expires'); table.json('metadata').defaultTo('{}'); table.timestamps(true, true); // Indexes table.index('username'); table.index('email'); table.index('status'); table.index('created_at'); }); // Projects table await knex.schema.createTable('projects', table => { table.increments('id').primary(); table.string('name', 255).notNullable(); table.text('path').unique().notNullable(); table.string('project_type', 100); table.text('description'); table.timestamp('last_analyzed'); table.json('metadata').defaultTo('{}'); table.timestamps(true, true); // Indexes table.index('name'); table.index('project_type'); table.index(['last_analyzed', 'created_at']); }); // User sessions table await knex.schema.createTable('user_sessions', table => { table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')); table.uuid('user_id').references('id').inTable('users').onDelete('CASCADE'); table.string('session_token', 255).unique().notNullable(); table.string('refresh_token', 255).unique().notNullable(); table.timestamp('expires_at').notNullable(); table.timestamp('last_activity').defaultTo(knex.fn.now()); table.string('ip_address', 45); // IPv6 compatible table.text('user_agent'); table.json('permissions').defaultTo('[]'); table.json('roles').defaultTo('[]'); table.timestamps(true, true); // Indexes table.index('user_id'); table.index('session_token'); table.index('expires_at'); table.index('last_activity'); }); // Voice interactions table await knex.schema.createTable('voice_interactions', table => { table.increments('id').primary(); table.uuid('session_id').notNullable(); table.string('voice_name', 100).notNullable(); table.text('prompt').notNullable(); table.text('response').notNullable(); table.decimal('confidence', 3, 2).notNullable(); table.integer('tokens_used').notNullable(); table.integer('response_time_ms'); table.string('model_used', 100); table.json('metadata').defaultTo('{}'); table.timestamp('created_at').defaultTo(knex.fn.now()); // Indexes table.index('session_id'); table.index('voice_name'); table.index('created_at'); table.index(['voice_name', 'created_at']); }); // Code analysis results table await knex.schema.createTable('code_analysis', table => { table.increments('id').primary(); table.integer('project_id').references('id').inTable('projects').onDelete('CASCADE'); table.text('file_path').notNullable(); table.string('analysis_type', 100).notNullable(); table.jsonb('results').notNullable(); // Use JSONB for better performance table.integer('quality_score'); table.decimal('execution_time_ms', 10, 3); table.string('analyzer_version', 50); table.timestamp('created_at').defaultTo(knex.fn.now()); // Indexes table.index('project_id'); table.index('analysis_type'); table.index('created_at'); table.index('quality_score'); // GIN index for JSONB queries table.index(knex.raw('results USING GIN')); }); // Application configuration table await knex.schema.createTable('app_config', table => { table.string('key', 255).primary(); table.jsonb('value').notNullable(); table.text('description'); table.boolean('encrypted').defaultTo(false); table.string('category', 100).defaultTo('general'); table.timestamp('updated_at').defaultTo(knex.fn.now()); // Indexes table.index('category'); table.index('updated_at'); }); // Backup metadata table await knex.schema.createTable('backup_metadata', table => { table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')); table.enum('type', ['full', 'incremental', 'differential']).notNullable(); table.bigInteger('size_bytes').notNullable(); table.boolean('compressed').defaultTo(true); table.boolean('encrypted').defaultTo(false); table.string('checksum', 255).notNullable(); table.string('version', 50).notNullable(); table.string('source', 255).notNullable(); table.text('destination').notNullable(); table.string('storage_type', 50).defaultTo('local'); table.json('metadata').defaultTo('{}'); table.timestamp('created_at').defaultTo(knex.fn.now()); table.timestamp('expires_at'); // Indexes table.index('type'); table.index('created_at'); table.index('expires_at'); table.index('storage_type'); }); // Security audit log table await knex.schema.createTable('security_audit_log', table => { table.increments('id').primary(); table.uuid('user_id').references('id').inTable('users').onDelete('SET NULL'); table.uuid('session_id').references('id').inTable('user_sessions').onDelete('SET NULL'); table.enum('event_type', [ 'login_success', 'login_failure', 'logout', 'permission_denied', 'data_access', 'data_modification', 'system_event', 'security_violation' ]).notNullable(); table.enum('severity', ['low', 'medium', 'high', 'critical']).notNullable(); table.enum('outcome', ['success', 'failure', 'blocked']).notNullable(); table.string('source_ip', 45); table.text('user_agent'); table.string('resource', 255); table.text('description').notNullable(); table.jsonb('details').defaultTo('{}'); table.timestamp('created_at').defaultTo(knex.fn.now()); // Indexes table.index('user_id'); table.index('event_type'); table.index('severity'); table.index('created_at'); table.index(['event_type', 'severity', 'created_at']); }); // Performance metrics table await knex.schema.createTable('performance_metrics', table => { table.increments('id').primary(); table.string('metric_name', 255).notNullable(); table.string('component', 100).notNullable(); table.decimal('value', 15, 6).notNullable(); table.string('unit', 50).notNullable(); table.json('tags').defaultTo('{}'); table.timestamp('timestamp').defaultTo(knex.fn.now()); // Indexes table.index('metric_name'); table.index('component'); table.index('timestamp'); table.index(['metric_name', 'timestamp']); }); // RBAC permissions table await knex.schema.createTable('permissions', table => { table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')); table.string('name', 255).unique().notNullable(); table.text('description'); table.string('resource', 255).notNullable(); table.string('action', 255).notNullable(); table.jsonb('constraints').defaultTo('{}'); table.boolean('is_system').defaultTo(false); table.timestamps(true, true); // Indexes table.index('name'); table.index(['resource', 'action']); }); // RBAC roles table await knex.schema.createTable('roles', table => { table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')); table.string('name', 255).unique().notNullable(); table.text('description'); table.json('permission_ids').defaultTo('[]'); table.json('inherited_role_ids').defaultTo('[]'); table.boolean('is_system').defaultTo(false); table.timestamps(true, true); // Indexes table.index('name'); table.index('is_system'); }); // Error log table for system errors await knex.schema.createTable('error_log', table => { table.increments('id').primary(); table.string('error_type', 255).notNullable(); table.string('component', 255).notNullable(); table.string('operation', 255); table.text('message').notNullable(); table.text('stack_trace'); table.jsonb('context').defaultTo('{}'); table.enum('severity', ['low', 'medium', 'high', 'critical']).notNullable(); table.boolean('resolved').defaultTo(false); table.timestamp('created_at').defaultTo(knex.fn.now()); table.timestamp('resolved_at'); // Indexes table.index('error_type'); table.index('component'); table.index('severity'); table.index('created_at'); table.index('resolved'); }); console.log('✅ Initial schema created successfully'); }; exports.down = async function(knex) { // Drop tables in reverse order to handle foreign key constraints const tables = [ 'error_log', 'roles', 'permissions', 'performance_metrics', 'security_audit_log', 'backup_metadata', 'app_config', 'code_analysis', 'voice_interactions', 'user_sessions', 'projects', 'users' ]; for (const table of tables) { await knex.schema.dropTableIfExists(table); } console.log('✅ Initial schema dropped successfully'); };