Files
clinera-site/test-immediate-booking-confirmation.js

288 lines
12 KiB
JavaScript

// Test immediate booking confirmation when appointment is created
const { PrismaClient } = require('@prisma/client');
const crypto = require('crypto');
const prisma = new PrismaClient();
async function testImmediateBookingConfirmation() {
console.log('📋 TESTING IMMEDIATE BOOKING CONFIRMATION WORKFLOW');
console.log('='.repeat(60));
console.log('🎯 This simulates exactly what happens when you create an appointment in the UI');
console.log('');
try {
// 1. Get system components
console.log('1️⃣ Setting up test environment...');
const clinic = await prisma.clinic.findFirst();
const obaidLead = await prisma.lead.findFirst({
where: { phone: '+201066544750' }
});
const treatment = await prisma.treatment.findFirst({
where: { clinicId: clinic.id, isActive: true }
});
if (!obaidLead) {
console.log('❌ Obaid lead not found!');
return;
}
console.log(` ✅ Clinic: ${clinic.name}`);
console.log(` ✅ Patient: ${obaidLead.name} (${obaidLead.phone})`);
console.log(` ✅ Treatment: ${treatment.name}`);
console.log(` ✅ Quiet hours: ${clinic.quietHoursStart}:00 - ${clinic.quietHoursEnd}:00`);
// 2. Check current time vs quiet hours
const now = new Date();
const currentHour = parseInt(
new Intl.DateTimeFormat("en-US", {
timeZone: clinic.timezone,
hour: "numeric",
hour12: false
}).format(now)
);
const inQuietHours = currentHour >= clinic.quietHoursStart && currentHour < clinic.quietHoursEnd;
console.log(` ✅ Current time: ${now.toLocaleTimeString()} (hour: ${currentHour})`);
console.log(` ✅ In quiet hours: ${inQuietHours ? 'YES' : 'NO'} - ${inQuietHours ? 'messages will be delayed' : 'messages will send immediately'}`);
// 3. Check booking confirmation template
const bookingTemplate = await prisma.reminderTemplate.findFirst({
where: {
clinicId: clinic.id,
trigger: 'booking_confirmed',
isActive: true
}
});
if (!bookingTemplate) {
console.log('❌ No active booking confirmation template found!');
return;
}
console.log(` ✅ Booking template found: "${bookingTemplate.message.substr(0, 50)}..."`);
console.log(` ✅ Template offset: ${bookingTemplate.offsetMinutes} minutes (should be 0 for immediate)`);
// 4. Get baseline counts
const beforeCounts = {
appointments: await prisma.appointment.count(),
reminders: await prisma.scheduledReminder.count(),
messages: await prisma.messageLog.count({ where: { phone: '+201066544750' } })
};
console.log('\n2️⃣ Baseline counts:');
console.log(` Appointments: ${beforeCounts.appointments}`);
console.log(` Reminders: ${beforeCounts.reminders}`);
console.log(` Messages to obaid: ${beforeCounts.messages}`);
// 5. Simulate exact UI appointment creation workflow
console.log('\n3️⃣ Creating appointment (simulating UI workflow)...');
// Create appointment exactly like the UI does
const appointmentTime = new Date();
appointmentTime.setDate(appointmentTime.getDate() + 1);
appointmentTime.setHours(14, 30, 0, 0); // Tomorrow 2:30 PM
const appointmentData = {
clinicId: clinic.id,
leadId: obaidLead.id,
treatmentId: treatment.id,
dateTime: appointmentTime,
status: 'scheduled',
confirmToken: crypto.randomBytes(32).toString('hex'),
notes: 'UI workflow test - booking confirmation should be immediate'
};
console.log(` Creating appointment for: ${appointmentTime.toLocaleString()}`);
const appointment = await prisma.appointment.create({
data: appointmentData,
include: { lead: true, treatment: true, clinic: true }
});
console.log(` ✅ Appointment created: ${appointment.id}`);
// 6. Call scheduleReminders exactly like the API does
console.log('\n4️⃣ Calling scheduleReminders function (like API does)...');
try {
// Import and call the actual scheduleReminders function
const { scheduleReminders } = require('./src/lib/reminders');
await scheduleReminders(appointment.id);
console.log(' ✅ scheduleReminders completed successfully');
} catch (scheduleError) {
console.log(` ❌ scheduleReminders failed: ${scheduleError.message}`);
// Fallback: manually schedule booking confirmation
console.log(' 🔧 Manually scheduling booking confirmation...');
let scheduledFor = new Date(Date.now() + 5000); // 5 seconds from now
// Apply quiet hours logic manually if needed
if (inQuietHours) {
console.log(' ⚠️ Adjusting for quiet hours...');
const nextDay = new Date(scheduledFor);
nextDay.setDate(nextDay.getDate() + 1);
nextDay.setHours(clinic.quietHoursEnd, 0, 0, 0);
scheduledFor = nextDay;
console.log(` 📅 Rescheduled to: ${scheduledFor.toLocaleString()}`);
}
await prisma.scheduledReminder.create({
data: {
appointmentId: appointment.id,
templateId: bookingTemplate.id,
scheduledFor: scheduledFor,
},
});
console.log(' ✅ Booking confirmation manually scheduled');
}
// 7. Check what was created
console.log('\n5️⃣ Checking scheduled reminders...');
const scheduledReminders = await prisma.scheduledReminder.findMany({
where: { appointmentId: appointment.id },
include: { template: true },
orderBy: { scheduledFor: 'asc' }
});
console.log(` 📅 Reminders scheduled: ${scheduledReminders.length}`);
const bookingReminder = scheduledReminders.find(r => r.template.trigger === 'booking_confirmed');
if (bookingReminder) {
const timeDiff = new Date(bookingReminder.scheduledFor).getTime() - Date.now();
const secondsUntil = Math.round(timeDiff / 1000);
console.log(` ✅ Booking confirmation found:`);
console.log(` Template: ${bookingReminder.template.trigger}`);
console.log(` Scheduled: ${bookingReminder.scheduledFor}`);
console.log(` Status: ${bookingReminder.status}`);
console.log(` Time until send: ${secondsUntil} seconds`);
if (secondsUntil <= 60) {
console.log(' 🎉 PERFECT! Booking confirmation will send within 1 minute');
} else {
console.log(` ⚠️ DELAYED: Booking confirmation delayed by ${Math.round(secondsUntil / 60)} minutes`);
}
// 8. Wait and trigger cron to send the reminder
if (secondsUntil <= 120) { // Only wait if it's within 2 minutes
console.log('\n6️⃣ Waiting for reminder to be due, then sending...');
const waitTime = Math.max(secondsUntil + 2, 5); // Wait until due + 2 seconds, minimum 5 seconds
console.log(` ⏳ Waiting ${waitTime} seconds...`);
for (let i = waitTime; i > 0; i--) {
process.stdout.write(`\r${i}s remaining...`);
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log('\n 📤 Triggering cron to send reminder...');
const cronResponse = await fetch('http://localhost:3000/api/cron/send-reminders?key=dev-cron-key', {
method: 'POST'
});
if (cronResponse.ok) {
const cronResult = await cronResponse.json();
console.log(` ✅ Cron result: sent=${cronResult.sent}, failed=${cronResult.failed}, skipped=${cronResult.skipped}`);
if (cronResult.sent > 0) {
console.log(' 🎉 BOOKING CONFIRMATION SENT SUCCESSFULLY!');
// Check the message log
await new Promise(resolve => setTimeout(resolve, 2000));
const sentMessage = await prisma.messageLog.findFirst({
where: {
appointmentId: appointment.id,
phone: '+201066544750'
},
orderBy: { createdAt: 'desc' }
});
if (sentMessage) {
console.log(' 📱 Message details:');
console.log(` Status: ${sentMessage.status}`);
console.log(` Sent at: ${sentMessage.sentAt}`);
console.log(` WAHA ID: ${sentMessage.wahaMessageId}`);
console.log(` Preview: "${sentMessage.message.substr(0, 60)}..."`);
}
} else if (cronResult.failed > 0) {
console.log(' ❌ BOOKING CONFIRMATION FAILED TO SEND');
} else {
console.log(' ⚠️ No reminders processed (not due yet or other issue)');
}
} else {
console.log(' ❌ Cron endpoint failed');
}
} else {
console.log('\n6️⃣ Booking confirmation is delayed too long to test now');
console.log(` ⏰ Will be sent at: ${bookingReminder.scheduledFor}`);
}
} else {
console.log(' ❌ NO BOOKING CONFIRMATION REMINDER SCHEDULED!');
console.log(' 🔧 This is the problem - the scheduleReminders function is not working');
}
// 9. Final verification
console.log('\n7️⃣ Final verification...');
const afterCounts = {
appointments: await prisma.appointment.count(),
reminders: await prisma.scheduledReminder.count(),
messages: await prisma.messageLog.count({ where: { phone: '+201066544750' } })
};
console.log(` Appointments: ${beforeCounts.appointments}${afterCounts.appointments} (+${afterCounts.appointments - beforeCounts.appointments})`);
console.log(` Reminders: ${beforeCounts.reminders}${afterCounts.reminders} (+${afterCounts.reminders - beforeCounts.reminders})`);
console.log(` Messages to obaid: ${beforeCounts.messages}${afterCounts.messages} (+${afterCounts.messages - beforeCounts.messages})`);
console.log('\n🎯 TEST RESULTS:');
console.log('='.repeat(40));
if (afterCounts.appointments > beforeCounts.appointments &&
afterCounts.reminders > beforeCounts.reminders &&
afterCounts.messages > beforeCounts.messages) {
console.log('🎉 SUCCESS! Complete workflow working:');
console.log(' ✅ Appointment created');
console.log(' ✅ Reminder scheduled');
console.log(' ✅ Message sent');
console.log('');
console.log('📱 OBAID - Check your WhatsApp (+201066544750)!');
console.log(' You should see the booking confirmation message');
console.log('');
console.log('🚀 The system will work the same when you create appointments in the UI!');
} else if (afterCounts.appointments > beforeCounts.appointments &&
afterCounts.reminders > beforeCounts.reminders) {
console.log('🟡 PARTIAL SUCCESS:');
console.log(' ✅ Appointment created');
console.log(' ✅ Reminder scheduled');
console.log(' ⚠️ Message not sent yet (timing or quiet hours)');
console.log('');
console.log(' The message will be sent when the cron runs next');
} else {
console.log('❌ ISSUE DETECTED:');
console.log(' ✅ Appointment created');
if (afterCounts.reminders <= beforeCounts.reminders) {
console.log(' ❌ Reminder NOT scheduled - scheduleReminders function issue');
}
if (afterCounts.messages <= beforeCounts.messages) {
console.log(' ❌ Message NOT sent - cron or WAHA issue');
}
}
} catch (error) {
console.error('❌ Test failed:', error);
} finally {
await prisma.$disconnect();
}
}
testImmediateBookingConfirmation().catch(console.error);