Files
optima/api/src/modules/algorithms/computeSubResourceCacheTTL.ts
T
2026-04-08 01:02:45 +00:00

58 lines
1.6 KiB
TypeScript

/**
* computeSubResourceCacheTTL
*
* Computes the Redis TTL (in milliseconds) for opportunity sub-resources
* (notes, contacts, activities, etc.) that share the parent opportunity's
* activity window.
*
* Rules are identical to the main opportunity TTL but use different
* exported constant names so callers can distinguish them.
*/
export const SUB_TTL_HIGH_ACTIVITY = 60_000; // 60 seconds
export const SUB_TTL_MODERATE_ACTIVITY = 120_000; // 2 minutes
export const SUB_TTL_LOW_ACTIVITY = 300_000; // 5 minutes
export interface ComputeSubResourceCacheTTLInput {
closedFlag: boolean;
closedDate: Date | null;
expectedCloseDate: Date | null;
lastUpdated: Date | null;
now?: Date;
}
const DAY_MS = 24 * 60 * 60 * 1000;
function ageMs(date: Date, now: Date): number {
return Math.abs(now.getTime() - date.getTime());
}
export function computeSubResourceCacheTTL(
input: ComputeSubResourceCacheTTLInput
): number | null {
const now = input.now ?? new Date();
// Rule 1a — closed > 30 days → no cache
if (input.closedFlag) {
if (!input.closedDate) return null;
const daysClosed = ageMs(input.closedDate, now) / DAY_MS;
if (daysClosed > 30) return null;
return SUB_TTL_LOW_ACTIVITY;
}
const dates = [input.lastUpdated, input.expectedCloseDate].filter(
(d): d is Date => d !== null
);
if (dates.length === 0) {
return SUB_TTL_LOW_ACTIVITY;
}
const minDeltaDays =
Math.min(...dates.map((d) => ageMs(d, now))) / DAY_MS;
if (minDeltaDays <= 5) return SUB_TTL_HIGH_ACTIVITY;
if (minDeltaDays <= 14) return SUB_TTL_MODERATE_ACTIVITY;
return SUB_TTL_LOW_ACTIVITY;
}