diff --git a/src/db/schema.ts b/src/db/schema.ts index c0b13d9..a5bc1b8 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -197,3 +197,54 @@ export const agentsRelations = relations(agents, ({ one }) => ({ export type Agent = InferSelectModel; export type NewAgent = InferInsertModel; + +// ============================================================================ +// MESSAGES +// ============================================================================ + +export const messages = sqliteTable('messages', { + id: text('id').primaryKey(), + senderType: text('sender_type', { enum: ['agent', 'user'] }).notNull(), + senderId: text('sender_id').references(() => agents.id, { onDelete: 'set null' }), // Agent ID if senderType='agent', null for user + recipientType: text('recipient_type', { enum: ['agent', 'user'] }).notNull(), + recipientId: text('recipient_id').references(() => agents.id, { onDelete: 'set null' }), // Agent ID if recipientType='agent', null for user + type: text('type', { enum: ['question', 'info', 'error', 'response'] }) + .notNull() + .default('info'), + content: text('content').notNull(), + requiresResponse: integer('requires_response', { mode: 'boolean' }) + .notNull() + .default(false), + status: text('status', { enum: ['pending', 'read', 'responded'] }) + .notNull() + .default('pending'), + parentMessageId: text('parent_message_id').references((): ReturnType => messages.id, { onDelete: 'set null' }), // Links response to original question + createdAt: integer('created_at', { mode: 'timestamp' }).notNull(), + updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(), +}); + +export const messagesRelations = relations(messages, ({ one, many }) => ({ + // Sender agent (optional - null for user senders) + senderAgent: one(agents, { + fields: [messages.senderId], + references: [agents.id], + relationName: 'senderAgent', + }), + // Recipient agent (optional - null for user recipients) + recipientAgent: one(agents, { + fields: [messages.recipientId], + references: [agents.id], + relationName: 'recipientAgent', + }), + // Parent message (for threading responses) + parentMessage: one(messages, { + fields: [messages.parentMessageId], + references: [messages.id], + relationName: 'parentMessage', + }), + // Child messages (replies to this message) + childMessages: many(messages, { relationName: 'parentMessage' }), +})); + +export type Message = InferSelectModel; +export type NewMessage = InferInsertModel;