import { v } from 'convex/values'; import { mutation, query } from './_generated/server'; export const getByMnemonic = query({ args: { mnemonic: v.string() }, returns: v.union( v.object({ _id: v.id('chats'), _creationTime: v.number(), userId: v.id('users'), mnemonic: v.string(), createdAt: v.number() }), v.null() ), handler: async (ctx, args) => { return await ctx.db .query('chats') .withIndex('by_mnemonic', (q) => q.eq('mnemonic', args.mnemonic)) .unique(); } }); export const create = mutation({ args: { userId: v.id('users'), mnemonic: v.string() }, returns: v.id('chats'), handler: async (ctx, args) => { return await ctx.db.insert('chats', { userId: args.userId, mnemonic: args.mnemonic, createdAt: Date.now() }); } }); export const clear = mutation({ args: { chatId: v.id('chats'), preserveImages: v.optional(v.boolean()) }, returns: v.null(), handler: async (ctx, args) => { const messages = await ctx.db .query('messages') .withIndex('by_chat_id', (q) => q.eq('chatId', args.chatId)) .collect(); for (const message of messages) { if (args.preserveImages && message.imageBase64) { continue; } await ctx.db.delete(message._id); } return null; } }); export const getWithUser = query({ args: { mnemonic: v.string() }, returns: v.union( v.object({ chat: v.object({ _id: v.id('chats'), _creationTime: v.number(), userId: v.id('users'), mnemonic: v.string(), createdAt: v.number() }), user: v.object({ _id: v.id('users'), _creationTime: v.number(), telegramId: v.int64(), telegramChatId: v.optional(v.int64()), geminiApiKey: v.optional(v.string()), systemPrompt: v.optional(v.string()), followUpPrompt: v.optional(v.string()), model: v.string(), followUpModel: v.optional(v.string()), activeChatId: v.optional(v.id('chats')) }) }), v.null() ), handler: async (ctx, args) => { const chat = await ctx.db .query('chats') .withIndex('by_mnemonic', (q) => q.eq('mnemonic', args.mnemonic)) .unique(); if (!chat) { return null; } const user = await ctx.db.get(chat.userId); if (!user) { return null; } return { chat, user }; } });