Files
helix-engage/scripts/seed-data.ts
saridsa2 44bd221108 feat: deploy to Hostinger VPS, switch to global_healthx Ozonetel account
- Add helix.svg and PNG favicon (generated via nano-banana)
- Update page title to "Helix Engage" with proper meta tags
- Make seed scripts configurable via SEED_GQL/SEED_ORIGIN env vars
- Support remote workspace member IDs in seed-data.ts
- Dynamic doctor-to-clinic linking in seed-new-entities.ts (fetch IDs from platform)
- Remove deprecated branchClinic field from seed data
- Fix TypeScript errors: callNotes null vs undefined, Lead type casting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:27:25 +05:30

415 lines
29 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Helix Engage — Platform Data Seeder
* 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):
* Campaign: campaignType→typeCustom, campaignStatus→status, impressionCount→impressions,
* clickCount→clicks, contactedCount→contacted, convertedCount→converted, leadCount→leadsGenerated
* Lead: leadSource→source, leadStatus→status, firstContactedAt→firstContacted,
* lastContactedAt→lastContacted, landingPageUrl→landingPage
* Call: callDirection→direction, durationSeconds→durationSec
* Appointment: durationMinutes→durationMin, appointmentStatus→status, roomNumber→room
* FollowUp: followUpType→typeCustom, followUpStatus→status
* Patient: address→addressCustom
* Doctor: isActive→active, branch→branchClinic
* NOTE: callNotes/visitNotes/clinicalNotes are RICH_TEXT — read-only, cannot seed
*/
const GQL = process.env.SEED_GQL ?? 'http://localhost:4000/graphql';
const SUB = 'fortytwo-dev';
const ORIGIN = process.env.SEED_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();
}
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();
}
async function gql(query: string, variables?: any) {
const h: Record<string, string> = { 'Content-Type': 'application/json', 'X-Workspace-Subdomain': SUB };
if (token) h['Authorization'] = `Bearer ${token}`;
const r = await fetch(GQL, { method: 'POST', headers: h, body: JSON.stringify({ query, variables }) });
const d: any = await r.json();
if (d.errors) { console.error('❌', d.errors[0].message); throw new Error(d.errors[0].message); }
return d.data;
}
async function auth() {
const d1 = await gql(`mutation { getLoginTokenFromCredentials(email: "dev@fortytwo.dev", password: "tim@apple.dev", origin: "${ORIGIN}") { loginToken { token } } }`);
const lt = d1.getLoginTokenFromCredentials.loginToken.token;
const d2 = await gql(`mutation { getAuthTokensFromLoginToken(loginToken: "${lt}", origin: "${ORIGIN}") { tokens { accessOrWorkspaceAgnosticToken { token } } } }`);
token = d2.getAuthTokensFromLoginToken.tokens.accessOrWorkspaceAgnosticToken.token;
}
async function mk(entity: string, data: any): Promise<string> {
const cap = entity[0].toUpperCase() + entity.slice(1);
const d = await gql(`mutation($data: ${cap}CreateInput!) { create${cap}(data: $data) { id } }`, { data });
return d[`create${cap}`].id;
}
async function main() {
console.log('🌱 Seeding Helix Engage demo data...\n');
await auth();
console.log('✅ Auth OK\n');
// Workspace member IDs — switch based on target platform
const WM = GQL.includes('srv1477139') ? {
drSharma: '107efa70-fd32-4819-8936-994197c6ada1',
drPatel: '7e1fe368-1f23-4a10-8c2f-3e9c3846b209',
drKumar: 'b86ff7d3-57de-44e5-aa13-e5da848a960c',
drReddy: 'b82693b6-701c-4783-8d02-cc137c9c306b',
drSingh: 'b2a00dd2-5bb5-4c29-8fb1-70a681193a4c',
} : {
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,
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,
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,
visitingHours: 'MonFri 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,
visitingHours: 'MonSat 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,
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),
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,
externalCampaignId: 'fb_camp_28491',
});
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),
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,
externalCampaignId: 'ggl_camp_44102',
});
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),
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,
externalCampaignId: 'fb_camp_28555',
});
console.log(` IVF: ${ivfCamp}\n`);
await auth();
// ═══════════════════════════════════════════
// PATIENTS
// ═══════════════════════════════════════════
console.log('🏥 Patients');
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',
});
console.log(` Priya Sharma: ${priyaPat}`);
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',
});
console.log(` Deepa Rao: ${deepaPat}`);
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',
});
console.log(` Vijay Nair: ${vijayPat}\n`);
await auth();
// ═══════════════════════════════════════════
// LEADS (linked to campaigns + patients)
// ═══════════════════════════════════════════
console.log('👥 Leads');
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 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: priyaPat,
utmSource: 'facebook', utmMedium: 'paid', utmCampaign: 'ivf-free-consult',
});
console.log(` Priya Sharma (phone: 9949879837): ${priyaLead}`);
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 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 (phone: 6309248884): ${raviLead}`);
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 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: deepaPat,
});
console.log(` Deepa Rao: ${deepaLead}`);
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 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: vijayPat,
});
console.log(` Vijay Nair: ${vijayLead}`);
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. No contact yet.",
aiSuggestedAction: 'Send WhatsApp template and assign to call center',
campaignId: wdCamp, utmSource: 'facebook', utmMedium: 'paid',
});
console.log(` Kavitha S: ${kavithaLead}\n`);
await auth();
// ═══════════════════════════════════════════
// 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: 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)
// ═══════════════════════════════════════════
console.log('📞 Calls');
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 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)');
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 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 (full journey timeline)
// ═══════════════════════════════════════════
console.log('📋 Activities');
const acts: any[] = [
// 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 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 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 follow-up attendance. Interested in premium IVF package (₹1.5L).', occurredAt: ago(2), performedBy: 'Rekha S', channel: 'PHONE', leadId: priyaLead },
// 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 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 (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 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 (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 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 (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);
console.log(` ${acts.length} activities created\n`);
await auth();
// ═══════════════════════════════════════════
// FOLLOW-UPS
// ═══════════════════════════════════════════
console.log('🔔 Follow-ups');
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 S', priority: 'HIGH' });
console.log(' Vijay — appointment reminder (tomorrow 9am)\n');
console.log('🎉 Seed complete!');
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); });