5 Commits

Author SHA1 Message Date
34eae1c19a merge: hardening/apr-week2 → master (v0.13-ai-coaching)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
AI coaching pipeline + sidecar hardening.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 12:47:37 +05:30
Kartik Datrika
1dd8413297 Revert "AI Summary not showing appointments fix."
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This reverts commit 973614749b.
2026-04-16 14:54:20 +05:30
Kartik Datrika
7d8424b446 Revert "AI Summary not showing appointments fix."
This reverts commit 55b8680923.
2026-04-16 14:54:17 +05:30
Kartik Datrika
55b8680923 AI Summary not showing appointments fix. 2026-04-16 12:50:33 +05:30
Kartik Datrika
973614749b AI Summary not showing appointments fix. 2026-04-16 11:36:10 +05:30

View File

@@ -89,8 +89,8 @@ export class CallerContextService {
private async build(leadId: string, patientId: string, auth: string): Promise<CallerContext | null> { private async build(leadId: string, patientId: string, auth: string): Promise<CallerContext | null> {
try { try {
// Step 1: Fetch lead first to get the authoritative patientId const [leadData, appointmentsData, callsData, activitiesData] = await Promise.all([
const leadData = await this.platform.queryWithAuth<any>( this.platform.queryWithAuth<any>(
`{ lead(filter: { id: { eq: "${leadId}" } }) { `{ lead(filter: { id: { eq: "${leadId}" } }) {
id contactName { firstName lastName } id contactName { firstName lastName }
contactPhone { primaryPhoneNumber } contactPhone { primaryPhoneNumber }
@@ -99,24 +99,9 @@ export class CallerContextService {
utmCampaign patientId utmCampaign patientId
} }`, } }`,
undefined, auth, undefined, auth,
); ),
patientId ? this.platform.queryWithAuth<any>(
const lead = leadData?.lead; `{ appointments(first: 10, filter: { patientId: { eq: "${patientId}" } }, orderBy: [{ scheduledAt: DescNullsLast }]) { edges { node {
if (!lead) return null;
// Use Lead's patientId as authoritative source — the input
// param may be empty if caller resolution just linked them.
const resolvedPatientId = patientId || lead.patientId || '';
this.logger.log(`[CALLER-CTX] Resolved patientId=${resolvedPatientId} (input=${patientId}, lead=${lead.patientId ?? '∅'})`);
const firstName = lead.contactName?.firstName ?? '';
const lastName = lead.contactName?.lastName ?? '';
// Step 2: Fetch appointments, calls, activities in parallel
// using the resolved patientId from the Lead record.
const [appointmentsData, callsData, activitiesData] = await Promise.all([
resolvedPatientId ? this.platform.queryWithAuth<any>(
`{ appointments(first: 10, filter: { patientId: { eq: "${resolvedPatientId}" } }, orderBy: [{ scheduledAt: DescNullsLast }]) { edges { node {
scheduledAt status doctorName department reasonForVisit scheduledAt status doctorName department reasonForVisit
} } } }`, } } } }`,
undefined, auth, undefined, auth,
@@ -135,6 +120,12 @@ export class CallerContextService {
), ),
]); ]);
const lead = leadData?.lead;
if (!lead) return null;
const firstName = lead.contactName?.firstName ?? '';
const lastName = lead.contactName?.lastName ?? '';
const appointments = (appointmentsData?.appointments?.edges ?? []).map((e: any) => e.node); const appointments = (appointmentsData?.appointments?.edges ?? []).map((e: any) => e.node);
const calls = (callsData?.calls?.edges ?? []).map((e: any) => ({ const calls = (callsData?.calls?.edges ?? []).map((e: any) => ({
startedAt: e.node.startedAt, startedAt: e.node.startedAt,
@@ -157,7 +148,7 @@ export class CallerContextService {
return { return {
leadId, leadId,
patientId: resolvedPatientId, patientId: patientId || lead.patientId || '',
name: `${firstName} ${lastName}`.trim() || 'Unknown', name: `${firstName} ${lastName}`.trim() || 'Unknown',
phone: lead.contactPhone?.primaryPhoneNumber ?? '', phone: lead.contactPhone?.primaryPhoneNumber ?? '',
isNew: false, isNew: false,