mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-05-18 20:08:19 +00:00
115 lines
5.5 KiB
TypeScript
115 lines
5.5 KiB
TypeScript
/**
|
||
* Seed DoctorVisitSlots for all Ramaiah doctors.
|
||
* Assigns default visiting hours based on department patterns.
|
||
* Run after seed-ramaiah.ts has populated doctors + clinic.
|
||
*
|
||
* 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-slots.ts
|
||
*/
|
||
|
||
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';
|
||
|
||
let token = '';
|
||
|
||
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) 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;
|
||
}
|
||
|
||
// Default schedule patterns by department type
|
||
const schedulePatterns: Record<string, { days: string[]; start: string; end: string }> = {
|
||
// Surgical departments: morning OPD
|
||
surgery: { days: ['MONDAY', 'WEDNESDAY', 'FRIDAY', 'SATURDAY'], start: '09:00', end: '13:00' },
|
||
// Medical departments: afternoon OPD
|
||
medicine: { days: ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY'], start: '14:00', end: '17:00' },
|
||
// High-traffic: full day Mon-Sat
|
||
fullDay: { days: ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'], start: '09:00', end: '17:00' },
|
||
// Emergency/Critical: all week
|
||
allWeek: { days: ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'], start: '08:00', end: '20:00' },
|
||
// Specialists: limited days
|
||
specialist: { days: ['TUESDAY', 'THURSDAY', 'SATURDAY'], start: '10:00', end: '14:00' },
|
||
};
|
||
|
||
function getPattern(department: string): { days: string[]; start: string; end: string } {
|
||
const d = department.toLowerCase();
|
||
if (d.includes('emergency') || d.includes('critical care')) return schedulePatterns.allWeek;
|
||
if (d.includes('general medicine') || d.includes('paediatrics') || d.includes('obstetrics')) return schedulePatterns.fullDay;
|
||
if (d.includes('surgery') || d.includes('ortho') || d.includes('neuro')) return schedulePatterns.surgery;
|
||
if (d.includes('cardiology') || d.includes('nephrology') || d.includes('oncology')) return schedulePatterns.medicine;
|
||
if (d.includes('dermatology') || d.includes('psychiatry') || d.includes('rheumatology') || d.includes('endocrinology')) return schedulePatterns.specialist;
|
||
// Default: Mon-Fri mornings
|
||
return { days: ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY'], start: '09:00', end: '13:00' };
|
||
}
|
||
|
||
async function main() {
|
||
console.log('🕐 Seeding visit slots for Ramaiah doctors...\n');
|
||
await auth();
|
||
console.log('✅ Auth OK\n');
|
||
|
||
// Fetch all doctors
|
||
const docData = await gql(`{ doctors(first: 500) { edges { node { id name department } } } }`);
|
||
const doctors = docData.doctors.edges.map((e: any) => e.node);
|
||
console.log(`📋 Found ${doctors.length} doctors\n`);
|
||
|
||
// Fetch clinic
|
||
const clinicData = await gql(`{ clinics(first: 1) { edges { node { id clinicName } } } }`);
|
||
const clinicId = clinicData.clinics.edges[0]?.node.id;
|
||
const clinicName = clinicData.clinics.edges[0]?.node.clinicName ?? 'Clinic';
|
||
if (!clinicId) { console.error('No clinic found!'); process.exit(1); }
|
||
console.log(`🏥 Clinic: ${clinicName} (${clinicId})\n`);
|
||
|
||
let created = 0;
|
||
let failed = 0;
|
||
|
||
for (let i = 0; i < doctors.length; i++) {
|
||
if (i > 0 && i % 40 === 0) {
|
||
await auth();
|
||
console.log(` (re-authed at ${i})`);
|
||
}
|
||
|
||
const doc = doctors[i];
|
||
const pattern = getPattern(doc.department ?? '');
|
||
|
||
for (const day of pattern.days) {
|
||
try {
|
||
await gql(
|
||
`mutation($data: DoctorVisitSlotCreateInput!) { createDoctorVisitSlot(data: $data) { id } }`,
|
||
{
|
||
data: {
|
||
name: `${doc.name} — ${day} ${pattern.start}–${pattern.end}`,
|
||
doctorId: doc.id,
|
||
clinicId,
|
||
dayOfWeek: day,
|
||
startTime: pattern.start,
|
||
endTime: pattern.end,
|
||
},
|
||
},
|
||
);
|
||
created++;
|
||
} catch (err: any) {
|
||
failed++;
|
||
if (failed <= 5) console.error(` ✗ ${doc.name} ${day}: ${err.message?.slice(0, 60)}`);
|
||
}
|
||
}
|
||
|
||
if ((i + 1) % 30 === 0) console.log(` ${i + 1}/${doctors.length} doctors processed (${created} slots)...`);
|
||
}
|
||
|
||
console.log(`\n✅ ${created} visit slots created, ${failed} failed`);
|
||
console.log(` ${doctors.length} doctors × avg ${Math.round(created / doctors.length)} days each`);
|
||
}
|
||
|
||
main().catch(e => { console.error('💥', e.message); process.exit(1); });
|