fix(messaging): generate hourly slots from visitSlots day-of-week data

Was reading non-existent availableSlots field. Now reads raw visitSlots,
matches target date's day-of-week, and generates hourly time slots from
startTime to endTime. Doctors with 08:00-20:00 get 10 hourly options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-20 15:19:09 +05:30
parent 8aae95e8cc
commit b1922809d0

View File

@@ -251,7 +251,10 @@ ${callerContext ? `\n${callerContext}` : ''}`;
date: z.string().optional().describe('Date in YYYY-MM-DD. Defaults to tomorrow.'), date: z.string().optional().describe('Date in YYYY-MM-DD. Defaults to tomorrow.'),
}), }),
execute: async ({ doctorId, doctorName, date }) => { execute: async ({ doctorId, doctorName, date }) => {
// Default to tomorrow, use IST for day-of-week matching
const targetDate = date ?? new Date(Date.now() + 86400000).toISOString().split('T')[0]; const targetDate = date ?? new Date(Date.now() + 86400000).toISOString().split('T')[0];
const dayNames = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'];
const targetDay = dayNames[new Date(targetDate + 'T00:00:00+05:30').getDay()];
const data = await platform.query<any>( const data = await platform.query<any>(
`{ doctors(first: 50) { edges { node { `{ doctors(first: 50) { edges { node {
@@ -259,25 +262,46 @@ ${callerContext ? `\n${callerContext}` : ''}`;
${DOCTOR_VISIT_SLOTS_FRAGMENT} ${DOCTOR_VISIT_SLOTS_FRAGMENT}
} } } }`, } } } }`,
); );
const allDocs = normalizeDoctors(data.doctors.edges.map((e: any) => e.node)); const rawDocs = data.doctors.edges.map((e: any) => e.node);
const doctor = allDocs.find((d: any) => d.id === doctorId); const doctor = rawDocs.find((d: any) => d.id === doctorId);
const slots = doctor?.availableSlots ?? []; if (!doctor) {
return { sent: false, message: `Doctor not found.` };
}
if (!slots.length) { // Find visit slots for the target day-of-week
const rawSlots = doctor.visitSlots?.edges?.map((e: any) => e.node) ?? [];
const daySlots = rawSlots.filter((s: any) => s.dayOfWeek === targetDay);
if (!daySlots.length) {
return { sent: false, message: `${doctorName} is not available on ${targetDay.charAt(0) + targetDay.slice(1).toLowerCase()} (${targetDate}). Please choose a different date.` };
}
// Generate hourly time slots from startTime-endTime
const timeSlots: { time: string; clinic: string }[] = [];
for (const ds of daySlots) {
const startHour = parseInt(ds.startTime?.split(':')[0] ?? '9', 10);
const endHour = parseInt(ds.endTime?.split(':')[0] ?? '17', 10);
const clinicName = ds.clinic?.clinicName ?? '';
for (let h = startHour; h < endHour && timeSlots.length < 10; h++) {
timeSlots.push({ time: `${String(h).padStart(2, '0')}:00`, clinic: clinicName });
}
}
if (!timeSlots.length) {
return { sent: false, message: `No slots available for ${doctorName} on ${targetDate}.` }; return { sent: false, message: `No slots available for ${doctorName} on ${targetDate}.` };
} }
const sections: ListSection[] = [{ const sections: ListSection[] = [{
title: `${doctorName}${targetDate}`, title: `${doctorName}${targetDate}`,
rows: slots.slice(0, 10).map((s: any) => ({ rows: timeSlots.map((s) => ({
id: `slot:${doctorId}:${targetDate}T${s.time}:00`, id: `slot:${doctorId}:${targetDate}T${s.time}:00`,
title: s.time, title: s.time,
description: s.clinic ?? '', description: s.clinic,
})), })),
}]; }];
await provider.sendList(phone, `Available slots for ${doctorName}:`, 'View Slots', sections); await provider.sendList(phone, `Available slots for ${doctorName}:`, 'View Slots', sections);
logger.log(`[WA-TOOL] send_slot_list: ${slots.length} slots for ${doctorName}`); logger.log(`[WA-TOOL] send_slot_list: ${timeSlots.length} slots for ${doctorName} on ${targetDate} (${targetDay})`);
return { sent: true, slots: slots.length }; return { sent: true, slots: timeSlots.length };
}, },
}), }),