import { v } from 'convex/values'; import { mutation, query } from './_generated/server'; const DEFAULT_MODEL = 'gemini-3-pro-preview'; export const getById = query({ args: { userId: v.id('users') }, returns: v.union( 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) => { return await ctx.db.get(args.userId); } }); export const getByTelegramId = query({ args: { telegramId: v.int64() }, returns: v.union( 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) => { return await ctx.db .query('users') .withIndex('by_telegram_id', (q) => q.eq('telegramId', args.telegramId)) .unique(); } }); export const getOrCreate = mutation({ args: { telegramId: v.int64(), telegramChatId: v.optional(v.int64()) }, returns: v.id('users'), handler: async (ctx, args) => { const existing = await ctx.db .query('users') .withIndex('by_telegram_id', (q) => q.eq('telegramId', args.telegramId)) .unique(); if (existing) { if (args.telegramChatId && existing.telegramChatId !== args.telegramChatId) { await ctx.db.patch(existing._id, { telegramChatId: args.telegramChatId }); } return existing._id; } return await ctx.db.insert('users', { telegramId: args.telegramId, telegramChatId: args.telegramChatId, model: DEFAULT_MODEL }); } }); export const setApiKey = mutation({ args: { userId: v.id('users'), apiKey: v.string() }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { geminiApiKey: args.apiKey }); return null; } }); export const setSystemPrompt = mutation({ args: { userId: v.id('users'), prompt: v.string() }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { systemPrompt: args.prompt }); return null; } }); export const setFollowUpPrompt = mutation({ args: { userId: v.id('users'), prompt: v.string() }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { followUpPrompt: args.prompt }); return null; } }); export const setModel = mutation({ args: { userId: v.id('users'), model: v.string() }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { model: args.model }); return null; } }); export const setFollowUpModel = mutation({ args: { userId: v.id('users'), model: v.string() }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { followUpModel: args.model }); return null; } }); export const setActiveChat = mutation({ args: { userId: v.id('users'), chatId: v.id('chats') }, returns: v.null(), handler: async (ctx, args) => { await ctx.db.patch(args.userId, { activeChatId: args.chatId }); return null; } });