fix: restore voice call replay dedupe keys

This commit is contained in:
Tak Hoffman
2026-04-10 19:08:47 -05:00
parent 5ed410b79e
commit 6504087b97
2 changed files with 36 additions and 3 deletions

View File

@@ -107,4 +107,37 @@ describe("CallManager verification on restore", () => {
expect(activeCall.callId).toBe(call.callId);
expect(activeCall.state).toBe(call.state);
});
it("restores dedupe keys from terminal persisted calls so replayed webhooks stay ignored", async () => {
const storePath = createTestStorePath();
const persisted = makePersistedCall({
state: "completed",
endedAt: Date.now() - 5_000,
endReason: "completed",
processedEventIds: ["evt-terminal-init"],
});
writeCallsToStore(storePath, [persisted]);
const provider = new FakeProvider();
const config = VoiceCallConfigSchema.parse({
enabled: true,
provider: "plivo",
fromNumber: "+15550000000",
});
const manager = new CallManager(config, storePath);
await manager.initialize(provider, "https://example.com/voice/webhook");
manager.processEvent({
id: "evt-terminal-init",
type: "call.initiated",
callId: String(persisted.providerCallId),
providerCallId: String(persisted.providerCallId),
timestamp: Date.now(),
direction: "outbound",
from: "+15550000000",
to: "+15550000001",
});
expect(manager.getActiveCalls()).toHaveLength(0);
});
});

View File

@@ -50,6 +50,9 @@ export function loadActiveCallsFromStore(storePath: string): {
const rejectedProviderCallIds = new Set<string>();
for (const [callId, call] of callMap) {
for (const eventId of call.processedEventIds) {
processedEventIds.add(eventId);
}
if (TerminalStates.has(call.state)) {
continue;
}
@@ -57,9 +60,6 @@ export function loadActiveCallsFromStore(storePath: string): {
if (call.providerCallId) {
providerCallIdMap.set(call.providerCallId, callId);
}
for (const eventId of call.processedEventIds) {
processedEventIds.add(eventId);
}
}
return { activeCalls, providerCallIdMap, processedEventIds, rejectedProviderCallIds };