import { index, integer, real, sqliteTable, text, } from "drizzle-orm/sqlite-core"; import { conversations } from "./conversations.js"; export const callSessions = sqliteTable( "call_sessions", { id: text("id").primaryKey(), conversationId: text("conversation_id") .notNull() .references(() => conversations.id, { onDelete: "cascade" }), provider: text("provider").notNull(), providerCallSid: text("provider_call_sid"), fromNumber: text("from_number").notNull(), toNumber: text("to_number").notNull(), task: text("task"), status: text("status").notNull().default("initiated"), callMode: text("call_mode"), verificationSessionId: text("verification_session_id"), inviteFriendName: text("invite_friend_name"), inviteGuardianName: text("invite_guardian_name"), callerIdentityMode: text("caller_identity_mode"), callerIdentitySource: text("caller_identity_source"), skipDisclosure: integer("skip_disclosure").notNull().default(0), initiatedFromConversationId: text("initiated_from_conversation_id"), startedAt: integer("started_at"), endedAt: integer("ended_at"), lastError: text("last_error"), createdAt: integer("created_at").notNull(), updatedAt: integer("updated_at").notNull(), }, (table) => [index("idx_call_sessions_status").on(table.status)], ); export const callEvents = sqliteTable("call_events", { id: text("id").primaryKey(), callSessionId: text("call_session_id") .notNull() .references(() => callSessions.id, { onDelete: "cascade" }), eventType: text("event_type").notNull(), payloadJson: text("payload_json").notNull().default("{}"), createdAt: integer("created_at").notNull(), }); export const callPendingQuestions = sqliteTable("call_pending_questions", { id: text("id").primaryKey(), callSessionId: text("call_session_id") .notNull() .references(() => callSessions.id, { onDelete: "cascade" }), questionText: text("question_text").notNull(), status: text("status").notNull().default("pending"), askedAt: integer("asked_at").notNull(), answeredAt: integer("answered_at"), answerText: text("answer_text"), }); export const processedCallbacks = sqliteTable("processed_callbacks", { id: text("id").primaryKey(), dedupeKey: text("dedupe_key").notNull().unique(), callSessionId: text("call_session_id") .notNull() .references(() => callSessions.id, { onDelete: "cascade" }), claimId: text("claim_id"), createdAt: integer("created_at").notNull(), }); export const externalConversationBindings = sqliteTable( "external_conversation_bindings", { conversationId: text("conversation_id") .primaryKey() .references(() => conversations.id, { onDelete: "cascade" }), sourceChannel: text("source_channel").notNull(), externalChatId: text("external_chat_id").notNull(), externalChatName: text("external_chat_name"), externalThreadId: text("external_thread_id"), externalUserId: text("external_user_id"), displayName: text("display_name"), username: text("username"), createdAt: integer("created_at").notNull(), updatedAt: integer("updated_at").notNull(), lastInboundAt: integer("last_inbound_at"), lastOutboundAt: integer("last_outbound_at"), }, ); export const mediaAssets = sqliteTable("media_assets", { id: text("id").primaryKey(), title: text("title").notNull(), filePath: text("file_path").notNull(), mimeType: text("mime_type").notNull(), durationSeconds: real("duration_seconds"), fileHash: text("file_hash").notNull(), status: text("status").notNull().default("registered"), // registered | processing | indexed | failed mediaType: text("media_type").notNull(), // video | audio | image metadata: text("metadata"), // JSON createdAt: integer("created_at").notNull(), updatedAt: integer("updated_at").notNull(), }); export const processingStages = sqliteTable("processing_stages", { id: text("id").primaryKey(), assetId: text("asset_id") .notNull() .references(() => mediaAssets.id, { onDelete: "cascade" }), stage: text("stage").notNull(), status: text("status").notNull().default("pending"), // pending | running | completed | failed progress: integer("progress").notNull().default(0), // 0-100 lastError: text("last_error"), startedAt: integer("started_at"), completedAt: integer("completed_at"), }); export const mediaKeyframes = sqliteTable("media_keyframes", { id: text("id").primaryKey(), assetId: text("asset_id") .notNull() .references(() => mediaAssets.id, { onDelete: "cascade" }), timestamp: real("timestamp").notNull(), filePath: text("file_path").notNull(), metadata: text("metadata"), // JSON createdAt: integer("created_at").notNull(), });