/** * Seed clinics, health packages, insurance partners, and link doctors to clinics. * Run: cd helix-engage && npx tsx scripts/seed-new-entities.ts * * Prerequisites: doctors already seeded via seed-data.ts * * Platform field mapping (SDK name → platform name): * Clinic: address→addressCustom, operatingHoursWeekday→weekdayHours, * operatingHoursSaturday→saturdayHours, operatingHoursSunday→sundayHours, * clinicStatus→status, onlineBookingEnabled→onlineBooking, * arriveEarlyMinutes→arriveEarlyMin, paymentCash→acceptsCash, * paymentCard→acceptsCard, paymentUpi→acceptsUpi * HealthPackage: packageDepartment→department, durationMinutes→durationMin, isActive→active * InsurancePartner: planTypes→planTypesAccepted */ 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 = ''; async function gql(query: string, variables?: any) { const h: Record = { '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 { 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 update(entity: string, id: string, data: any): Promise { const cap = entity[0].toUpperCase() + entity.slice(1); await gql(`mutation($id: UUID!, $data: ${cap}UpdateInput!) { update${cap}(id: $id, data: $data) { id } }`, { id, data }); } async function main() { console.log('🌱 Seeding clinics, health packages, insurance partners...\n'); await auth(); console.log('✅ Auth OK\n'); // ═══════════════════════════════════════════ // CLINICS // ═══════════════════════════════════════════ console.log('🏥 Clinics'); const koramangala = await mk('clinic', { name: 'Global Hospital — Koramangala', clinicName: 'Koramangala', addressCustom: { addressStreet1: '#45, 80 Feet Road', addressCity: 'Bengaluru', addressState: 'Karnataka', addressPostcode: '560034', addressCountry: 'India', }, phone: { primaryPhoneNumber: '08041234567', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, email: { primaryEmail: 'koramangala@globalhospital.com' }, weekdayHours: '8:00 AM – 8:00 PM', saturdayHours: '8:00 AM – 8:00 PM', sundayHours: '9:00 AM – 2:00 PM', status: 'ACTIVE', walkInAllowed: true, onlineBooking: true, cancellationWindowHours: 4, arriveEarlyMin: 15, requiredDocuments: 'ID proof + medical records', acceptsCash: 'YES', acceptsCard: 'YES', acceptsUpi: 'YES', }); console.log(` Koramangala: ${koramangala}`); const whitefield = await mk('clinic', { name: 'Global Hospital — Whitefield', clinicName: 'Whitefield', addressCustom: { addressStreet1: 'Prestige Shantiniketan', addressCity: 'Bengaluru', addressState: 'Karnataka', addressPostcode: '560048', addressCountry: 'India', }, phone: { primaryPhoneNumber: '08041234568', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, email: { primaryEmail: 'whitefield@globalhospital.com' }, weekdayHours: '8:00 AM – 8:00 PM', saturdayHours: '8:00 AM – 8:00 PM', sundayHours: 'Closed', status: 'ACTIVE', walkInAllowed: true, onlineBooking: true, cancellationWindowHours: 4, arriveEarlyMin: 15, requiredDocuments: 'ID proof + medical records', acceptsCash: 'YES', acceptsCard: 'YES', acceptsUpi: 'YES', }); console.log(` Whitefield: ${whitefield}`); const indiranagar = await mk('clinic', { name: 'Global Hospital — Indiranagar', clinicName: 'Indiranagar', addressCustom: { addressStreet1: '#12, 100 Feet Road', addressCity: 'Bengaluru', addressState: 'Karnataka', addressPostcode: '560038', addressCountry: 'India', }, phone: { primaryPhoneNumber: '08041234569', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, email: { primaryEmail: 'indiranagar@globalhospital.com' }, weekdayHours: '9:00 AM – 7:00 PM', saturdayHours: '9:00 AM – 7:00 PM', sundayHours: '10:00 AM – 1:00 PM', status: 'ACTIVE', walkInAllowed: true, onlineBooking: true, cancellationWindowHours: 4, arriveEarlyMin: 15, requiredDocuments: 'ID proof + medical records', acceptsCash: 'YES', acceptsCard: 'YES', acceptsUpi: 'YES', }); console.log(` Indiranagar: ${indiranagar}\n`); await auth(); // ═══════════════════════════════════════════ // LINK DOCTORS TO CLINICS // ═══════════════════════════════════════════ console.log('🔗 Linking doctors to clinics'); // Fetch doctor IDs dynamically from platform const docData = await gql(`{ doctors(first: 10) { edges { node { id name } } } }`); const allDocs = docData.doctors.edges.map((e: any) => e.node); const clinicAssignment: Record = { 'Sharma': koramangala, 'Patel': indiranagar, 'Kumar': whitefield, 'Reddy': koramangala, 'Singh': indiranagar, }; for (const doc of allDocs) { const lastName = Object.keys(clinicAssignment).find(n => doc.name?.includes(n)); if (lastName && clinicAssignment[lastName]) { await update('doctor', doc.id, { clinicId: clinicAssignment[lastName] }); const clinicName = clinicAssignment[lastName] === koramangala ? 'Koramangala' : clinicAssignment[lastName] === whitefield ? 'Whitefield' : 'Indiranagar'; console.log(` ${doc.name} → ${clinicName}`); } } console.log(''); await auth(); // ═══════════════════════════════════════════ // HEALTH PACKAGES // ═══════════════════════════════════════════ console.log('📦 Health Packages'); await mk('healthPackage', { name: 'Master Health Checkup', packageName: 'Master Health Checkup', description: 'Comprehensive annual health screening — blood work, ECG, chest X-ray, BMI, vision, dental', price: { amountMicros: 2_999_000_000, currencyCode: 'INR' }, department: 'PREVENTIVE', inclusions: 'CBC, Lipid Profile, Liver Function, Kidney Function, Thyroid, Blood Sugar, ECG, Chest X-ray, BMI, Vision Test, Dental Check', durationMin: 180, eligibility: 'All adults above 18 years', active: true, clinicId: koramangala, }); console.log(' Master Health Checkup — ₹2,999'); await mk('healthPackage', { name: 'Cardiac Screening', packageName: 'Cardiac Screening', description: 'Heart health assessment — ECG, Echo, TMT, lipid panel, cardiac risk markers', price: { amountMicros: 4_999_000_000, currencyCode: 'INR' }, department: 'CARDIOLOGY', inclusions: 'ECG, 2D Echocardiogram, TMT (Treadmill Test), Lipid Profile, hs-CRP, Homocysteine, HbA1c, Cardiologist Consultation', durationMin: 240, eligibility: 'Adults above 30 or family history of heart disease', active: true, clinicId: koramangala, }); console.log(' Cardiac Screening — ₹4,999'); await mk('healthPackage', { name: "Women's Wellness Package", packageName: "Women's Wellness Package", description: 'Complete women\'s health screening — PAP smear, mammogram, hormone panel, bone density', price: { amountMicros: 3_499_000_000, currencyCode: 'INR' }, department: 'GYNECOLOGY', inclusions: 'PAP Smear, Mammogram, Pelvic Ultrasound, Thyroid Panel, Vitamin D, Calcium, CBC, Hormone Panel (FSH/LH/Estradiol), Bone Density Scan, Gynecologist Consultation', durationMin: 210, eligibility: 'Women above 25 years', active: true, clinicId: indiranagar, }); console.log(" Women's Wellness — ₹3,499"); await mk('healthPackage', { name: 'Orthopedic Assessment', packageName: 'Orthopedic Assessment', description: 'Joint and bone health evaluation — X-rays, bone density, vitamin levels, specialist consult', price: { amountMicros: 1_999_000_000, currencyCode: 'INR' }, department: 'ORTHOPEDICS', inclusions: 'Joint X-rays (knee/hip/spine), Bone Density Scan, Vitamin D, Calcium, Uric Acid, RA Factor, Orthopedic Consultation', durationMin: 120, eligibility: 'Adults with joint pain or age above 40', active: true, clinicId: whitefield, }); console.log(' Orthopedic Assessment — ₹1,999'); await mk('healthPackage', { name: 'IVF Consultation Package', packageName: 'IVF Consultation Package', description: 'Initial fertility assessment — hormone panel, ultrasound, semen analysis, specialist consult', price: { amountMicros: 5_999_000_000, currencyCode: 'INR' }, discountedPrice: { amountMicros: 0, currencyCode: 'INR' }, department: 'GYNECOLOGY', inclusions: 'AMH, FSH, LH, Estradiol, Prolactin, Thyroid Panel, Transvaginal Ultrasound, Semen Analysis, Fertility Specialist Consultation', durationMin: 150, eligibility: 'Couples planning IVF or facing infertility (1+ year)', active: true, clinicId: indiranagar, }); console.log(' IVF Consultation — ₹5,999 (free first visit via campaign)\n'); await auth(); // ═══════════════════════════════════════════ // INSURANCE PARTNERS // ═══════════════════════════════════════════ console.log('🛡️ Insurance Partners'); await mk('insurancePartner', { name: 'Star Health Insurance', insurerName: 'Star Health', tpaName: 'Star Health & Allied Insurance', planTypesAccepted: 'Family Health Optima, Comprehensive, Senior Citizen Red Carpet', settlementType: 'BOTH', empanelmentStatus: 'ACTIVE', validUntil: '2027-03-31', contactPerson: 'Rajesh M', contactPhone: { primaryPhoneNumber: '9900200001', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: koramangala, }); console.log(' Star Health — cashless + reimbursement'); await mk('insurancePartner', { name: 'ICICI Lombard', insurerName: 'ICICI Lombard', tpaName: 'Medi Assist', planTypesAccepted: 'iHealth, Complete Health Insurance, Group Mediclaim', settlementType: 'CASHLESS', empanelmentStatus: 'ACTIVE', validUntil: '2027-06-30', contactPerson: 'Priya K', contactPhone: { primaryPhoneNumber: '9900200002', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: koramangala, }); console.log(' ICICI Lombard — cashless'); await mk('insurancePartner', { name: 'Bajaj Allianz', insurerName: 'Bajaj Allianz', tpaName: 'Health India TPA', planTypesAccepted: 'Health Guard, Silver Health, Group Health', settlementType: 'BOTH', empanelmentStatus: 'ACTIVE', validUntil: '2027-01-31', contactPerson: 'Suresh V', contactPhone: { primaryPhoneNumber: '9900200003', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: whitefield, }); console.log(' Bajaj Allianz — cashless + reimbursement'); await mk('insurancePartner', { name: 'HDFC Ergo', insurerName: 'HDFC Ergo', tpaName: 'Paramount Health Services', planTypesAccepted: 'Optima Secure, Optima Restore, My Health Suraksha', settlementType: 'CASHLESS', empanelmentStatus: 'ACTIVE', validUntil: '2027-09-30', contactPerson: 'Anita S', contactPhone: { primaryPhoneNumber: '9900200004', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: indiranagar, }); console.log(' HDFC Ergo — cashless'); await mk('insurancePartner', { name: 'Niva Bupa (Max Bupa)', insurerName: 'Niva Bupa', tpaName: 'Niva Bupa Health Insurance', planTypesAccepted: 'Health Recharge, Health Premia, ReAssure 2.0', settlementType: 'BOTH', empanelmentStatus: 'ACTIVE', validUntil: '2027-04-30', contactPerson: 'Deepak R', contactPhone: { primaryPhoneNumber: '9900200005', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: koramangala, }); console.log(' Niva Bupa — cashless + reimbursement'); await mk('insurancePartner', { name: 'New India Assurance', insurerName: 'New India Assurance', tpaName: 'Raksha TPA', planTypesAccepted: 'Mediclaim Policy, Jan Arogya Bima, Group Mediclaim', settlementType: 'REIMBURSEMENT', empanelmentStatus: 'ACTIVE', validUntil: '2027-12-31', contactPerson: 'Mohan T', contactPhone: { primaryPhoneNumber: '9900200006', primaryPhoneCallingCode: '+91', primaryPhoneCountryCode: 'IN' }, clinicId: whitefield, }); console.log(' New India Assurance — reimbursement\n'); // ═══════════════════════════════════════════ // CLEANUP: Delete the empty doctor record // ═══════════════════════════════════════════ try { await gql(`mutation { deleteDoctor(id: "967e1959-9b85-497e-9f8e-cad65120c5de") { id } }`); console.log('🧹 Cleaned up empty doctor record\n'); } catch { // Ignore if already deleted } console.log('🎉 Done!'); console.log(' 3 clinics · 5 health packages · 6 insurance partners'); console.log(' 5 doctors linked to clinics'); } main().catch(e => { console.error('💥', e.message); process.exit(1); });