From 8da431a6cdc7dde76465d166638c3e6bdd12ad9d Mon Sep 17 00:00:00 2001 From: saridsa2 Date: Fri, 10 Apr 2026 17:18:48 +0530 Subject: [PATCH] =?UTF-8?q?feat:=20Ramaiah=20hospital=20seed=20script=20?= =?UTF-8?q?=E2=80=94=20195=20doctors=20from=20website=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/seed-ramaiah.ts | 117 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 scripts/seed-ramaiah.ts diff --git a/scripts/seed-ramaiah.ts b/scripts/seed-ramaiah.ts new file mode 100644 index 0000000..4df79bb --- /dev/null +++ b/scripts/seed-ramaiah.ts @@ -0,0 +1,117 @@ +/** + * Helix Engage โ€” Ramaiah Hospital Data Seeder + * + * Seeds clinic + 195 doctors from scraped website data. + * Run: cd helix-engage && SEED_GQL=https://ramaiah.app.healix360.net/graphql SEED_SUB=ramaiah SEED_ORIGIN=https://ramaiah.app.healix360.net npx tsx scripts/seed-ramaiah.ts + */ +import { readFileSync } from 'fs'; + +const GQL = process.env.SEED_GQL ?? 'http://localhost:4000/graphql'; +const SUB = process.env.SEED_SUB ?? 'ramaiah'; +const ORIGIN = process.env.SEED_ORIGIN ?? 'http://ramaiah.localhost:5080'; +const DATA_FILE = process.env.SEED_DATA ?? '/tmp/ramaiah-seed-data.json'; + +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 main() { + console.log('๐ŸŒฑ Seeding Ramaiah Hospital data...\n'); + + const raw = JSON.parse(readFileSync(DATA_FILE, 'utf-8')); + console.log(`๐Ÿ“ Loaded ${raw.doctors.length} doctors, ${raw.departments.length} departments\n`); + + await auth(); + console.log('โœ… Auth OK\n'); + + // Clinic + console.log('๐Ÿฅ Clinic'); + const clinicId = await mk('clinic', { + name: raw.clinic.name, + clinicName: raw.clinic.name, + status: 'ACTIVE', + opensAt: '08:00', + closesAt: '20:00', + openMonday: true, openTuesday: true, openWednesday: true, + openThursday: true, openFriday: true, openSaturday: true, openSunday: false, + phone: { + primaryPhoneNumber: raw.clinic.phone?.replace(/[^0-9]/g, '').slice(-10) ?? '', + primaryPhoneCallingCode: '+91', + primaryPhoneCountryCode: 'IN', + }, + addressCustom: { + addressStreet1: raw.clinic.address?.split(',')[0] ?? 'New BEL Road', + addressCity: raw.clinic.city ?? 'Bangalore', + addressState: raw.clinic.state ?? 'Karnataka', + addressCountry: 'India', + addressPostcode: raw.clinic.pincode ?? '560054', + }, + onlineBooking: true, + walkInAllowed: true, + }); + console.log(` ${raw.clinic.name}: ${clinicId}\n`); + + // Re-auth (long operation ahead) + await auth(); + + // Doctors โ€” batch in groups of 20 with re-auth + console.log(`๐Ÿ‘จโ€โš•๏ธ Doctors (${raw.doctors.length})`); + let created = 0; + let failed = 0; + + for (let i = 0; i < raw.doctors.length; i++) { + // Re-auth every 40 doctors (token may expire on long runs) + if (i > 0 && i % 40 === 0) { + await auth(); + console.log(` (re-authed at ${i})`); + } + + const doc = raw.doctors[i]; + const firstName = doc.name.replace(/^Dr\.?\s*/i, '').split(' ')[0] ?? ''; + const lastNameParts = doc.name.replace(/^Dr\.?\s*/i, '').split(' ').slice(1); + const lastName = lastNameParts.join(' '); + + try { + await mk('doctor', { + name: doc.name, + fullName: { firstName, lastName }, + department: doc.department ?? 'Other', + specialty: doc.designation ?? 'Consultant', + qualifications: doc.qualifications ?? '', + registrationNumber: '', + active: true, + }); + created++; + if (created % 20 === 0) console.log(` ${created}/${raw.doctors.length} created...`); + } catch (err: any) { + failed++; + console.error(` โœ— ${doc.name}: ${err.message?.slice(0, 80)}`); + } + } + + console.log(`\n โœ… ${created} doctors created, ${failed} failed\n`); + console.log('๐ŸŽ‰ Ramaiah seed complete!'); + console.log(` 1 clinic ยท ${created} doctors ยท ${raw.departments.length} departments`); +} + +main().catch(e => { console.error('๐Ÿ’ฅ', e.message); process.exit(1); });