feat: add CW callback route and optimize cache refresh workflows

This commit is contained in:
2026-03-03 19:46:48 -06:00
parent 6d935e7180
commit a048e1e824
28 changed files with 3268 additions and 294 deletions
+23 -13
View File
@@ -15,7 +15,10 @@ import {
CWOpportunity,
CWOpportunityNote,
} from "../modules/cw-utils/opportunities/opportunity.types";
import { resolveMember } from "../modules/cw-utils/members/memberCache";
import {
resolveMember,
resolveMembers,
} from "../modules/cw-utils/members/memberCache";
import { ForecastProductController } from "./ForecastProductController";
import GenericError from "../Errors/GenericError";
import { computeSubResourceCacheTTL } from "../modules/algorithms/computeSubResourceCacheTTL";
@@ -429,18 +432,25 @@ export class OpportunityController {
/** Serialize raw CW note data into the API response shape. */
private async _serializeNotes(notes: any[]) {
return Promise.all(
notes.map(async (n: any) => ({
id: n.id,
text: n.text,
type: n.type ? { id: n.type.id, name: n.type.name } : null,
flagged: n.flagged,
dateEntered: n._info?.lastUpdated
? new Date(n._info.lastUpdated)
: null,
enteredBy: await resolveMember(n.enteredBy),
})),
);
// Batch-resolve all member identifiers in a single DB query
const identifiers = notes
.map((n: any) => n.enteredBy as string)
.filter(Boolean);
const memberMap = await resolveMembers(identifiers);
return notes.map((n: any) => ({
id: n.id,
text: n.text,
type: n.type ? { id: n.type.id, name: n.type.name } : null,
flagged: n.flagged,
dateEntered: n._info?.lastUpdated ? new Date(n._info.lastUpdated) : null,
enteredBy: memberMap.get(n.enteredBy) ?? {
id: null,
identifier: n.enteredBy,
name: n.enteredBy,
cwMemberId: null,
},
}));
}
/**