diff --git a/scripts/seed-data.ts b/scripts/seed-data.ts index c70126f..e1f00b4 100644 --- a/scripts/seed-data.ts +++ b/scripts/seed-data.ts @@ -1,6 +1,6 @@ /** * Helix Engage — Platform Data Seeder - * Creates 5 patient stories with fully linked records. + * Creates 5 patient stories + 5 doctors with fully linked records. * Run: cd helix-engage && npx tsx scripts/seed-data.ts * * Platform field mapping (SDK name → platform name): @@ -12,7 +12,8 @@ * Appointment: durationMinutes→durationMin, appointmentStatus→status, roomNumber→room * FollowUp: followUpType→typeCustom, followUpStatus→status * Patient: address→addressCustom - * NOTE: callNotes/visitNotes are RICH_TEXT — read-only, cannot seed + * Doctor: isActive→active, branch→branchClinic + * NOTE: callNotes/visitNotes/clinicalNotes are RICH_TEXT — read-only, cannot seed */ const GQL = 'http://localhost:4000/graphql'; @@ -22,17 +23,10 @@ const ORIGIN = 'http://fortytwo-dev.localhost:4010'; let token = ''; function ago(days: number, hours = 0): string { - const d = new Date(); - d.setDate(d.getDate() - days); - d.setHours(d.getHours() - hours); - return d.toISOString(); + const d = new Date(); d.setDate(d.getDate() - days); d.setHours(d.getHours() - hours); return d.toISOString(); } - function future(days: number, hour = 10): string { - const d = new Date(); - d.setDate(d.getDate() + days); - d.setHours(hour, 0, 0, 0); - return d.toISOString(); + const d = new Date(); d.setDate(d.getDate() + days); d.setHours(hour, 0, 0, 0); return d.toISOString(); } async function gql(query: string, variables?: any) { @@ -62,13 +56,123 @@ async function main() { await auth(); console.log('✅ Auth OK\n'); - // ═══════════════ CAMPAIGNS ═══════════════ + // Workspace member IDs (from platform — set names + roles in UI before running) + const WM = { + drSharma: '251e9b32-3a83-4f3c-a904-fad7e8b840c3', + drPatel: '2b1bbf20-3838-434f-9fe9-b98436362230', + drKumar: '16109622-9b13-4682-b327-eb611ffa8338', + drReddy: '478a9ccb-d231-48fb-a740-0228d3c9325b', + drSingh: 'b854b55b-7302-4981-8dfc-bea516abdc86', + }; + + // ═══════════════════════════════════════════ + // DOCTORS (linked to workspace members) + // ═══════════════════════════════════════════ + console.log('👨‍⚕️ Doctors'); + const drSharma = await mk('doctor', { + name: 'Dr. Arun Sharma', + fullName: { firstName: 'Arun', lastName: 'Sharma' }, + department: 'CARDIOLOGY', + specialty: 'Interventional Cardiology', + qualifications: 'MBBS, MD (Medicine), DM (Cardiology), FACC', + yearsOfExperience: 18, + branchClinic: 'Koramangala, Whitefield', + visitingHours: 'Mon/Wed/Fri 10:00 AM – 1:00 PM', + consultationFeeNew: { amountMicros: 800_000_000, currencyCode: 'INR' }, + consultationFeeFollowUp: { amountMicros: 500_000_000, currencyCode: 'INR' }, + phone: { primaryPhoneNumber: '9900100001', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, + email: { primaryEmail: 'dr.sharma@globalhospital.com' }, + registrationNumber: 'KMC-45672', + active: true, + portalUserId: WM.drSharma, + }); + console.log(` Dr. Sharma (Cardiology, WM: ${WM.drSharma}): ${drSharma}`); + + const drPatel = await mk('doctor', { + name: 'Dr. Meena Patel', + fullName: { firstName: 'Meena', lastName: 'Patel' }, + department: 'GYNECOLOGY', + specialty: 'Reproductive Medicine & IVF', + qualifications: 'MBBS, MS (OBG), Fellowship in Reproductive Medicine', + yearsOfExperience: 15, + branchClinic: 'Indiranagar, Koramangala', + visitingHours: 'Tue/Thu/Sat 9:00 AM – 12:00 PM', + consultationFeeNew: { amountMicros: 700_000_000, currencyCode: 'INR' }, + consultationFeeFollowUp: { amountMicros: 400_000_000, currencyCode: 'INR' }, + phone: { primaryPhoneNumber: '9900100002', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, + email: { primaryEmail: 'dr.patel@globalhospital.com' }, + registrationNumber: 'KMC-38291', + active: true, + portalUserId: WM.drPatel, + }); + console.log(` Dr. Patel (Gynecology/IVF, WM: ${WM.drPatel}): ${drPatel}`); + + const drKumar = await mk('doctor', { + name: 'Dr. Rajesh Kumar', + fullName: { firstName: 'Rajesh', lastName: 'Kumar' }, + department: 'ORTHOPEDICS', + specialty: 'Joint Replacement & Sports Medicine', + qualifications: 'MBBS, MS (Ortho), Fellowship in Arthroplasty', + yearsOfExperience: 12, + branchClinic: 'Whitefield', + visitingHours: 'Mon–Fri 2:00 PM – 5:00 PM', + consultationFeeNew: { amountMicros: 600_000_000, currencyCode: 'INR' }, + consultationFeeFollowUp: { amountMicros: 400_000_000, currencyCode: 'INR' }, + phone: { primaryPhoneNumber: '9900100003', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, + email: { primaryEmail: 'dr.kumar@globalhospital.com' }, + registrationNumber: 'KMC-51003', + active: true, + portalUserId: WM.drKumar, + }); + console.log(` Dr. Kumar (Orthopedics, WM: ${WM.drKumar}): ${drKumar}`); + + const drReddy = await mk('doctor', { + name: 'Dr. Lakshmi Reddy', + fullName: { firstName: 'Lakshmi', lastName: 'Reddy' }, + department: 'GENERAL_MEDICINE', + specialty: 'Internal Medicine & Preventive Health', + qualifications: 'MBBS, MD (General Medicine)', + yearsOfExperience: 20, + branchClinic: 'Koramangala, Indiranagar, Whitefield', + visitingHours: 'Mon–Sat 9:00 AM – 6:00 PM', + consultationFeeNew: { amountMicros: 500_000_000, currencyCode: 'INR' }, + consultationFeeFollowUp: { amountMicros: 300_000_000, currencyCode: 'INR' }, + phone: { primaryPhoneNumber: '9900100004', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, + email: { primaryEmail: 'dr.reddy@globalhospital.com' }, + registrationNumber: 'KMC-22145', + active: true, + portalUserId: WM.drReddy, + }); + console.log(` Dr. Reddy (General Medicine, WM: ${WM.drReddy}): ${drReddy}`); + + const drSingh = await mk('doctor', { + name: 'Dr. Harpreet Singh', + fullName: { firstName: 'Harpreet', lastName: 'Singh' }, + department: 'ENT', + specialty: 'Otorhinolaryngology & Head/Neck Surgery', + qualifications: 'MBBS, MS (ENT), DNB', + yearsOfExperience: 10, + branchClinic: 'Indiranagar', + visitingHours: 'Mon/Wed/Fri 11:00 AM – 3:00 PM', + consultationFeeNew: { amountMicros: 600_000_000, currencyCode: 'INR' }, + consultationFeeFollowUp: { amountMicros: 400_000_000, currencyCode: 'INR' }, + phone: { primaryPhoneNumber: '9900100005', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, + email: { primaryEmail: 'dr.singh@globalhospital.com' }, + registrationNumber: 'KMC-60782', + active: true, + portalUserId: WM.drSingh, + }); + console.log(` Dr. Singh (ENT, WM: ${WM.drSingh}): ${drSingh}\n`); + + await auth(); + + // ═══════════════════════════════════════════ + // CAMPAIGNS + // ═══════════════════════════════════════════ console.log('📢 Campaigns'); const wdCamp = await mk('campaign', { - name: "Women's Day Health Checkup", - campaignName: "Women's Day Health Checkup", - status: 'ACTIVE', platform: 'FACEBOOK', - startDate: ago(14), endDate: future(16), + name: "Women's Day Health Checkup", campaignName: "Women's Day Health Checkup", + status: 'ACTIVE', platform: 'FACEBOOK', startDate: ago(14), endDate: future(16), budget: { amountMicros: 200_000_000_000, currencyCode: 'INR' }, amountSpent: { amountMicros: 130_000_000_000, currencyCode: 'INR' }, impressions: 82000, clicks: 2100, targetCount: 500, contacted: 89, converted: 24, leadsGenerated: 148, @@ -77,10 +181,8 @@ async function main() { console.log(` Women's Day: ${wdCamp}`); const csCamp = await mk('campaign', { - name: 'Cervical Cancer Screening Drive', - campaignName: 'Cervical Cancer Screening Drive', - status: 'ACTIVE', platform: 'GOOGLE', - startDate: ago(10), endDate: future(28), + name: 'Cervical Cancer Screening Drive', campaignName: 'Cervical Cancer Screening Drive', + status: 'ACTIVE', platform: 'GOOGLE', startDate: ago(10), endDate: future(28), budget: { amountMicros: 150_000_000_000, currencyCode: 'INR' }, amountSpent: { amountMicros: 57_500_000_000, currencyCode: 'INR' }, impressions: 45000, clicks: 1300, targetCount: 300, contacted: 31, converted: 8, leadsGenerated: 56, @@ -89,10 +191,8 @@ async function main() { console.log(` Cervical Screening: ${csCamp}`); const ivfCamp = await mk('campaign', { - name: 'IVF Consultation — Free First Visit', - campaignName: 'IVF Consultation — Free First Visit', - status: 'ACTIVE', platform: 'FACEBOOK', - startDate: ago(23), endDate: future(13), + name: 'IVF Consultation — Free First Visit', campaignName: 'IVF Consultation — Free First Visit', + status: 'ACTIVE', platform: 'FACEBOOK', startDate: ago(23), endDate: future(13), budget: { amountMicros: 300_000_000_000, currencyCode: 'INR' }, amountSpent: { amountMicros: 246_000_000_000, currencyCode: 'INR' }, impressions: 156000, clicks: 4200, targetCount: 500, contacted: 198, converted: 52, leadsGenerated: 312, @@ -102,201 +202,192 @@ async function main() { await auth(); - // ═══════════════ PATIENTS ═══════════════ + // ═══════════════════════════════════════════ + // PATIENTS + // ═══════════════════════════════════════════ console.log('🏥 Patients'); - const priyaPatient = await mk('patient', { + const priyaPat = await mk('patient', { name: 'Priya Sharma', fullName: { firstName: 'Priya', lastName: 'Sharma' }, phones: { primaryPhoneNumber: '9949879837', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, emails: { primaryEmail: 'priya.sharma@gmail.com' }, - dateOfBirth: '1994-05-15', - gender: 'FEMALE', - patientType: 'RETURNING', + dateOfBirth: '1994-05-15', gender: 'FEMALE', patientType: 'RETURNING', }); - console.log(` Priya Sharma (IVF, returning): ${priyaPatient}`); + console.log(` Priya Sharma: ${priyaPat}`); - const deepaPatient = await mk('patient', { + const deepaPat = await mk('patient', { name: 'Deepa Rao', fullName: { firstName: 'Deepa', lastName: 'Rao' }, phones: { primaryPhoneNumber: '7654321098', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, - dateOfBirth: '1997-08-22', - gender: 'FEMALE', - patientType: 'NEW', + dateOfBirth: '1997-08-22', gender: 'FEMALE', patientType: 'NEW', }); - console.log(` Deepa Rao (IVF, new): ${deepaPatient}`); + console.log(` Deepa Rao: ${deepaPat}`); - const vijayPatient = await mk('patient', { + const vijayPat = await mk('patient', { name: 'Vijay Nair', fullName: { firstName: 'Vijay', lastName: 'Nair' }, phones: { primaryPhoneNumber: '6543210987', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, emails: { primaryEmail: 'vijay.n@gmail.com' }, - dateOfBirth: '1971-02-10', - gender: 'MALE', - patientType: 'RETURNING', + dateOfBirth: '1971-02-10', gender: 'MALE', patientType: 'RETURNING', }); - console.log(` Vijay Nair (cardiology, regular): ${vijayPatient}\n`); + console.log(` Vijay Nair: ${vijayPat}\n`); await auth(); - // ═══════════════ LEADS ═══════════════ + // ═══════════════════════════════════════════ + // LEADS (linked to campaigns + patients) + // ═══════════════════════════════════════════ console.log('👥 Leads'); - - // Story 1: Priya — returning IVF patient (demo phone: 9949879837) const priyaLead = await mk('lead', { name: 'Priya Sharma', contactName: { firstName: 'Priya', lastName: 'Sharma' }, contactPhone: { primaryPhoneNumber: '9949879837', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, contactEmail: { primaryEmail: 'priya.sharma@gmail.com' }, source: 'FACEBOOK_AD', status: 'APPOINTMENT_SET', interestedService: 'IVF Consultation', - assignedAgent: 'Rekha CC', spamScore: 5, isSpam: false, isDuplicate: false, + assignedAgent: 'Rekha S', spamScore: 5, isSpam: false, isDuplicate: false, firstContacted: ago(12), lastContacted: ago(2), contactAttempts: 3, leadScore: 92, aiSummary: 'Returning IVF patient. Had first consultation with Dr. Patel last week. Next appointment in 3 days. Very responsive — all 3 calls answered. Interested in premium IVF package.', aiSuggestedAction: 'Confirm upcoming appointment and discuss treatment timeline', - campaignId: ivfCamp, patientId: priyaPatient, + campaignId: ivfCamp, patientId: priyaPat, utmSource: 'facebook', utmMedium: 'paid', utmCampaign: 'ivf-free-consult', }); - console.log(` Priya Sharma (IVF, phone: 9949879837): ${priyaLead}`); + console.log(` Priya Sharma (phone: 9949879837): ${priyaLead}`); - // Story 2: Ravi — missed call, SLA breached (demo phone: 6309248884) const raviLead = await mk('lead', { name: 'Ravi Kumar', contactName: { firstName: 'Ravi', lastName: 'Kumar' }, contactPhone: { primaryPhoneNumber: '6309248884', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, contactEmail: { primaryEmail: 'ravi.k@yahoo.com' }, source: 'GOOGLE_AD', status: 'NEW', interestedService: 'Cervical Screening', - assignedAgent: 'Rekha CC', spamScore: 8, isSpam: false, contactAttempts: 0, leadScore: 75, + assignedAgent: 'Rekha S', spamScore: 8, isSpam: false, contactAttempts: 0, leadScore: 75, aiSummary: 'New lead from Google Ads cervical screening campaign. Missed call 18 hours ago — no callback. SLA breached. Urgent follow-up required.', aiSuggestedAction: 'Urgent callback — missed call SLA breached', campaignId: csCamp, utmSource: 'google', utmMedium: 'paid', }); - console.log(` Ravi Kumar (missed call, phone: 6309248884): ${raviLead}`); + console.log(` Ravi Kumar (phone: 6309248884): ${raviLead}`); - // Story 3: Deepa — walk-in converted const deepaLead = await mk('lead', { name: 'Deepa Rao', contactName: { firstName: 'Deepa', lastName: 'Rao' }, contactPhone: { primaryPhoneNumber: '7654321098', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, source: 'WALK_IN', status: 'CONVERTED', interestedService: 'IVF Package', - assignedAgent: 'Rekha CC', convertedAt: ago(2), firstContacted: ago(7), + assignedAgent: 'Rekha S', convertedAt: ago(2), firstContacted: ago(7), lastContacted: ago(2), contactAttempts: 2, leadScore: 88, aiSummary: 'Walk-in converted to IVF patient. Completed first consultation with Dr. Patel 2 days ago. Interested in premium IVF package.', aiSuggestedAction: 'Follow up on treatment plan discussion', - campaignId: ivfCamp, patientId: deepaPatient, + campaignId: ivfCamp, patientId: deepaPat, }); - console.log(` Deepa Rao (converted walk-in): ${deepaLead}`); + console.log(` Deepa Rao: ${deepaLead}`); - // Story 4: Vijay — multi-visit cardiology const vijayLead = await mk('lead', { name: 'Vijay Nair', contactName: { firstName: 'Vijay', lastName: 'Nair' }, contactPhone: { primaryPhoneNumber: '6543210987', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, contactEmail: { primaryEmail: 'vijay.n@gmail.com' }, source: 'REFERRAL', status: 'APPOINTMENT_SET', interestedService: 'Cardiology Consultation', - assignedAgent: 'Rekha CC', firstContacted: ago(20), lastContacted: ago(3), + assignedAgent: 'Rekha S', firstContacted: ago(20), lastContacted: ago(3), contactAttempts: 4, leadScore: 85, aiSummary: 'Regular cardiology patient under Dr. Sharma. 2 completed visits, good outcomes. Upcoming quarterly check-up in 5 days. Cancelled once before — confirm proactively.', aiSuggestedAction: 'Confirm upcoming appointment — previous cancellation history', - patientId: vijayPatient, + patientId: vijayPat, }); - console.log(` Vijay Nair (cardiology regular): ${vijayLead}`); + console.log(` Vijay Nair: ${vijayLead}`); - // Story 5: Kavitha — fresh lead today const kavithaLead = await mk('lead', { name: 'Kavitha S', contactName: { firstName: 'Kavitha', lastName: 'S' }, contactPhone: { primaryPhoneNumber: '9845123456', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, source: 'FACEBOOK_AD', status: 'NEW', interestedService: "Women's Health Checkup", spamScore: 3, isSpam: false, contactAttempts: 0, leadScore: 80, - aiSummary: "Brand new lead from today's Women's Day Facebook campaign. Complete details provided. No contact yet.", + aiSummary: "Brand new lead from today's Women's Day Facebook campaign. No contact yet.", aiSuggestedAction: 'Send WhatsApp template and assign to call center', campaignId: wdCamp, utmSource: 'facebook', utmMedium: 'paid', }); - console.log(` Kavitha S (fresh lead): ${kavithaLead}\n`); + console.log(` Kavitha S: ${kavithaLead}\n`); await auth(); - // ═══════════════ APPOINTMENTS (linked to patients) ═══════════════ + // ═══════════════════════════════════════════ + // APPOINTMENTS (linked to patients AND doctors) + // ═══════════════════════════════════════════ console.log('📅 Appointments'); - await mk('appointment', { name: 'Priya — IVF Consultation', scheduledAt: ago(5), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF initial consultation — fertility assessment', patientId: priyaPatient }); - console.log(' Priya — completed IVF consultation (5d ago)'); - await mk('appointment', { name: 'Priya — IVF Follow-up', scheduledAt: future(3, 10), durationMin: 45, appointmentType: 'FOLLOW_UP', status: 'SCHEDULED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF follow-up — treatment plan discussion', patientId: priyaPatient }); - console.log(' Priya — upcoming IVF follow-up (in 3d)'); - await mk('appointment', { name: 'Deepa — IVF Consultation', scheduledAt: ago(2), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF package consultation — walk-in referral', patientId: deepaPatient }); - console.log(' Deepa — completed IVF consultation (2d ago)'); - await mk('appointment', { name: 'Vijay — Cardiology Initial', scheduledAt: ago(14), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Initial assessment — chest discomfort, family history', patientId: vijayPatient }); - console.log(' Vijay — completed initial cardiology (14d ago)'); - await mk('appointment', { name: 'Vijay — Echo Review', scheduledAt: ago(7), durationMin: 30, appointmentType: 'FOLLOW_UP', status: 'COMPLETED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Echocardiogram review — all clear', patientId: vijayPatient }); - console.log(' Vijay — completed echo review (7d ago)'); - await mk('appointment', { name: 'Vijay — Quarterly Check-up', scheduledAt: future(5, 11), durationMin: 30, appointmentType: 'FOLLOW_UP', status: 'SCHEDULED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Quarterly cardiology check-up', patientId: vijayPatient }); - console.log(' Vijay — upcoming quarterly (in 5d)\n'); + await mk('appointment', { name: 'Priya — IVF Consultation', scheduledAt: ago(5), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF initial consultation — fertility assessment', patientId: priyaPat, doctorId: drPatel }); + console.log(' Priya × Dr. Patel — completed IVF consultation (5d ago)'); + await mk('appointment', { name: 'Priya — IVF Follow-up', scheduledAt: future(3, 10), durationMin: 45, appointmentType: 'FOLLOW_UP', status: 'SCHEDULED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF follow-up — treatment plan discussion', patientId: priyaPat, doctorId: drPatel }); + console.log(' Priya × Dr. Patel — upcoming follow-up (in 3d)'); + await mk('appointment', { name: 'Deepa — IVF Consultation', scheduledAt: ago(2), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Patel', department: 'Gynecology', reasonForVisit: 'IVF package consultation — walk-in referral', patientId: deepaPat, doctorId: drPatel }); + console.log(' Deepa × Dr. Patel — completed consultation (2d ago)'); + await mk('appointment', { name: 'Vijay — Cardiology Initial', scheduledAt: ago(14), durationMin: 30, appointmentType: 'CONSULTATION', status: 'COMPLETED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Initial assessment — chest discomfort, family history', patientId: vijayPat, doctorId: drSharma }); + console.log(' Vijay × Dr. Sharma — completed initial (14d ago)'); + await mk('appointment', { name: 'Vijay — Echo Review', scheduledAt: ago(7), durationMin: 30, appointmentType: 'FOLLOW_UP', status: 'COMPLETED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Echocardiogram review — all clear', patientId: vijayPat, doctorId: drSharma }); + console.log(' Vijay × Dr. Sharma — completed echo (7d ago)'); + await mk('appointment', { name: 'Vijay — Quarterly Check-up', scheduledAt: future(5, 11), durationMin: 30, appointmentType: 'FOLLOW_UP', status: 'SCHEDULED', doctorName: 'Dr. Sharma', department: 'Cardiology', reasonForVisit: 'Quarterly cardiology check-up', patientId: vijayPat, doctorId: drSharma }); + console.log(' Vijay × Dr. Sharma — upcoming quarterly (in 5d)\n'); await auth(); - // ═══════════════ CALLS (linked to leads) ═══════════════ + // ═══════════════════════════════════════════ + // CALLS (linked to leads) + // ═══════════════════════════════════════════ console.log('📞 Calls'); - // Priya: 3 calls - await mk('call', { name: 'Priya — IVF Enquiry', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(12), endedAt: ago(12), durationSec: 240, disposition: 'INFO_PROVIDED', leadId: priyaLead }); + await mk('call', { name: 'Priya — IVF Enquiry', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(12), endedAt: ago(12), durationSec: 240, disposition: 'INFO_PROVIDED', leadId: priyaLead }); console.log(' Priya — inbound enquiry (12d ago)'); - await mk('call', { name: 'Priya — Appt Booked', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(6), endedAt: ago(6), durationSec: 180, disposition: 'APPOINTMENT_BOOKED', leadId: priyaLead }); - console.log(' Priya — outbound, booked appointment (6d ago)'); - await mk('call', { name: 'Priya — Reminder', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(2), endedAt: ago(2), durationSec: 120, disposition: 'FOLLOW_UP_SCHEDULED', leadId: priyaLead }); - console.log(' Priya — outbound reminder (2d ago)'); - - // Ravi: 1 missed - await mk('call', { name: 'Ravi — Missed Call', direction: 'INBOUND', callStatus: 'MISSED', agentName: 'Rekha CC', startedAt: ago(0, 18), durationSec: 0, leadId: raviLead }); + await mk('call', { name: 'Priya — Appt Booked', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(6), endedAt: ago(6), durationSec: 180, disposition: 'APPOINTMENT_BOOKED', leadId: priyaLead }); + console.log(' Priya — appointment booked (6d ago)'); + await mk('call', { name: 'Priya — Reminder', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(2), endedAt: ago(2), durationSec: 120, disposition: 'FOLLOW_UP_SCHEDULED', leadId: priyaLead }); + console.log(' Priya — reminder (2d ago)'); + await mk('call', { name: 'Ravi — Missed Call', direction: 'INBOUND', callStatus: 'MISSED', agentName: 'Rekha S', startedAt: ago(0, 18), durationSec: 0, leadId: raviLead }); console.log(' Ravi — missed inbound (18h ago)'); - - // Deepa: 2 calls - await mk('call', { name: 'Deepa — Walk-in Enquiry', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(7), endedAt: ago(7), durationSec: 300, disposition: 'INFO_PROVIDED', leadId: deepaLead }); - console.log(' Deepa — inbound IVF enquiry (7d ago)'); - await mk('call', { name: 'Deepa — Appt Booked', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(3), endedAt: ago(3), durationSec: 150, disposition: 'APPOINTMENT_BOOKED', leadId: deepaLead }); - console.log(' Deepa — outbound, booked (3d ago)'); - - // Vijay: 4 calls - await mk('call', { name: 'Vijay — Referral Call', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(20), endedAt: ago(20), durationSec: 210, disposition: 'APPOINTMENT_BOOKED', leadId: vijayLead }); - console.log(' Vijay — inbound referral (20d ago)'); - await mk('call', { name: 'Vijay — Follow-up Scheduled', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(10), endedAt: ago(10), durationSec: 90, disposition: 'FOLLOW_UP_SCHEDULED', leadId: vijayLead }); - console.log(' Vijay — follow-up call (10d ago)'); - await mk('call', { name: 'Vijay — No Answer', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(5), endedAt: ago(5), durationSec: 0, disposition: 'NO_ANSWER', leadId: vijayLead }); + await mk('call', { name: 'Deepa — Walk-in Enquiry', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(7), endedAt: ago(7), durationSec: 300, disposition: 'INFO_PROVIDED', leadId: deepaLead }); + console.log(' Deepa — enquiry (7d ago)'); + await mk('call', { name: 'Deepa — Appt Booked', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(3), endedAt: ago(3), durationSec: 150, disposition: 'APPOINTMENT_BOOKED', leadId: deepaLead }); + console.log(' Deepa — booked (3d ago)'); + await mk('call', { name: 'Vijay — Referral Call', direction: 'INBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(20), endedAt: ago(20), durationSec: 210, disposition: 'APPOINTMENT_BOOKED', leadId: vijayLead }); + console.log(' Vijay — referral (20d ago)'); + await mk('call', { name: 'Vijay — Follow-up', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(10), endedAt: ago(10), durationSec: 90, disposition: 'FOLLOW_UP_SCHEDULED', leadId: vijayLead }); + console.log(' Vijay — follow-up (10d ago)'); + await mk('call', { name: 'Vijay — No Answer', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(5), endedAt: ago(5), durationSec: 0, disposition: 'NO_ANSWER', leadId: vijayLead }); console.log(' Vijay — no answer (5d ago)'); - await mk('call', { name: 'Vijay — Quarterly Confirmed', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha CC', startedAt: ago(3), endedAt: ago(3), durationSec: 180, disposition: 'APPOINTMENT_BOOKED', leadId: vijayLead }); - console.log(' Vijay — quarterly confirmed (3d ago)\n'); + await mk('call', { name: 'Vijay — Quarterly Confirmed', direction: 'OUTBOUND', callStatus: 'COMPLETED', agentName: 'Rekha S', startedAt: ago(3), endedAt: ago(3), durationSec: 180, disposition: 'APPOINTMENT_BOOKED', leadId: vijayLead }); + console.log(' Vijay — confirmed (3d ago)\n'); await auth(); - // ═══════════════ LEAD ACTIVITIES ═══════════════ + // ═══════════════════════════════════════════ + // LEAD ACTIVITIES (full journey timeline) + // ═══════════════════════════════════════════ console.log('📋 Activities'); const acts: any[] = [ - // Priya journey + // Priya journey (8 activities) { name: 'Lead created', activityType: 'STATUS_CHANGE', summary: 'Lead created from Facebook IVF campaign', occurredAt: ago(14), performedBy: 'System', channel: 'SYSTEM', leadId: priyaLead }, - { name: 'Assigned', activityType: 'ASSIGNED', summary: 'Auto-assigned to Rekha CC via round-robin', occurredAt: ago(14), performedBy: 'System', channel: 'SYSTEM', newValue: 'Rekha CC', leadId: priyaLead }, - { name: 'WhatsApp sent', activityType: 'WHATSAPP_SENT', summary: 'IVF consultation template sent via WhatsApp', occurredAt: ago(13), performedBy: 'Sanjay Marketing', channel: 'WHATSAPP', leadId: priyaLead }, - { name: 'Enquiry call', activityType: 'CALL_RECEIVED', summary: 'Inbound call — enquired about IVF costs and process', occurredAt: ago(12), performedBy: 'Rekha CC', channel: 'PHONE', leadId: priyaLead }, + { name: 'Assigned', activityType: 'ASSIGNED', summary: 'Auto-assigned to Rekha S via round-robin', occurredAt: ago(14), performedBy: 'System', channel: 'SYSTEM', newValue: 'Rekha S', leadId: priyaLead }, + { name: 'WhatsApp sent', activityType: 'WHATSAPP_SENT', summary: 'IVF consultation template sent via WhatsApp', occurredAt: ago(13), performedBy: 'Sanjay Kumar', channel: 'WHATSAPP', leadId: priyaLead }, + { name: 'Enquiry call', activityType: 'CALL_RECEIVED', summary: 'Inbound call — enquired about IVF costs and process', occurredAt: ago(12), performedBy: 'Rekha S', channel: 'PHONE', leadId: priyaLead }, { name: 'Status → CONTACTED', activityType: 'STATUS_CHANGE', summary: 'NEW → CONTACTED', occurredAt: ago(12), performedBy: 'System', channel: 'SYSTEM', previousValue: 'NEW', newValue: 'CONTACTED', leadId: priyaLead }, - { name: 'Appt booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Booked IVF consultation with Dr. Patel', occurredAt: ago(6), performedBy: 'Rekha CC', channel: 'PHONE', leadId: priyaLead }, + { name: 'Appt booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Booked IVF consultation with Dr. Patel at Indiranagar', occurredAt: ago(6), performedBy: 'Rekha S', channel: 'PHONE', leadId: priyaLead }, { name: 'Status → APPOINTMENT_SET', activityType: 'STATUS_CHANGE', summary: 'CONTACTED → APPOINTMENT_SET', occurredAt: ago(6), performedBy: 'System', channel: 'SYSTEM', previousValue: 'CONTACTED', newValue: 'APPOINTMENT_SET', leadId: priyaLead }, - { name: 'Confirmed', activityType: 'NOTE_ADDED', summary: 'Patient confirmed attendance for follow-up. Interested in premium IVF package.', occurredAt: ago(2), performedBy: 'Rekha CC', channel: 'PHONE', leadId: priyaLead }, + { name: 'Confirmed', activityType: 'NOTE_ADDED', summary: 'Patient confirmed follow-up attendance. Interested in premium IVF package (₹1.5L).', occurredAt: ago(2), performedBy: 'Rekha S', channel: 'PHONE', leadId: priyaLead }, - // Ravi journey + // Ravi journey (3 activities) { name: 'Lead created', activityType: 'STATUS_CHANGE', summary: 'Lead created from Google cervical screening campaign', occurredAt: ago(3), performedBy: 'System', channel: 'SYSTEM', leadId: raviLead }, - { name: 'Assigned', activityType: 'ASSIGNED', summary: 'Assigned to Rekha CC', occurredAt: ago(3), performedBy: 'System', channel: 'SYSTEM', newValue: 'Rekha CC', leadId: raviLead }, + { name: 'Assigned', activityType: 'ASSIGNED', summary: 'Assigned to Rekha S', occurredAt: ago(3), performedBy: 'System', channel: 'SYSTEM', newValue: 'Rekha S', leadId: raviLead }, { name: 'Missed call', activityType: 'CALL_RECEIVED', summary: 'Missed inbound call — all agents busy', occurredAt: ago(0, 18), performedBy: 'System', channel: 'PHONE', leadId: raviLead }, - // Deepa journey + // Deepa journey (4 activities) { name: 'Walk-in created', activityType: 'STATUS_CHANGE', summary: 'Walk-in enquiry lead created', occurredAt: ago(7), performedBy: 'System', channel: 'IN_PERSON', leadId: deepaLead }, - { name: 'IVF enquiry', activityType: 'CALL_RECEIVED', summary: 'Walk-in enquiry — interested in IVF packages', occurredAt: ago(7), performedBy: 'Rekha CC', channel: 'PHONE', leadId: deepaLead }, - { name: 'Appt booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Booked IVF consultation with Dr. Patel', occurredAt: ago(3), performedBy: 'Rekha CC', channel: 'PHONE', leadId: deepaLead }, - { name: 'Converted', activityType: 'CONVERTED', summary: 'Completed first IVF consultation — converted', occurredAt: ago(2), performedBy: 'System', channel: 'SYSTEM', leadId: deepaLead }, + { name: 'IVF enquiry', activityType: 'CALL_RECEIVED', summary: 'Walk-in enquiry — interested in IVF packages and Dr. Patel availability', occurredAt: ago(7), performedBy: 'Rekha S', channel: 'PHONE', leadId: deepaLead }, + { name: 'Appt booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Booked IVF consultation with Dr. Patel at Koramangala', occurredAt: ago(3), performedBy: 'Rekha S', channel: 'PHONE', leadId: deepaLead }, + { name: 'Converted', activityType: 'CONVERTED', summary: 'Completed first IVF consultation — converted to active patient', occurredAt: ago(2), performedBy: 'System', channel: 'SYSTEM', leadId: deepaLead }, - // Vijay journey + // Vijay journey (6 activities) { name: 'Referral created', activityType: 'STATUS_CHANGE', summary: 'Referral lead — family doctor recommended cardiology check', occurredAt: ago(21), performedBy: 'System', channel: 'SYSTEM', leadId: vijayLead }, - { name: 'Initial booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Cardiology consultation with Dr. Sharma booked', occurredAt: ago(20), performedBy: 'Rekha CC', channel: 'PHONE', leadId: vijayLead }, - { name: 'Clinical note', activityType: 'NOTE_ADDED', summary: 'Family history of cardiac issues. Dr. Sharma ordered echocardiogram.', occurredAt: ago(14), performedBy: 'Rekha CC', channel: 'SYSTEM', leadId: vijayLead }, - { name: 'Follow-up booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Echo review follow-up booked with Dr. Sharma', occurredAt: ago(10), performedBy: 'Rekha CC', channel: 'PHONE', leadId: vijayLead }, - { name: 'Cancellation note', activityType: 'NOTE_ADDED', summary: 'Patient cancelled echo review once — successfully rescheduled', occurredAt: ago(8), performedBy: 'Rekha CC', channel: 'PHONE', leadId: vijayLead }, - { name: 'Quarterly confirmed', activityType: 'APPOINTMENT_BOOKED', summary: 'Quarterly cardiology check-up confirmed', occurredAt: ago(3), performedBy: 'Rekha CC', channel: 'PHONE', leadId: vijayLead }, + { name: 'Initial booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Cardiology consultation with Dr. Sharma at Koramangala booked', occurredAt: ago(20), performedBy: 'Rekha S', channel: 'PHONE', leadId: vijayLead }, + { name: 'Clinical note', activityType: 'NOTE_ADDED', summary: 'Family history of cardiac issues. Dr. Sharma ordered echocardiogram. Patient compliant.', occurredAt: ago(14), performedBy: 'Rekha S', channel: 'SYSTEM', leadId: vijayLead }, + { name: 'Follow-up booked', activityType: 'APPOINTMENT_BOOKED', summary: 'Echo review follow-up with Dr. Sharma booked', occurredAt: ago(10), performedBy: 'Rekha S', channel: 'PHONE', leadId: vijayLead }, + { name: 'Cancellation note', activityType: 'NOTE_ADDED', summary: 'Patient cancelled echo review once (work conflict) — successfully rescheduled to next day', occurredAt: ago(8), performedBy: 'Rekha S', channel: 'PHONE', leadId: vijayLead }, + { name: 'Quarterly confirmed', activityType: 'APPOINTMENT_BOOKED', summary: 'Quarterly cardiology check-up with Dr. Sharma confirmed', occurredAt: ago(3), performedBy: 'Rekha S', channel: 'PHONE', leadId: vijayLead }, - // Kavitha + // Kavitha (1 activity) { name: 'Lead created', activityType: 'STATUS_CHANGE', summary: "New lead from Women's Day Facebook campaign", occurredAt: ago(0, 2), performedBy: 'System', channel: 'SYSTEM', leadId: kavithaLead }, ]; for (const a of acts) await mk('leadActivity', a); @@ -304,16 +395,19 @@ async function main() { await auth(); - // ═══════════════ FOLLOW-UPS ═══════════════ + // ═══════════════════════════════════════════ + // FOLLOW-UPS + // ═══════════════════════════════════════════ console.log('🔔 Follow-ups'); - await mk('followUp', { name: 'Ravi — Urgent Callback', typeCustom: 'CALLBACK', status: 'OVERDUE', scheduledAt: ago(0, 6), assignedAgent: 'Rekha CC', priority: 'URGENT' }); + await mk('followUp', { name: 'Ravi — Urgent Callback', typeCustom: 'CALLBACK', status: 'OVERDUE', scheduledAt: ago(0, 6), assignedAgent: 'Rekha S', priority: 'URGENT' }); console.log(' Ravi — overdue callback (6h ago, URGENT)'); - await mk('followUp', { name: 'Vijay — Appointment Reminder', typeCustom: 'APPOINTMENT_REMINDER', status: 'PENDING', scheduledAt: future(1, 9), assignedAgent: 'Rekha CC', priority: 'HIGH' }); + await mk('followUp', { name: 'Vijay — Appointment Reminder', typeCustom: 'APPOINTMENT_REMINDER', status: 'PENDING', scheduledAt: future(1, 9), assignedAgent: 'Rekha S', priority: 'HIGH' }); console.log(' Vijay — appointment reminder (tomorrow 9am)\n'); console.log('🎉 Seed complete!'); - console.log(' 3 campaigns · 3 patients · 5 leads · 6 appointments · 10 calls · 22 activities · 2 follow-ups'); + console.log(' 5 doctors · 3 campaigns · 3 patients · 5 leads · 6 appointments · 10 calls · 22 activities · 2 follow-ups'); console.log(' Demo phones: Priya=9949879837, Ravi=6309248884'); + console.log(' All appointments linked to doctor entities'); } main().catch(e => { console.error('💥', e.message); process.exit(1); });