|
import { pgTable, text, serial, integer, boolean, timestamp, real, jsonb } from "drizzle-orm/pg-core"; |
|
import { createInsertSchema } from "drizzle-zod"; |
|
import { z } from "zod"; |
|
|
|
export const documents = pgTable("documents", { |
|
id: serial("id").primaryKey(), |
|
title: text("title").notNull(), |
|
content: text("content").notNull(), |
|
source: text("source").notNull(), |
|
sourceType: text("source_type").notNull(), |
|
url: text("url"), |
|
metadata: jsonb("metadata"), |
|
embedding: text("embedding"), |
|
createdAt: timestamp("created_at").defaultNow().notNull(), |
|
}); |
|
|
|
export const searchQueries = pgTable("search_queries", { |
|
id: serial("id").primaryKey(), |
|
query: text("query").notNull(), |
|
searchType: text("search_type").notNull().default("semantic"), |
|
filters: jsonb("filters"), |
|
resultsCount: integer("results_count").default(0), |
|
searchTime: real("search_time"), |
|
createdAt: timestamp("created_at").defaultNow().notNull(), |
|
}); |
|
|
|
export const searchResults = pgTable("search_results", { |
|
id: serial("id").primaryKey(), |
|
queryId: integer("query_id").references(() => searchQueries.id).notNull(), |
|
documentId: integer("document_id").references(() => documents.id).notNull(), |
|
relevanceScore: real("relevance_score").notNull(), |
|
snippet: text("snippet").notNull(), |
|
rank: integer("rank").notNull(), |
|
}); |
|
|
|
export const citations = pgTable("citations", { |
|
id: serial("id").primaryKey(), |
|
documentId: integer("document_id").references(() => documents.id).notNull(), |
|
citationText: text("citation_text").notNull(), |
|
pageNumber: integer("page_number"), |
|
section: text("section"), |
|
createdAt: timestamp("created_at").defaultNow().notNull(), |
|
}); |
|
|
|
|
|
export const insertDocumentSchema = createInsertSchema(documents).omit({ |
|
id: true, |
|
createdAt: true, |
|
}); |
|
|
|
export const insertSearchQuerySchema = createInsertSchema(searchQueries).omit({ |
|
id: true, |
|
createdAt: true, |
|
}); |
|
|
|
export const insertSearchResultSchema = createInsertSchema(searchResults).omit({ |
|
id: true, |
|
}); |
|
|
|
export const insertCitationSchema = createInsertSchema(citations).omit({ |
|
id: true, |
|
createdAt: true, |
|
}); |
|
|
|
|
|
export type Document = typeof documents.$inferSelect; |
|
export type InsertDocument = z.infer<typeof insertDocumentSchema>; |
|
|
|
export type SearchQuery = typeof searchQueries.$inferSelect; |
|
export type InsertSearchQuery = z.infer<typeof insertSearchQuerySchema>; |
|
|
|
export type SearchResult = typeof searchResults.$inferSelect; |
|
export type InsertSearchResult = z.infer<typeof insertSearchResultSchema>; |
|
|
|
export type Citation = typeof citations.$inferSelect; |
|
export type InsertCitation = z.infer<typeof insertCitationSchema>; |
|
|
|
|
|
export const searchRequestSchema = z.object({ |
|
query: z.string().min(1), |
|
searchType: z.enum(["semantic", "keyword", "hybrid"]).default("semantic"), |
|
filters: z.object({ |
|
sourceTypes: z.array(z.string()).optional(), |
|
dateRange: z.object({ |
|
start: z.string().optional(), |
|
end: z.string().optional(), |
|
}).optional(), |
|
}).optional(), |
|
limit: z.number().min(1).max(50).default(10), |
|
offset: z.number().min(0).default(0), |
|
}); |
|
|
|
export type SearchRequest = z.infer<typeof searchRequestSchema>; |
|
|
|
export interface SearchResponse { |
|
results: Array<Document & { |
|
relevanceScore: number; |
|
snippet: string; |
|
rank: number; |
|
}>; |
|
totalCount: number; |
|
searchTime: number; |
|
query: string; |
|
queryId: number; |
|
} |
|
|
|
export interface DocumentWithContext extends Document { |
|
relevanceScore: number; |
|
snippet: string; |
|
rank: number; |
|
additionalContext?: Array<{ |
|
text: string; |
|
section: string; |
|
pageNumber?: number; |
|
}>; |
|
} |
|
|