import { PrismaClient } from '@prisma/client'; import * as XLSX from 'xlsx'; import * as path from 'path'; import * as fs from 'fs'; interface IcdData { code: string; display: string; version: string; } export class IcdSeeder { private readonly prisma = new PrismaClient(); async seed(): Promise<{ icd9Count: number; icd10Count: number; total: number; }> { try { console.log('Starting ICD data import...'); // Import ICD-9 data const icd9Data = this.readExcelFile( 'prisma/seed/icd/[PUBLIC] ICD-9CM e-klaim.xlsx', 'ICD9', ); // Import ICD-10 data const icd10Data = this.readExcelFile( 'prisma/seed/icd/[PUBLIC] ICD-10 e-klaim.xlsx', 'ICD10', ); // Clear existing data await this.prisma.icdCode.deleteMany({}); console.log('Cleared existing ICD data'); // Insert ICD-9 data const icd9Count = await this.bulkInsertData(icd9Data, 'ICD9'); console.log(`Imported ${icd9Count} ICD-9 codes`); // Insert ICD-10 data const icd10Count = await this.bulkInsertData(icd10Data, 'ICD10'); console.log(`Imported ${icd10Count} ICD-10 codes`); const total = icd9Count + icd10Count; console.log(`Total imported: ${total} ICD codes`); return { icd9Count, icd10Count, total, }; } catch (error) { console.error('Error importing ICD data:', error); throw error; } } private readExcelFile(filePath: string, category: string): IcdData[] { try { const fullPath = path.join(process.cwd(), filePath); if (!fs.existsSync(fullPath)) { throw new Error(`File not found: ${fullPath}`); } console.log(`Reading ${category} file: ${filePath}`); const workbook = XLSX.readFile(fullPath); const sheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[sheetName]; // Convert sheet to JSON const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // Skip header row and process data const icdData: IcdData[] = []; for (let i = 1; i < jsonData.length; i++) { const row = jsonData[i] as any[]; if (row && row.length >= 3) { const code = this.cleanString(row[0]); const display = this.cleanString(row[1]); const version = this.cleanString(row[2]); if (code && display && version) { icdData.push({ code, display, version, }); } } } console.log(`Found ${icdData.length} valid ${category} records`); return icdData; } catch (error) { console.error(`Error reading ${category} file:`, error); throw error; } } private async bulkInsertData( data: IcdData[], category: string, ): Promise { try { const batchSize = 1000; let totalInserted = 0; for (let i = 0; i < data.length; i += batchSize) { const batch = data.slice(i, i + batchSize); const insertData = batch.map((item) => ({ code: item.code, display: item.display, version: item.version, category, })); await this.prisma.icdCode.createMany({ data: insertData, skipDuplicates: true, }); totalInserted += batch.length; console.log( `Inserted batch ${Math.floor(i / batchSize) + 1} for ${category}: ${batch.length} records`, ); } return totalInserted; } catch (error) { console.error(`Error inserting ${category} data:`, error); throw error; } } private cleanString(value: any): string { if (value === null || value === undefined) { return ''; } return String(value).trim(); } async disconnect() { await this.prisma.$disconnect(); } } // Standalone execution if (require.main === module) { const seeder = new IcdSeeder(); seeder .seed() .then((result) => { console.log('ICD seeding completed successfully:', result); }) .catch((error) => { console.error('ICD seeding failed:', error); process.exit(1); }) .finally(() => { void seeder.disconnect(); }); }