130 lines
3.3 KiB
TypeScript
130 lines
3.3 KiB
TypeScript
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;
|
|
}
|
|
});
|