SPB Git

spb/vquant Public MIT

VibeQuant — AI-powered institutional-grade financial intelligence platform.

TypeScript 84.3% Python 11.7% JavaScript 1.6% CSS 1.5% HTML 0.7%
8.0 KB · 177 lines typescript
Raw Blame History
1/*2 * =============================================================================3 *  VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4 * -----------------------------------------------------------------------------5 *  File:      shared/schema.ts6 *7 *  Author:    Simon-Pierre Boucher8 *  Contact:   contact@spboucher.ai9 *  Website:   https://www.spboucher.ai10 *  Demo:      https://www.vquant.ai11 *  License:   MIT (see LICENSE)12 *13 *  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14 * =============================================================================15 */1617import { sql } from "drizzle-orm";18import { pgTable, text, varchar, timestamp, integer, real, vector } from "drizzle-orm/pg-core";19import { createInsertSchema } from "drizzle-zod";20import { z } from "zod";2122// Re-export shared API types23export type { SearchResult, ClaudeMessage, ClaudeToolCall, ClaudeToolResult, ChatRequest, ChatResponse, ConversationMessage } from "./types";2425// Users table with token-based authentication26export const users = pgTable("users", {27  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),28  displayName: text("display_name").notNull(),29  token: text("token").notNull().unique(),30  createdAt: timestamp("created_at").notNull().defaultNow(),31});3233// Crawled pages table - stores web content34export const crawledPages = pgTable("crawled_pages", {35  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),36  url: text("url").notNull().unique(),37  title: text("title").notNull(),38  content: text("content").notNull(),39  snippet: text("snippet"),40  favicon: text("favicon"),41  crawledAt: timestamp("crawled_at").notNull().defaultNow(),42});4344// Embeddings table - stores vector embeddings for semantic search45export const embeddings = pgTable("embeddings", {46  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),47  pageId: varchar("page_id").notNull().unique().references(() => crawledPages.id, { onDelete: "cascade" }),48  embedding: vector("embedding", { dimensions: 3072 }),49  tokenCount: integer("token_count").notNull(),50  createdAt: timestamp("created_at").notNull().defaultNow(),51});5253// Chat messages table - stores conversation history54export const messages = pgTable("messages", {55  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),56  sessionId: varchar("session_id").notNull(),57  role: text("role").notNull(),58  content: text("content").notNull(),59  sources: text("sources").array(),60  createdAt: timestamp("created_at").notNull().defaultNow(),61});6263// Shared reports table64export const sharedReports = pgTable("shared_reports", {65  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),66  shareId: varchar("share_id").notNull().unique(),67  question: text("question").notNull(),68  answer: text("answer").notNull(),69  toolResults: text("tool_results"),70  sources: text("sources"),71  customPythonFigures: text("custom_python_figures"),72  createdAt: timestamp("created_at").notNull().defaultNow(),73});7475// Conversation sessions table76export const conversationSessions = pgTable("conversation_sessions", {77  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),78  sessionId: varchar("session_id").notNull().unique(),79  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }),80  title: text("title").notNull(),81  messages: text("messages").notNull(),82  inputTokens: integer("input_tokens").default(0),83  outputTokens: integer("output_tokens").default(0),84  totalCost: real("total_cost").default(0),85  createdAt: timestamp("created_at").notNull().defaultNow(),86  updatedAt: timestamp("updated_at").notNull().defaultNow(),87});8889// Active users tracking90export const activeUsers = pgTable("active_users", {91  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),92  sessionId: varchar("session_id").notNull().unique(),93  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }),94  status: text("status").notNull().default("idle"),95  currentQuery: text("current_query"),96  lastHeartbeat: timestamp("last_heartbeat").notNull().defaultNow(),97  userAgent: text("user_agent"),98  ipAddress: text("ip_address"),99  createdAt: timestamp("created_at").notNull().defaultNow(),100});101102// Analytics metrics103export const analyticsMetrics = pgTable("analytics_metrics", {104  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),105  timestamp: timestamp("timestamp").notNull().defaultNow(),106  totalRequests: integer("total_requests").default(0),107  successfulRequests: integer("successful_requests").default(0),108  failedRequests: integer("failed_requests").default(0),109  activeUsers: integer("active_users").default(0),110  uniqueVisitors: integer("unique_visitors").default(0),111  averageResponseTime: real("average_response_time").default(0),112  peakResponseTime: real("peak_response_time").default(0),113  tokensGenerated: integer("tokens_generated").default(0),114  estimatedCost: real("estimated_cost").default(0),115  toolCallsCount: integer("tool_calls_count").default(0),116  pythonExecutions: integer("python_executions").default(0),117  searchQueries: integer("search_queries").default(0),118  errorCount: integer("error_count").default(0),119  errorRate: real("error_rate").default(0),120  periodType: text("period_type").notNull().default("minute"),121});122123// Request logs124export const requestLogs = pgTable("request_logs", {125  id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),126  sessionId: varchar("session_id").notNull(),127  userId: varchar("user_id").references(() => users.id, { onDelete: "cascade" }),128  query: text("query").notNull(),129  responseTime: real("response_time"),130  inputTokens: integer("input_tokens").default(0),131  outputTokens: integer("output_tokens").default(0),132  totalCost: real("total_cost").default(0),133  toolsCalled: text("tools_called"),134  status: text("status").notNull(),135  errorMessage: text("error_message"),136  timestamp: timestamp("timestamp").notNull().defaultNow(),137});138139// Zod schemas for validation140export const insertUserSchema = createInsertSchema(users).omit({ id: true, createdAt: true });141export const insertCrawledPageSchema = createInsertSchema(crawledPages).omit({ id: true, crawledAt: true });142export const insertEmbeddingSchema = createInsertSchema(embeddings).omit({ id: true, createdAt: true });143export const insertMessageSchema = createInsertSchema(messages).omit({ id: true, createdAt: true });144export const insertSharedReportSchema = createInsertSchema(sharedReports).omit({ id: true, createdAt: true });145export const insertConversationSessionSchema = createInsertSchema(conversationSessions).omit({ id: true, createdAt: true, updatedAt: true });146export const insertActiveUserSchema = createInsertSchema(activeUsers).omit({ id: true, createdAt: true });147export const insertAnalyticsMetricSchema = createInsertSchema(analyticsMetrics).omit({ id: true, timestamp: true });148export const insertRequestLogSchema = createInsertSchema(requestLogs).omit({ id: true, timestamp: true });149150// TypeScript types151export type User = typeof users.$inferSelect;152export type InsertUser = z.infer<typeof insertUserSchema>;153154export type CrawledPage = typeof crawledPages.$inferSelect;155export type InsertCrawledPage = z.infer<typeof insertCrawledPageSchema>;156157export type Embedding = typeof embeddings.$inferSelect;158export type InsertEmbedding = z.infer<typeof insertEmbeddingSchema>;159160export type Message = typeof messages.$inferSelect;161export type InsertMessage = z.infer<typeof insertMessageSchema>;162163export type SharedReport = typeof sharedReports.$inferSelect;164export type InsertSharedReport = z.infer<typeof insertSharedReportSchema>;165166export type ConversationSession = typeof conversationSessions.$inferSelect;167export type InsertConversationSession = z.infer<typeof insertConversationSessionSchema>;168169export type ActiveUser = typeof activeUsers.$inferSelect;170export type InsertActiveUser = z.infer<typeof insertActiveUserSchema>;171172export type AnalyticsMetric = typeof analyticsMetrics.$inferSelect;173export type InsertAnalyticsMetric = z.infer<typeof insertAnalyticsMetricSchema>;174175export type RequestLog = typeof requestLogs.$inferSelect;176export type InsertRequestLog = z.infer<typeof insertRequestLogSchema>;177