56 lines
1.9 KiB
JavaScript
56 lines
1.9 KiB
JavaScript
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.up = async function (knex) {
|
|
// Create calls table for tracking voice calls
|
|
await knex.schema.createTable('calls', (table) => {
|
|
table.string('id', 36).primary();
|
|
table.string('call_sid', 100).unique().notNullable().comment('Twilio call SID');
|
|
table.enum('direction', ['inbound', 'outbound']).notNullable();
|
|
table.string('from_number', 20).notNullable();
|
|
table.string('to_number', 20).notNullable();
|
|
table.enum('status', [
|
|
'queued',
|
|
'ringing',
|
|
'in-progress',
|
|
'completed',
|
|
'busy',
|
|
'failed',
|
|
'no-answer',
|
|
'canceled'
|
|
]).notNullable().defaultTo('queued');
|
|
table.integer('duration_seconds').unsigned().nullable();
|
|
table.string('recording_url', 500).nullable();
|
|
table.text('ai_transcript').nullable().comment('Full transcript from OpenAI');
|
|
table.text('ai_summary').nullable().comment('AI-generated summary');
|
|
table.json('ai_insights').nullable().comment('Structured insights from AI');
|
|
table.string('user_id', 36).notNullable().comment('User who handled the call');
|
|
table.timestamp('started_at').nullable();
|
|
table.timestamp('ended_at').nullable();
|
|
table.timestamp('created_at').defaultTo(knex.fn.now());
|
|
table.timestamp('updated_at').defaultTo(knex.fn.now());
|
|
|
|
// Indexes
|
|
table.index('call_sid');
|
|
table.index('user_id');
|
|
table.index('status');
|
|
table.index('direction');
|
|
table.index(['created_at', 'user_id']);
|
|
|
|
// Foreign key to users table
|
|
table.foreign('user_id').references('id').inTable('users').onDelete('CASCADE');
|
|
});
|
|
|
|
console.log('✅ Created calls table');
|
|
};
|
|
|
|
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.down = async function (knex) {
|
|
await knex.schema.dropTableIfExists('calls');
|
|
console.log('✅ Dropped calls table');
|
|
};
|