feat: Redis opportunity cache, CW API retry/logging, adaptive TTLs
- Add Redis-backed opportunity cache with background refresh (30s interval) - Fix concurrency bug: use lazy thunks instead of eager promises for batching - Add withCwRetry utility with exponential backoff for transient CW errors - Add adaptive TTL algorithms (primary, sub-resource, products) based on opportunity activity - Add include query param on GET /sales/opportunities/:id (notes,contacts,products) - Add opt-in CW API logger (LOG_CW_API env var) with timestamped files in cw-api-logs/ - Add debug-scripts/analyze-cw-calls.py for API call analysis - Add computeSubResourceCacheTTL and computeProductsCacheTTL algorithms with tests - Increase CW API timeout from 15s to 30s - Unblock cache refresh from startup chain (remove await) - Prioritize recently updated opportunities in refresh cycle - Add CACHING.md documentation - Update API_ROUTES.md with caching details and include param - Update copilot instructions to require CACHING.md sync - Add dev:log script for CW API call logging during development
This commit is contained in:
@@ -115,6 +115,24 @@ export const activityCw = {
|
||||
return activityCw.fetchAll(`opportunity/id=${opportunityId}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch Activities by Opportunity (Direct)
|
||||
*
|
||||
* Lightweight single-call variant that skips the count request.
|
||||
* Fetches up to 1000 activities in a single GET — sufficient for
|
||||
* virtually all opportunities. Used by the background cache refresh
|
||||
* to avoid doubling CW API calls.
|
||||
*/
|
||||
fetchByOpportunityDirect: async (
|
||||
opportunityId: number,
|
||||
): Promise<CWActivity[]> => {
|
||||
const conditions = encodeURIComponent(`opportunity/id=${opportunityId}`);
|
||||
const response = await connectWiseApi.get(
|
||||
`/sales/activities?pageSize=1000&conditions=${conditions}`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create Activity
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user