import type { XiaobaoRiskSnapshot } from './xiaobao-risk-trend'; export interface XiaobaoRiskInsight { summary: string; why: string[]; forecast: string; recommendedReleaseWindow?: string; suggestedActions: string[]; ownerHints: string[]; generatedAt: string; } export interface XiaobaoRiskInsightCacheItem { versionId: string; riskSignature: string; insight: XiaobaoRiskInsight; generatedAt: string; providerInfo?: { providerId?: string; model?: string }; } export function findCachedInsight( rows: XiaobaoRiskInsightCacheItem[], versionId: string, riskSignature: string, ): XiaobaoRiskInsightCacheItem | undefined { return rows.find((row) => row.versionId === versionId && row.riskSignature === riskSignature); } export function upsertInsight( rows: XiaobaoRiskInsightCacheItem[], item: XiaobaoRiskInsightCacheItem, ): XiaobaoRiskInsightCacheItem[] { return [ item, ...rows.filter((row) => row.versionId !== item.versionId || row.riskSignature !== item.riskSignature), ]; } export function upsertDailySnapshot( rows: XiaobaoRiskSnapshot[], item: XiaobaoRiskSnapshot, ): XiaobaoRiskSnapshot[] { return [ item, ...rows.filter((row) => row.versionId !== item.versionId || row.date !== item.date), ]; } export function mergeDailySnapshotCacheForSave( localRows: XiaobaoRiskSnapshot[], remoteRows: XiaobaoRiskSnapshot[], item: XiaobaoRiskSnapshot, ): XiaobaoRiskSnapshot[] { const remoteKeys = new Set(remoteRows.map((row) => `${row.versionId}::${row.date}`)); const localOnly = localRows.filter((row) => !remoteKeys.has(`${row.versionId}::${row.date}`)); return upsertDailySnapshot([...remoteRows, ...localOnly], item); } export function mergeInsightCacheForSave( localRows: XiaobaoRiskInsightCacheItem[], remoteRows: XiaobaoRiskInsightCacheItem[], item: XiaobaoRiskInsightCacheItem, ): XiaobaoRiskInsightCacheItem[] { const remoteKeys = new Set(remoteRows.map((row) => `${row.versionId}::${row.riskSignature}`)); const localOnly = localRows.filter((row) => !remoteKeys.has(`${row.versionId}::${row.riskSignature}`)); return upsertInsight([...remoteRows, ...localOnly], item); }