import { hash, genSalt } from "bcrypt"; import { db } from "../config/database.ts"; import { config } from "../config/env.ts"; // Helper function to hash password with proper salt generation async function hashPassword(password: string): Promise { const salt = await genSalt(config.BCRYPT_ROUNDS); return await hash(password, salt); } async function seedDatabase() { try { console.log("🔌 Connecting to database..."); await db.connect(); console.log("✅ Connected to database\n"); // 1. Seed Departments console.log("📁 Seeding departments..."); const existingDepts = await db.query<{ count: number }[]>( "SELECT COUNT(*) as count FROM departments" ); if (existingDepts[0].count === 0) { await db.execute(` INSERT INTO departments (name) VALUES ('Tudki'), ('Dana'), ('Groundnut') `); console.log(" ✅ Departments created"); } else { console.log(" â„šī¸ Departments already exist"); } // 2. Seed Sub-departments and Activities for all departments console.log("📂 Seeding sub-departments and activities..."); // Get department IDs const tudkiDeptResult = await db.query<{ id: number }[]>( "SELECT id FROM departments WHERE name = ?", ["Tudki"] ); const danaDeptResult = await db.query<{ id: number }[]>( "SELECT id FROM departments WHERE name = ?", ["Dana"] ); const groundnutDeptResult = await db.query<{ id: number }[]>( "SELECT id FROM departments WHERE name = ?", ["Groundnut"] ); const tudkiId = tudkiDeptResult[0]?.id; const danaId = danaDeptResult[0]?.id; const groundnutId = groundnutDeptResult[0]?.id; // Define sub-departments and activities per department based on activities.md const departmentData: { [key: number]: { subDept: string; activities: { name: string; unit: string }[] }[] } = {}; if (groundnutId) { departmentData[groundnutId] = [ { subDept: "Loading/Unloading", activities: [ { name: "Mufali Aavak Katai (Groundnut Arrival Cutting)", unit: "Per Bag" }, { name: "Mufali Aavak Dhaang (Groundnut Arrival Stacking)", unit: "Per Bag" }, { name: "Dhaang Se Katai (Cutting from Stack)", unit: "Per Bag" }, { name: "Guthli Bori Silai Dhaang (Kernel Bag Stitching Stack)", unit: "Per Bag" }, { name: "Guthali dhada Pala Tulai Silai Dhaang / Loading", unit: "Per Bag" }, { name: "Mufali Patthar Bori silai Dhaang", unit: "Per Bag" }, { name: "Mufali Patthar Bori Utrai (Groundnut Stone Bag Unloading)", unit: "Per Bag" }, { name: "Bardana Bandal Loading (Gunny Bundle Loading)", unit: "Per Bag" }, { name: "Bardana Gatthi Loading/Unloading", unit: "Per Bag" }, { name: "Black Dana Loading/Unloading", unit: "Per Bag" }, { name: "Dala - Chomu & Jaipur (Branch)", unit: "Per Bag" }, ] }, { subDept: "Pre Cleaning", activities: [{ name: "Pre Cleaner", unit: "Fixed Rate-Per Person" }] }, { subDept: "Destoner", activities: [{ name: "Destoner", unit: "Fixed Rate-Per Person" }] }, { subDept: "Water", activities: [{ name: "Water", unit: "Fixed Rate-Per Person" }] }, { subDept: "Decordicater & Cleaning and Round Chalna", activities: [ { name: "Decordicater", unit: "Fixed Rate-Per Person" }, { name: "Round Chalna (Round Sieving)", unit: "Fixed Rate-Per Person" }, { name: "Cleaning", unit: "Fixed Rate-Per Person" }, ] }, { subDept: "Round Chalna No.1", activities: [{ name: "Round Chalna No.1 (Round Sieving No.1)", unit: "Fixed Rate-Per Person" }] }, ]; } if (danaId) { departmentData[danaId] = [ { subDept: "Loading/Unloading", activities: [ { name: "Tulai Silai Loading (Weighing Stitching Loading)", unit: "Per Bag" }, { name: "Dhaang se Loading (Loading from Stack)", unit: "Per Bag" }, { name: "Silai Dhaang (Stitching Stack)", unit: "Per Bag" }, { name: "Tulai Silai Dhaang Ikai No. 2 Machine ke Pass", unit: "Per Bag" }, { name: "Dana Unloading/Dhaang (Grain Unloading/Stack)", unit: "Per Bag" }, { name: "Dana Aavak Keep Katai (Grain Arrival Hopper Cutting)", unit: "Per Bag" }, { name: "Kachri Dhada Pala Bharai Tulai Silai Load/Dhaang 70kg", unit: "Per Bag" }, { name: "Kachri Dhaang se loading (Waste Loading from Stack)", unit: "Per Bag" }, { name: "Keep Katai Khulla Katta (Hopper Cutting Open Bag)", unit: "Per Bag" }, { name: "Keep Katai Silai Kholkar (Hopper Cutting Opening Stitched)", unit: "Per Bag" }, { name: "Bardana Paltai (Gunny Turning)", unit: "Per Bag" }, { name: "Ekai No. 2 me Keep Katai Khula Bag", unit: "Per Bag" }, { name: "Ekai No. 2 me Keep Katai Silai Kholkar", unit: "Per Bag" }, { name: "Silai Loading Company Gadi Dala Sahit", unit: "Per Bag" }, { name: "Kachri Bharai Silai Dhaang Chatt Par", unit: "Per Bag" }, { name: "Bardana Unloading (Gunny Unloading)", unit: "Per Bag" }, { name: "Grading", unit: "Per Bag" }, ] }, { subDept: "Destoner", activities: [{ name: "Destoner", unit: "Fixed Rate-Per Person" }] }, { subDept: "Gravity", activities: [{ name: "Gravity", unit: "Fixed Rate-Per Person" }] }, { subDept: "Tank", activities: [{ name: "Tank", unit: "Fixed Rate-Per Person" }] }, { subDept: "Sortex", activities: [{ name: "Sortex", unit: "Fixed Rate-Per Person" }] }, { subDept: "X-Ray", activities: [{ name: "X-Ray", unit: "Fixed Rate-Per Person" }] }, { subDept: "Kachri", activities: [{ name: "Kachri (Waste)", unit: "Fixed Rate-Per Person" }] }, { subDept: "Other Works", activities: [{ name: "Other Works", unit: "Fixed Rate-Per Person" }] }, ]; } if (tudkiId) { departmentData[tudkiId] = [ { subDept: "Loading/Unloading", activities: [ { name: "Dana Loading/Unloading (Grain Loading/Unloading)", unit: "Per Bag" }, { name: "Loading/Unloading 40 Kg", unit: "Per Bag" }, { name: "Grading Chalne se Maal Bharai Tulai Silai Dhaang", unit: "Per Bag" }, { name: "Grading Chalne se Maal Bharai Tulai Silai Loading", unit: "Per Bag" }, { name: "Chilka Bharai silai Dhaang (Husk Filling Stitching Stack)", unit: "Per Bag" }, { name: "Keep katai Bahar Se (Hopper Cutting from Outside)", unit: "Per Bag" }, { name: "Keep katai Andar Se (Hopper Cutting from Inside)", unit: "Per Bag" }, { name: "Cartoon Banai Vacume Bharai Tulai Packing and Dhaang", unit: "Per Bag" }, { name: "Cartoon Banai Vacume Bharai Tulai Packing and Loading", unit: "Per Bag" }, { name: "Katta Paltai (Bag Turning)", unit: "Per Bag" }, { name: "Dhada Pala Bharai Tulai Silai Dhaang", unit: "Per Bag" }, { name: "Dhada Pala Bharai Tulai Silai Loading", unit: "Per Bag" }, { name: "Sike Maal Ki Silai Dhaang Andar", unit: "Per Bag" }, { name: "Sike Maal Ki Silai Dhaang Bahar", unit: "Per Bag" }, { name: "Nakku Silai Dhaang Bahar (Rejection Stitching Stack Outside)", unit: "Per Bag" }, ] }, { subDept: "Tank", activities: [{ name: "Tank", unit: "Fixed Rate-Per Person" }] }, { subDept: "Grader (Machine)", activities: [{ name: "Grader (Machine)", unit: "Fixed Rate-Per Person" }] }, { subDept: "Sortex", activities: [{ name: "Sortex", unit: "Fixed Rate-Per Person" }] }, { subDept: "X-Ray", activities: [{ name: "X-Ray", unit: "Fixed Rate-Per Person" }] }, { subDept: "Rejection", activities: [{ name: "Rejection", unit: "Fixed Rate-Per Person" }] }, { subDept: "Store", activities: [{ name: "Store", unit: "Fixed Rate-Per Person" }] }, { subDept: "Roster", activities: [{ name: "Roster", unit: "Fixed Rate-Per Person" }] }, { subDept: "Blancher", activities: [{ name: "Blancher", unit: "Fixed Rate-Per Person" }] }, { subDept: "Other Works", activities: [{ name: "Other Works", unit: "Fixed Rate-Per Person" }] }, ]; } // Check if activities table exists, if not create it try { await db.execute(` CREATE TABLE IF NOT EXISTS activities ( id INT AUTO_INCREMENT PRIMARY KEY, sub_department_id INT NOT NULL, name VARCHAR(255) NOT NULL, unit_of_measurement ENUM('Per Bag', 'Fixed Rate-Per Person') NOT NULL DEFAULT 'Per Bag', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE CASCADE, UNIQUE KEY unique_activity (sub_department_id, name) ) `); } catch (_e) { // Table might already exist } // Seed sub-departments and activities for each department for (const [deptId, subDepts] of Object.entries(departmentData)) { const existingSubDepts = await db.query<{ count: number }[]>( "SELECT COUNT(*) as count FROM sub_departments WHERE department_id = ?", [deptId] ); if (existingSubDepts[0].count === 0) { for (const { subDept, activities } of subDepts) { // Insert sub-department await db.execute( "INSERT INTO sub_departments (department_id, name) VALUES (?, ?)", [deptId, subDept] ); // Get the sub-department ID const subDeptResult = await db.query<{ id: number }[]>( "SELECT id FROM sub_departments WHERE department_id = ? AND name = ?", [deptId, subDept] ); if (subDeptResult.length > 0) { const subDeptId = subDeptResult[0].id; // Insert activities for this sub-department for (const activity of activities) { try { await db.execute( "INSERT INTO activities (sub_department_id, name, unit_of_measurement) VALUES (?, ?, ?)", [subDeptId, activity.name, activity.unit] ); } catch (_e) { // Activity might already exist } } } } } } console.log(" ✅ Sub-departments and activities created"); // 3. Seed SuperAdmin console.log("👤 Seeding SuperAdmin user..."); const existingAdmin = await db.query<{ id: number }[]>( "SELECT id FROM users WHERE username = ?", ["admin"] ); const adminPassword = await hashPassword("admin123"); if (existingAdmin.length > 0) { await db.execute( "UPDATE users SET password = ?, is_active = TRUE WHERE username = ?", [adminPassword, "admin"] ); console.log(" ✅ SuperAdmin password updated"); } else { await db.execute( "INSERT INTO users (username, name, email, password, role, is_active) VALUES (?, ?, ?, ?, ?, ?)", ["admin", "Super Admin", "admin@workallocate.com", adminPassword, "SuperAdmin", true] ); console.log(" ✅ SuperAdmin created"); } // 4. Seed Supervisors for all departments console.log("đŸ‘Ĩ Seeding supervisors..."); const supervisorPassword = await hashPassword("supervisor123"); const supervisors = [ { username: "rajesh.sharma.tudki", name: "Rajesh Sharma", email: "rajesh.sharma@workallocate.com", deptId: tudkiId, phone: "9414567890" }, { username: "sunil.verma.dana", name: "Sunil Verma", email: "sunil.verma@workallocate.com", deptId: danaId, phone: "9414567891" }, { username: "mahesh.agarwal.groundnut", name: "Mahesh Agarwal", email: "mahesh.agarwal@workallocate.com", deptId: groundnutId, phone: "9414567892" } ]; for (const sup of supervisors) { if (sup.deptId) { const existing = await db.query<{ id: number }[]>( "SELECT id FROM users WHERE username = ?", [sup.username] ); if (existing.length === 0) { await db.execute( "INSERT INTO users (username, name, email, password, role, department_id, is_active, phone_number) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [sup.username, sup.name, sup.email, supervisorPassword, "Supervisor", sup.deptId, true, sup.phone] ); console.log(` ✅ ${sup.name} created`); } else { console.log(` â„šī¸ ${sup.name} already exists`); } } } // 5. Seed Contractors for all departments console.log("đŸ—ī¸ Seeding contractors..."); const contractorPassword = await hashPassword("contractor123"); const contractors = [ // Groundnut Department Contractors { username: "ramesh.patel.gn", name: "Ramesh Patel", email: "ramesh.patel@workallocate.com", deptId: groundnutId, phone: "9829012345", aadhar: "234567891234", bankAccount: "50100123456789", bankName: "HDFC Bank", bankIfsc: "HDFC0001234", agreementNo: "AGR-GN-2024-001", pfNo: "RJ/JPR/12345/001", esicNo: "12-34-567890-001-0001" }, { username: "kishan.meena.gn", name: "Kishan Meena", email: "kishan.meena@workallocate.com", deptId: groundnutId, phone: "9829012346", aadhar: "345678912345", bankAccount: "50100123456790", bankName: "State Bank of India", bankIfsc: "SBIN0005678", agreementNo: "AGR-GN-2024-002", pfNo: "RJ/JPR/12345/002", esicNo: "12-34-567890-001-0002" }, // Dana Department Contractors { username: "gopal.sharma.dana", name: "Gopal Sharma", email: "gopal.sharma@workallocate.com", deptId: danaId, phone: "9829012347", aadhar: "456789123456", bankAccount: "50100123456791", bankName: "Punjab National Bank", bankIfsc: "PUNB0009876", agreementNo: "AGR-DN-2024-001", pfNo: "RJ/JPR/12345/003", esicNo: "12-34-567890-002-0001" }, { username: "mohan.yadav.dana", name: "Mohan Yadav", email: "mohan.yadav@workallocate.com", deptId: danaId, phone: "9829012348", aadhar: "567891234567", bankAccount: "50100123456792", bankName: "Bank of Baroda", bankIfsc: "BARB0004567", agreementNo: "AGR-DN-2024-002", pfNo: "RJ/JPR/12345/004", esicNo: "12-34-567890-002-0002" }, // Tudki Department Contractors { username: "suresh.kumar.tudki", name: "Suresh Kumar", email: "suresh.kumar@workallocate.com", deptId: tudkiId, phone: "9829012349", aadhar: "678912345678", bankAccount: "50100123456793", bankName: "ICICI Bank", bankIfsc: "ICIC0003456", agreementNo: "AGR-TK-2024-001", pfNo: "RJ/JPR/12345/005", esicNo: "12-34-567890-003-0001" }, { username: "dinesh.gupta.tudki", name: "Dinesh Gupta", email: "dinesh.gupta@workallocate.com", deptId: tudkiId, phone: "9829012350", aadhar: "789123456789", bankAccount: "50100123456794", bankName: "Axis Bank", bankIfsc: "UTIB0002345", agreementNo: "AGR-TK-2024-002", pfNo: "RJ/JPR/12345/006", esicNo: "12-34-567890-003-0002" } ]; for (const con of contractors) { const existing = await db.query<{ id: number }[]>( "SELECT id FROM users WHERE username = ?", [con.username] ); if (existing.length === 0) { await db.execute( `INSERT INTO users (username, name, email, password, role, department_id, is_active, phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc, contractor_agreement_number, pf_number, esic_number) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [con.username, con.name, con.email, contractorPassword, "Contractor", con.deptId, true, con.phone, con.aadhar, con.bankAccount, con.bankName, con.bankIfsc, con.agreementNo, con.pfNo, con.esicNo] ); console.log(` ✅ ${con.name} created`); } else { console.log(` â„šī¸ ${con.name} already exists`); } } // 6. Seed Employees for all departments console.log("👷 Seeding employees..."); const employeePassword = await hashPassword("employee123"); // Get contractor IDs for employee assignment const contractorIds: { [key: string]: number } = {}; for (const con of contractors) { const result = await db.query<{ id: number }[]>( "SELECT id FROM users WHERE username = ?", [con.username] ); if (result.length > 0) { contractorIds[con.username] = result[0].id; } } const employees = [ // Groundnut Department Employees - Under Ramesh Patel { username: "ravi.singh.gn1", name: "Ravi Singh", email: "ravi.singh@workallocate.com", deptId: groundnutId, contractorUsername: "ramesh.patel.gn", phone: "9876501001", aadhar: "111122223333", bankAccount: "30100111122233", bankName: "State Bank of India", bankIfsc: "SBIN0001111" }, { username: "amit.kumar.gn2", name: "Amit Kumar", email: "amit.kumar@workallocate.com", deptId: groundnutId, contractorUsername: "ramesh.patel.gn", phone: "9876501002", aadhar: "222233334444", bankAccount: "30100222233344", bankName: "Punjab National Bank", bankIfsc: "PUNB0002222" }, { username: "vijay.meena.gn3", name: "Vijay Meena", email: "vijay.meena@workallocate.com", deptId: groundnutId, contractorUsername: "ramesh.patel.gn", phone: "9876501003", aadhar: "333344445555", bankAccount: "30100333344455", bankName: "HDFC Bank", bankIfsc: "HDFC0003333" }, // Groundnut Department Employees - Under Kishan Meena { username: "sanjay.yadav.gn4", name: "Sanjay Yadav", email: "sanjay.yadav@workallocate.com", deptId: groundnutId, contractorUsername: "kishan.meena.gn", phone: "9876501004", aadhar: "444455556666", bankAccount: "30100444455566", bankName: "Bank of Baroda", bankIfsc: "BARB0004444" }, { username: "prakash.sharma.gn5", name: "Prakash Sharma", email: "prakash.sharma@workallocate.com", deptId: groundnutId, contractorUsername: "kishan.meena.gn", phone: "9876501005", aadhar: "555566667777", bankAccount: "30100555566677", bankName: "ICICI Bank", bankIfsc: "ICIC0005555" }, // Dana Department Employees - Under Gopal Sharma { username: "rampal.verma.dn1", name: "Rampal Verma", email: "rampal.verma@workallocate.com", deptId: danaId, contractorUsername: "gopal.sharma.dana", phone: "9876502001", aadhar: "666677778888", bankAccount: "30100666677788", bankName: "State Bank of India", bankIfsc: "SBIN0006666" }, { username: "lakhan.singh.dn2", name: "Lakhan Singh", email: "lakhan.singh@workallocate.com", deptId: danaId, contractorUsername: "gopal.sharma.dana", phone: "9876502002", aadhar: "777788889999", bankAccount: "30100777788899", bankName: "Punjab National Bank", bankIfsc: "PUNB0007777" }, { username: "bharat.meena.dn3", name: "Bharat Meena", email: "bharat.meena@workallocate.com", deptId: danaId, contractorUsername: "gopal.sharma.dana", phone: "9876502003", aadhar: "888899990000", bankAccount: "30100888899900", bankName: "HDFC Bank", bankIfsc: "HDFC0008888" }, // Dana Department Employees - Under Mohan Yadav { username: "kailash.patel.dn4", name: "Kailash Patel", email: "kailash.patel@workallocate.com", deptId: danaId, contractorUsername: "mohan.yadav.dana", phone: "9876502004", aadhar: "999900001111", bankAccount: "30100999900011", bankName: "Bank of Baroda", bankIfsc: "BARB0009999" }, { username: "shyam.gupta.dn5", name: "Shyam Gupta", email: "shyam.gupta@workallocate.com", deptId: danaId, contractorUsername: "mohan.yadav.dana", phone: "9876502005", aadhar: "000011112222", bankAccount: "30100000011122", bankName: "ICICI Bank", bankIfsc: "ICIC0000000" }, // Tudki Department Employees - Under Suresh Kumar { username: "ganesh.kumar.tk1", name: "Ganesh Kumar", email: "ganesh.kumar@workallocate.com", deptId: tudkiId, contractorUsername: "suresh.kumar.tudki", phone: "9876503001", aadhar: "112233445566", bankAccount: "30100112233445", bankName: "State Bank of India", bankIfsc: "SBIN0001122" }, { username: "naresh.yadav.tk2", name: "Naresh Yadav", email: "naresh.yadav@workallocate.com", deptId: tudkiId, contractorUsername: "suresh.kumar.tudki", phone: "9876503002", aadhar: "223344556677", bankAccount: "30100223344556", bankName: "Punjab National Bank", bankIfsc: "PUNB0002233" }, { username: "mukesh.sharma.tk3", name: "Mukesh Sharma", email: "mukesh.sharma@workallocate.com", deptId: tudkiId, contractorUsername: "suresh.kumar.tudki", phone: "9876503003", aadhar: "334455667788", bankAccount: "30100334455667", bankName: "HDFC Bank", bankIfsc: "HDFC0003344" }, // Tudki Department Employees - Under Dinesh Gupta { username: "pappu.singh.tk4", name: "Pappu Singh", email: "pappu.singh@workallocate.com", deptId: tudkiId, contractorUsername: "dinesh.gupta.tudki", phone: "9876503004", aadhar: "445566778899", bankAccount: "30100445566778", bankName: "Bank of Baroda", bankIfsc: "BARB0004455" }, { username: "deepak.verma.tk5", name: "Deepak Verma", email: "deepak.verma@workallocate.com", deptId: tudkiId, contractorUsername: "dinesh.gupta.tudki", phone: "9876503005", aadhar: "556677889900", bankAccount: "30100556677889", bankName: "ICICI Bank", bankIfsc: "ICIC0005566" }, { username: "rahul.meena.tk6", name: "Rahul Meena", email: "rahul.meena@workallocate.com", deptId: tudkiId, contractorUsername: "dinesh.gupta.tudki", phone: "9876503006", aadhar: "667788990011", bankAccount: "30100667788990", bankName: "Axis Bank", bankIfsc: "UTIB0006677" } ]; for (const emp of employees) { const existing = await db.query<{ id: number }[]>( "SELECT id FROM users WHERE username = ?", [emp.username] ); if (existing.length === 0) { const contractorId = contractorIds[emp.contractorUsername]; if (contractorId) { await db.execute( `INSERT INTO users (username, name, email, password, role, department_id, contractor_id, is_active, phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [emp.username, emp.name, emp.email, employeePassword, "Employee", emp.deptId, contractorId, true, emp.phone, emp.aadhar, emp.bankAccount, emp.bankName, emp.bankIfsc] ); console.log(` ✅ ${emp.name} created`); } } else { console.log(` â„šī¸ ${emp.name} already exists`); } } // 7. Seed Contractor Rates for all contractors console.log("💰 Seeding contractor rates..."); const today = new Date().toISOString().split("T")[0]; // Get all sub-departments for rate assignment const allSubDepts = await db.query<{ id: number; name: string; department_id: number }[]>( "SELECT id, name, department_id FROM sub_departments" ); // Create rates for each contractor based on their department for (const [username, contractorId] of Object.entries(contractorIds)) { const existingRate = await db.query<{ id: number }[]>( "SELECT id FROM contractor_rates WHERE contractor_id = ?", [contractorId] ); if (existingRate.length === 0) { // Find the contractor's department const contractor = contractors.find(c => c.username === username); if (contractor) { // Get sub-departments for this contractor's department const deptSubDepts = allSubDepts.filter(sd => sd.department_id === contractor.deptId); // Create rates for Loading/Unloading sub-department (Per Bag rates) const loadingSubDept = deptSubDepts.find(sd => sd.name === "Loading/Unloading"); if (loadingSubDept) { // Get activities for this sub-department const activities = await db.query<{ id: number; name: string }[]>( "SELECT id, name FROM activities WHERE sub_department_id = ? LIMIT 3", [loadingSubDept.id] ); for (const activity of activities) { const rate = 5 + Math.random() * 3; // Random rate between 5-8 per bag await db.execute( "INSERT INTO contractor_rates (contractor_id, sub_department_id, activity, rate, effective_date) VALUES (?, ?, ?, ?, ?)", [contractorId, loadingSubDept.id, activity.name, rate.toFixed(2), today] ); } } // Create fixed rates for other sub-departments const fixedSubDepts = deptSubDepts.filter(sd => sd.name !== "Loading/Unloading"); for (const subDept of fixedSubDepts.slice(0, 2)) { // Limit to 2 fixed rate sub-depts per contractor const rate = 300 + Math.random() * 200; // Random rate between 300-500 per person await db.execute( "INSERT INTO contractor_rates (contractor_id, sub_department_id, rate, effective_date) VALUES (?, ?, ?, ?)", [contractorId, subDept.id, rate.toFixed(2), today] ); } } } } console.log(" ✅ Contractor rates created"); console.log(` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Database seeding completed successfully! 🔑 Default Login Credentials: SuperAdmin: Username: admin Password: admin123 Supervisors (password: supervisor123): - Tudki: rajesh.sharma.tudki - Dana: sunil.verma.dana - Groundnut: mahesh.agarwal.groundnut Contractors (password: contractor123): - Groundnut: ramesh.patel.gn, kishan.meena.gn - Dana: gopal.sharma.dana, mohan.yadav.dana - Tudki: suresh.kumar.tudki, dinesh.gupta.tudki Employees (password: employee123): - Use any employee username like ravi.singh.gn1, rampal.verma.dn1, ganesh.kumar.tk1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ `); } catch (error) { console.error("❌ Error seeding database:", (error as Error).message); Deno.exit(1); } finally { await db.close(); } } await seedDatabase();