mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-05-18 20:08:19 +00:00
fix(call-attribution): resolve Ozonetel chain AgentNames to agent.id
Inbound transferred calls arrive with AgentName like 'RamaiahAdmin -> GlobalHealthX'. The webhook was persisting the raw chain string and leaving agentId null; the CDR enrichment cron then silently skipped 100% of rows because the bulk CDR keys on caller-leg UCID while the webhook stores monitorUCID — the join never matched. - missed-call-webhook: split chain on ' -> ', take final handler, resolve via AgentLookupService (ozonetelAgentId + display name) - cdr-enrichment: index CDR rows by both UCID and monitorUCID so the cron actually patches historical rows - enrichment also parses chain in CDR AgentName as a second fallback - spec: add CallerResolutionService + AgentLookupService mocks
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Controller, Post, Body, Headers, Logger } from '@nestjs/common';
|
||||
import { PlatformGraphqlService } from '../platform/platform-graphql.service';
|
||||
import { AgentLookupService } from '../platform/agent-lookup.service';
|
||||
import { CallerResolutionService } from '../caller/caller-resolution.service';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@@ -22,6 +23,7 @@ export class MissedCallWebhookController {
|
||||
private readonly platform: PlatformGraphqlService,
|
||||
private readonly config: ConfigService,
|
||||
private readonly caller: CallerResolutionService,
|
||||
private readonly agentLookup: AgentLookupService,
|
||||
) {
|
||||
this.apiKey = config.get<string>('platform.apiKey') ?? '';
|
||||
}
|
||||
@@ -197,6 +199,25 @@ export class MissedCallWebhookController {
|
||||
callData.recording = { primaryLinkUrl: data.recordingUrl, primaryLinkLabel: 'Recording' };
|
||||
}
|
||||
|
||||
// Resolve agent relation at write-time so the supervisor dashboard
|
||||
// can bucket the row immediately. Ozonetel sends transferred calls
|
||||
// with a chain-style AgentName like "RamaiahAdmin -> GlobalHealthX" —
|
||||
// the final handler is the last segment, so split on " -> " and
|
||||
// resolve that. Try both ozonetelAgentId (lowercase unique) and
|
||||
// ozonetelDisplayName (mixed-case human label) since Ozonetel mixes
|
||||
// formats across webhook payloads. Leaves agentId null on miss so
|
||||
// the cdr-enrichment cron can still attempt a match by UCID later.
|
||||
if (data.agentName) {
|
||||
const segments = data.agentName.split('->').map((s) => s.trim()).filter(Boolean);
|
||||
const finalHandler = segments[segments.length - 1];
|
||||
if (finalHandler) {
|
||||
const uuid =
|
||||
(await this.agentLookup.resolveByOzonetelId(finalHandler)) ??
|
||||
(await this.agentLookup.resolveByDisplayName(finalHandler));
|
||||
if (uuid) callData.agentId = uuid;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await this.platform.queryWithAuth<any>(
|
||||
`mutation($data: CallCreateInput!) { createCall(data: $data) { id } }`,
|
||||
{ data: callData },
|
||||
|
||||
Reference in New Issue
Block a user