Files
ftb-project-management/apps/web/lib/xiaobao-risk-cache.ts
2026-06-29 18:44:59 +08:00

68 lines
2.1 KiB
TypeScript

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);
}