perf: build case-issue map once in stale-case-reminder; add idempotency TODO
- Hoist issues.list() loop outside stale-cases loop — reduces RPCs from O(cases × companies × issues) to O(companies × issues) - Add TODO comment for requestId-based idempotency guard in onWebhook Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -722,34 +722,35 @@ const plugin = definePlugin({
|
||||
total: number;
|
||||
};
|
||||
|
||||
let reminded = 0;
|
||||
// Build case→issue map once (O(companies × issues)) to avoid N×M RPCs per stale case
|
||||
const companies = await ctx.companies.list();
|
||||
for (const staleCase of data.cases) {
|
||||
const caseIssueMap = new Map<string, { issueId: string; companyId: string }>();
|
||||
for (const company of companies) {
|
||||
const issues = await ctx.issues.list({ companyId: company.id });
|
||||
let linkedIssueId: string | null = null;
|
||||
for (const issue of issues) {
|
||||
const linkedCase = await ctx.state.get({
|
||||
scopeKind: "issue",
|
||||
scopeId: issue.id,
|
||||
stateKey: "legal-case-number",
|
||||
});
|
||||
if (linkedCase === staleCase.case_number) {
|
||||
linkedIssueId = issue.id;
|
||||
break;
|
||||
if (linkedCase && typeof linkedCase === "string") {
|
||||
caseIssueMap.set(linkedCase, { issueId: issue.id, companyId: company.id });
|
||||
}
|
||||
}
|
||||
if (!linkedIssueId) continue;
|
||||
}
|
||||
|
||||
let reminded = 0;
|
||||
for (const staleCase of data.cases) {
|
||||
const linked = caseIssueMap.get(staleCase.case_number);
|
||||
if (!linked) continue;
|
||||
|
||||
await ctx.issues.createComment(
|
||||
linkedIssueId,
|
||||
linked.issueId,
|
||||
`⚠️ **תיק תקוע ${staleCase.case_number}** — ${staleCase.days_stale} ימים ללא עדכון (סטטוס: ${staleCase.status}). האם נדרשת פעולה?`,
|
||||
company.id,
|
||||
linked.companyId,
|
||||
);
|
||||
reminded++;
|
||||
ctx.logger.info(`stale-case-reminder: reminded case ${staleCase.case_number} (${staleCase.days_stale}d)`);
|
||||
break; // Found the company, move to next case
|
||||
}
|
||||
}
|
||||
|
||||
ctx.logger.info(`stale-case-reminder: done. ${reminded}/${data.total} cases reminded`);
|
||||
@@ -801,6 +802,9 @@ const plugin = definePlugin({
|
||||
async onWebhook(input: PluginWebhookInput): Promise<void> {
|
||||
if (!pluginCtx) return; // not yet initialized
|
||||
|
||||
// TODO: add idempotency guard using input.requestId to prevent duplicate
|
||||
// comments on rapid retries (store requestId in plugin state with ~60s TTL)
|
||||
|
||||
const { endpointKey, parsedBody } = input;
|
||||
|
||||
if (endpointKey !== "case-status") return;
|
||||
|
||||
Reference in New Issue
Block a user