// Debug and fix the ACTUAL UI appointment workflow const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); async function debugRealUIWorkflow() { console.log('šŸ”„ DEBUGGING REAL UI WORKFLOW - FIX THIS SHIT'); console.log('='.repeat(60)); console.log('😤 Test messages work but UI appointments don\'t - let\'s fix this NOW'); console.log(''); // Monitor appointments in real-time let lastAppointmentCount = await prisma.appointment.count(); let monitoring = true; let checkCount = 0; console.log('šŸ‘€ MONITORING FOR NEW APPOINTMENTS FROM UI...'); console.log(`šŸ“Š Current appointment count: ${lastAppointmentCount}`); console.log(''); console.log('šŸŽÆ CREATE AN APPOINTMENT IN THE UI NOW - I\'LL CATCH IT'); console.log(''); const monitor = setInterval(async () => { try { checkCount++; const currentCount = await prisma.appointment.count(); if (currentCount > lastAppointmentCount) { console.log('\n🚨 NEW APPOINTMENT DETECTED FROM UI!'); // Get the latest appointment const latestAppointments = await prisma.appointment.findMany({ take: currentCount - lastAppointmentCount, orderBy: { createdAt: 'desc' }, include: { lead: true, treatment: true, clinic: true, scheduledReminders: { include: { template: true } } } }); for (const appointment of latestAppointments) { console.log('\nšŸ“‹ APPOINTMENT DETAILS:'); console.log(` ID: ${appointment.id}`); console.log(` Patient: ${appointment.lead.name}`); console.log(` Phone: ${appointment.lead.phone}`); console.log(` Treatment: ${appointment.treatment.name}`); console.log(` DateTime: ${appointment.dateTime}`); console.log(` Status: ${appointment.status}`); console.log(` Confirm Token: ${appointment.confirmToken ? 'YES' : 'NO'}`); console.log(` Clinic: ${appointment.clinic.name}`); console.log(` Created: ${appointment.createdAt}`); // Check reminders console.log(`\nšŸ“… SCHEDULED REMINDERS: ${appointment.scheduledReminders.length}`); if (appointment.scheduledReminders.length === 0) { console.log('āŒ NO REMINDERS SCHEDULED - THIS IS THE PROBLEM!'); console.log('šŸ”§ FIXING NOW...'); // Get active templates for this clinic const templates = await prisma.reminderTemplate.findMany({ where: { clinicId: appointment.clinicId, isActive: true } }); console.log(`šŸ“‹ Available templates: ${templates.length}`); if (templates.length === 0) { console.log('āŒ NO ACTIVE TEMPLATES! Creating basic one...'); const newTemplate = await prisma.reminderTemplate.create({ data: { clinicId: appointment.clinicId, trigger: 'booking_confirmed', offsetMinutes: 0, sortOrder: 1, isActive: true, message: `Hi {{name}}! āœ… Your {{treatment}} appointment at {{clinic}} is confirmed: šŸ“… {{date}} šŸ• {{time}} āœ… Tap here to confirm: {{confirmLink}} Thank you for choosing our clinic!` } }); console.log('āœ… Created booking confirmation template'); templates.push(newTemplate); } // Schedule booking confirmation immediately const bookingTemplate = templates.find(t => t.trigger === 'booking_confirmed'); if (bookingTemplate) { const reminder = await prisma.scheduledReminder.create({ data: { appointmentId: appointment.id, templateId: bookingTemplate.id, scheduledFor: new Date(Date.now() + 3000), // 3 seconds from now }, }); console.log(`āœ… FIXED: Scheduled booking confirmation for ${reminder.scheduledFor}`); // Schedule other reminders too for (const template of templates) { if (template.trigger !== 'booking_confirmed') { let scheduledFor; if (template.trigger === '1_day_before') { scheduledFor = new Date(appointment.dateTime.getTime() - 24 * 60 * 60 * 1000); } else if (template.trigger === '2_hours_before') { scheduledFor = new Date(appointment.dateTime.getTime() - 2 * 60 * 60 * 1000); } else { scheduledFor = new Date(appointment.dateTime.getTime() + template.offsetMinutes * 60000); } if (scheduledFor > new Date()) { await prisma.scheduledReminder.create({ data: { appointmentId: appointment.id, templateId: template.id, scheduledFor: scheduledFor, }, }); console.log(`āœ… Scheduled ${template.trigger} for ${scheduledFor}`); } } } // Wait and send the booking confirmation console.log('\nā° WAITING 5 SECONDS THEN SENDING BOOKING CONFIRMATION...'); setTimeout(async () => { try { 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(`šŸ“¤ FORCED SEND: sent=${cronResult.sent}, failed=${cronResult.failed}`); if (cronResult.sent > 0) { console.log('šŸŽ‰ BOOKING CONFIRMATION SENT!'); // Check if it was sent to the right number const sentMessage = await prisma.messageLog.findFirst({ where: { appointmentId: appointment.id }, orderBy: { createdAt: 'desc' } }); if (sentMessage) { console.log(`šŸ“± Message sent to: ${sentMessage.phone}`); console.log(`šŸ“Ø Status: ${sentMessage.status}`); console.log(`šŸ†” WAHA ID: ${sentMessage.wahaMessageId}`); if (sentMessage.phone !== '+201066544750') { console.log('āŒ WRONG PHONE NUMBER! Sent to wrong patient!'); // Update the lead's phone number await prisma.lead.update({ where: { id: appointment.leadId }, data: { phone: '+201066544750' } }); console.log('šŸ”§ Updated lead phone to +201066544750'); // Send a corrected message const testMessage = { session: 'default', chatId: '201066544750@c.us', text: `šŸ”§ CORRECTED BOOKING CONFIRMATION Hi ${appointment.lead.name}! Your ${appointment.treatment.name} appointment is confirmed: šŸ“… ${appointment.dateTime} The system sent the original confirmation to the wrong number, but it's fixed now! This message is sent to your correct WhatsApp: +201066544750 Appointment ID: ${appointment.id}` }; const fixResponse = await fetch('http://localhost:3005/api/sendText', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': '992659f827564646ba3ab95ead50adc9' }, body: JSON.stringify(testMessage) }); if (fixResponse.ok) { const fixResult = await fixResponse.json(); console.log(`šŸ”§ CORRECTION SENT: ${fixResult.key?.id}`); console.log('šŸ“± CHECK YOUR WHATSAPP (+201066544750) NOW!'); } } else { console.log('āœ… Sent to correct number!'); console.log('šŸ“± CHECK YOUR WHATSAPP (+201066544750) NOW!'); } } } else { console.log('āŒ NO MESSAGES SENT - checking why...'); // Check the reminder status const reminderCheck = await prisma.scheduledReminder.findFirst({ where: { appointmentId: appointment.id }, include: { template: true } }); if (reminderCheck) { console.log(`šŸ“… Reminder status: ${reminderCheck.status}`); console.log(`šŸ“… Scheduled for: ${reminderCheck.scheduledFor}`); console.log(`šŸ“… Current time: ${new Date()}`); const timeDiff = new Date(reminderCheck.scheduledFor).getTime() - Date.now(); console.log(`ā° Time until due: ${Math.round(timeDiff / 1000)} seconds`); if (timeDiff > 0) { console.log('ā° Reminder not due yet - waiting...'); } } } } else { console.log('āŒ Cron call failed'); } } catch (error) { console.error('āŒ Send error:', error); } }, 5000); } else { console.log('āŒ No booking confirmation template found!'); } } else { console.log('āœ… Reminders already scheduled:'); appointment.scheduledReminders.forEach((r, i) => { console.log(` ${i + 1}. ${r.template.trigger} - ${r.scheduledFor} (${r.status})`); }); // Check if any are due now const dueNow = appointment.scheduledReminders.filter(r => r.status === 'pending' && new Date(r.scheduledFor) <= new Date() ); if (dueNow.length > 0) { console.log(`ā° ${dueNow.length} reminders due now - sending...`); 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: sent=${cronResult.sent}, failed=${cronResult.failed}`); } } } } lastAppointmentCount = currentCount; } // Show status every 30 seconds if (checkCount % 15 === 0) { console.log(`ā±ļø Still monitoring... (${checkCount * 2}s) - Create appointment in UI`); } } catch (error) { console.error('āŒ Monitor error:', error); } }, 2000); // Check every 2 seconds // Stop after 10 minutes setTimeout(() => { clearInterval(monitor); console.log('\nā¹ļø Monitoring stopped'); console.log('If no appointment was created, make sure to create one in the Clinera UI'); prisma.$disconnect(); process.exit(0); }, 10 * 60 * 1000); // Also provide immediate fix option console.log('\nšŸ”§ OR MANUAL FIX: If you just created an appointment:'); console.log(' I can find it and fix the reminders immediately'); console.log(' Just create the appointment and this script will catch it!'); } debugRealUIWorkflow().catch(console.error);