import { and, eq } from 'drizzle-orm'; import { drizzle } from 'drizzle-orm/bun-sqlite'; import type { CompanyAnalysis } from '@/lib/types'; import { getSqliteClient } from '@/lib/server/db'; import { companyOverviewCache, schema } from '@/lib/server/db/schema'; export const CURRENT_COMPANY_OVERVIEW_CACHE_VERSION = 1; type CompanyOverviewCacheRecord = { id: number; user_id: string; ticker: string; cache_version: number; source_signature: string; payload: CompanyAnalysis; created_at: string; updated_at: string; }; function toRecord(row: typeof companyOverviewCache.$inferSelect): CompanyOverviewCacheRecord { return { id: row.id, user_id: row.user_id, ticker: row.ticker, cache_version: row.cache_version, source_signature: row.source_signature, payload: row.payload as CompanyAnalysis, created_at: row.created_at, updated_at: row.updated_at }; } function getDb() { return drizzle(getSqliteClient(), { schema }); } export async function getCompanyOverviewCache(input: { userId: string; ticker: string }) { const normalizedTicker = input.ticker.trim().toUpperCase(); if (!normalizedTicker) { return null; } const [row] = await getDb() .select() .from(companyOverviewCache) .where(and( eq(companyOverviewCache.user_id, input.userId), eq(companyOverviewCache.ticker, normalizedTicker) )) .limit(1); return row ? toRecord(row) : null; } export async function upsertCompanyOverviewCache(input: { userId: string; ticker: string; sourceSignature: string; payload: CompanyAnalysis; }) { const now = new Date().toISOString(); const normalizedTicker = input.ticker.trim().toUpperCase(); const [saved] = await getDb() .insert(companyOverviewCache) .values({ user_id: input.userId, ticker: normalizedTicker, cache_version: CURRENT_COMPANY_OVERVIEW_CACHE_VERSION, source_signature: input.sourceSignature, payload: input.payload as unknown as Record, created_at: now, updated_at: now }) .onConflictDoUpdate({ target: [companyOverviewCache.user_id, companyOverviewCache.ticker], set: { cache_version: CURRENT_COMPANY_OVERVIEW_CACHE_VERSION, source_signature: input.sourceSignature, payload: input.payload as unknown as Record, updated_at: now } }) .returning(); return toRecord(saved); } async function deleteCompanyOverviewCache(input: { userId: string; ticker: string }) { const normalizedTicker = input.ticker.trim().toUpperCase(); return await getDb() .delete(companyOverviewCache) .where(and( eq(companyOverviewCache.user_id, input.userId), eq(companyOverviewCache.ticker, normalizedTicker) )); } const __companyOverviewCacheInternals = { CACHE_VERSION: CURRENT_COMPANY_OVERVIEW_CACHE_VERSION };