import { PrismaClient } from '@prisma/client' import { PrismaPg } from '@prisma/adapter-pg' import { Pool } from 'pg' import * as fs from 'fs' import * as path from 'path' import * as dotenv from 'dotenv' // Load environment variables dotenv.config() const pool = new Pool({ connectionString: process.env.DATABASE_URL }) const adapter = new PrismaPg(pool) const prisma = new PrismaClient({ adapter }) interface CsvRow { task: string daysAfterRenewal: number daysPriorToNextRenewal: number appliesTo: string active: boolean } function parseCsv(content: string): CsvRow[] { const lines = content.trim().split('\n') // Skip header row, handle BOM const dataLines = lines.slice(1) return dataLines.map((line) => { const parts = line.split(',') return { task: parts[0].trim(), daysAfterRenewal: parseInt(parts[1].trim()), daysPriorToNextRenewal: parseInt(parts[2].trim()), appliesTo: parts[3].trim(), active: parts[4].trim().toLowerCase() === 'yes', } }) } async function main() { console.log('Importing SHAPE tasks from CSV...') // Read CSV file const csvPath = path.join(__dirname, '../../dev/shapetasks.csv') const csvContent = fs.readFileSync(csvPath, 'utf-8') const rows = parseCsv(csvContent) console.log(`Found ${rows.length} tasks to import`) // Ensure Shape and Shape2 designations exist const shapeDesignation = await prisma.designation.upsert({ where: { name: 'Shape' }, update: {}, create: { name: 'Shape', description: 'SHAPE program - primary designation for claims workflow tasks', color: 'designation-indigo', displayOrder: 10, isActive: true, }, }) console.log(`Shape designation ID: ${shapeDesignation.id}`) const shape2Designation = await prisma.designation.upsert({ where: { name: 'Shape2' }, update: {}, create: { name: 'Shape2', description: 'SHAPE program - secondary designation for claims workflow tasks', color: 'designation-violet', displayOrder: 11, isActive: true, }, }) console.log(`Shape2 designation ID: ${shape2Designation.id}`) // Import task templates let created = 0 let skipped = 0 for (let i = 0; i < rows.length; i++) { const row = rows[i] const designationId = row.appliesTo === 'Shape' ? shapeDesignation.id : shape2Designation.id // Check if template already exists with same name and designation const existing = await prisma.taskTemplate.findFirst({ where: { name: row.task, designationId: designationId, }, }) if (existing) { console.log(`Skipping existing: "${row.task}" (${row.appliesTo})`) skipped++ continue } // Create template using PRE_RENEWAL timing with negative offset await prisma.taskTemplate.create({ data: { name: row.task, description: null, department: 'CLAIMS', timing: 'PRE_RENEWAL', daysOffset: -row.daysPriorToNextRenewal, // Negative for pre-renewal defaultPriority: 'MEDIUM', isActive: row.active, displayOrder: i + 1, designationId: designationId, }, }) console.log(`Created: "${row.task}" (${row.appliesTo}, ${row.daysPriorToNextRenewal} days before renewal)`) created++ } console.log(`\nImport complete: ${created} created, ${skipped} skipped`) } main() .catch((e) => { console.error('Import failed:', e) process.exit(1) }) .finally(async () => { await prisma.$disconnect() await pool.end() })