127 lines
3.6 KiB
TypeScript
127 lines
3.6 KiB
TypeScript
import { defineSchema, defineTable } from 'convex/server';
|
|
import { v } from 'convex/values';
|
|
|
|
export default defineSchema({
|
|
users: defineTable({
|
|
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')),
|
|
ragCollectionMode: v.optional(
|
|
v.object({
|
|
ragDatabaseId: v.id('ragDatabases'),
|
|
activeSince: v.number()
|
|
})
|
|
)
|
|
}).index('by_telegram_id', ['telegramId']),
|
|
|
|
chats: defineTable({
|
|
userId: v.id('users'),
|
|
mnemonic: v.string(),
|
|
createdAt: v.number()
|
|
}).index('by_mnemonic', ['mnemonic']),
|
|
|
|
messages: defineTable({
|
|
chatId: v.id('chats'),
|
|
role: v.union(v.literal('user'), v.literal('assistant')),
|
|
content: v.string(),
|
|
imageBase64: v.optional(v.string()),
|
|
imageMediaType: v.optional(v.string()),
|
|
imageStorageId: v.optional(v.id('_storage')),
|
|
imagesBase64: v.optional(v.array(v.string())),
|
|
imagesMediaTypes: v.optional(v.array(v.string())),
|
|
followUpOptions: v.optional(v.array(v.string())),
|
|
source: v.union(v.literal('telegram'), v.literal('web')),
|
|
createdAt: v.number(),
|
|
isStreaming: v.optional(v.boolean())
|
|
})
|
|
.index('by_chat_id', ['chatId'])
|
|
.index('by_chat_id_and_created_at', ['chatId', 'createdAt']),
|
|
|
|
pendingGenerations: defineTable({
|
|
userId: v.id('users'),
|
|
chatId: v.id('chats'),
|
|
userMessage: v.string(),
|
|
imagesBase64: v.optional(v.array(v.string())),
|
|
imagesMediaTypes: v.optional(v.array(v.string())),
|
|
createdAt: v.number()
|
|
}),
|
|
|
|
pendingGenerationImages: defineTable({
|
|
pendingGenerationId: v.id('pendingGenerations'),
|
|
base64: v.string(),
|
|
mediaType: v.string(),
|
|
order: v.number()
|
|
}).index('by_pending_generation_id', ['pendingGenerationId']),
|
|
|
|
messageImages: defineTable({
|
|
messageId: v.id('messages'),
|
|
base64: v.string(),
|
|
mediaType: v.string(),
|
|
order: v.number()
|
|
}).index('by_message_id', ['messageId']),
|
|
|
|
devicePairings: defineTable({
|
|
chatId: v.id('chats'),
|
|
deviceId: v.string(),
|
|
hasCamera: v.boolean(),
|
|
pairedWithDeviceId: v.optional(v.string()),
|
|
lastSeen: v.number()
|
|
}).index('by_chat_id', ['chatId']),
|
|
|
|
pairingRequests: defineTable({
|
|
chatId: v.id('chats'),
|
|
fromDeviceId: v.string(),
|
|
status: v.union(v.literal('pending'), v.literal('accepted'), v.literal('rejected')),
|
|
createdAt: v.number()
|
|
}).index('by_chat_id', ['chatId']),
|
|
|
|
photoRequests: defineTable({
|
|
chatId: v.id('chats'),
|
|
requesterId: v.string(),
|
|
captureDeviceId: v.optional(v.string()),
|
|
status: v.union(
|
|
v.literal('pending'),
|
|
v.literal('countdown'),
|
|
v.literal('capture_now'),
|
|
v.literal('captured'),
|
|
v.literal('accepted'),
|
|
v.literal('rejected')
|
|
),
|
|
photoBase64: v.optional(v.string()),
|
|
photoMediaType: v.optional(v.string()),
|
|
thumbnailBase64: v.optional(v.string()),
|
|
createdAt: v.number()
|
|
}).index('by_chat_id', ['chatId']),
|
|
|
|
photoDrafts: defineTable({
|
|
chatId: v.id('chats'),
|
|
deviceId: v.string(),
|
|
base64: v.string(),
|
|
mediaType: v.string(),
|
|
createdAt: v.number()
|
|
}).index('by_chat_id_and_device_id', ['chatId', 'deviceId']),
|
|
|
|
ragDatabases: defineTable({
|
|
userId: v.id('users'),
|
|
name: v.string(),
|
|
createdAt: v.number()
|
|
})
|
|
.index('by_user_id', ['userId'])
|
|
.index('by_user_id_and_name', ['userId', 'name']),
|
|
|
|
ragConnections: defineTable({
|
|
userId: v.id('users'),
|
|
ragDatabaseId: v.id('ragDatabases'),
|
|
isGlobal: v.boolean(),
|
|
createdAt: v.number()
|
|
})
|
|
.index('by_user_id', ['userId'])
|
|
.index('by_user_id_and_rag_database_id', ['userId', 'ragDatabaseId'])
|
|
.index('by_rag_database_id', ['ragDatabaseId'])
|
|
});
|