import 'dotenv/config'; import db from '../src/database/models/index.js'; import bcrypt from 'bcryptjs'; import { syncLocationManagers, syncRegionManager, syncZoneManager } from '../src/modules/master/syncHierarchy.service.js'; const { Role, Zone, Region, State, District, User, UserRole } = db; async function seed() { console.log('--- Seeding Normalized Denormalized Data ---'); await db.sequelize.authenticate(); // Use sync with alter false to match main app behavior await db.sequelize.sync({ alter: false }); const hashedPassword = await bcrypt.hash('Admin@123', 10); // 1. Create Roles const roles = [ { roleCode: 'NBH', roleName: 'National Business Head', category: 'NATIONAL' }, { roleCode: 'DD Head', roleName: 'DD Head', category: 'NATIONAL' }, { roleCode: 'ZBH', roleName: 'Zonal Business Head', category: 'ZONAL' }, { roleCode: 'DD Lead', roleName: 'DD Lead', category: 'ZONAL' }, { roleCode: 'RBM', roleName: 'Regional Business Manager', category: 'REGIONAL' }, { roleCode: 'RM', roleName: 'Regional Manager', category: 'REGIONAL' }, { roleCode: 'DD-ZM', roleName: 'DD Zonal Manager', category: 'ZONAL' }, { roleCode: 'ASM', roleName: 'Area Sales Manager', category: 'AREA' }, { roleCode: 'Super Admin', roleName: 'Super Admin', category: 'NATIONAL' }, { roleCode: 'Finance', roleName: 'Finance', category: 'DEPARTMENT' }, { roleCode: 'Dealer', roleName: 'Dealer', category: 'EXTERNAL' }, { roleCode: 'DD Admin', roleName: 'DD Admin', category: 'ADMIN' }, { roleCode: 'Legal Admin', roleName: 'Legal Admin', category: 'DEPARTMENT' } ]; for (const r of roles) { await Role.findOrCreate({ where: { roleCode: r.roleCode }, defaults: r }); } console.log('Roles seeded.'); // 2. Create Districts (Hierarchy) const [zone1] = await Zone.findOrCreate({ where: { name: 'North Zone' }, defaults: { name: 'North Zone', code: 'ZONE-N' } }); const [zone2] = await Zone.findOrCreate({ where: { name: 'South Zone' }, defaults: { name: 'South Zone', code: 'ZONE-S' } }); const [state1] = await State.findOrCreate({ where: { name: 'Delhi' }, defaults: { name: 'Delhi', zoneId: zone1.id } }); const [region1] = await Region.findOrCreate({ where: { name: 'NCR Region' }, defaults: { name: 'NCR Region', zoneId: zone1.id } }); const [region2] = await Region.findOrCreate({ where: { name: 'Bangalore Region' }, defaults: { name: 'Bangalore Region', zoneId: zone2.id } }); const [district1] = await District.findOrCreate({ where: { name: 'South Delhi District' }, defaults: { name: 'South Delhi District', stateId: state1.id, regionId: region1.id, zoneId: zone1.id } }); console.log('Geographical Hierarchy seeded.'); const mapUserRole = async (userRec: any, roleCode: string, assignment: { zoneId?: string | null, regionId?: string | null, districtId?: string | null } = {}) => { const role = await Role.findOne({ where: { roleCode } }); if (role) { await UserRole.findOrCreate({ where: { userId: userRec.id, roleId: role.id, ...assignment }, defaults: { userId: userRec.id, roleId: role.id, ...assignment, isActive: true, isPrimary: true } }); } }; // 4. Create Users and Map them const nbhResult = await User.findOrCreate({ where: { email: 'nbh@example.com' }, defaults: { fullName: 'National Head', roleCode: 'NBH', password: hashedPassword } }); await mapUserRole(nbhResult[0], 'NBH'); const zbhResult = await User.findOrCreate({ where: { email: 'zbh.north@example.com' }, defaults: { fullName: 'North Zonal Head', roleCode: 'ZBH', password: hashedPassword, employeeId: 'ZBH001' } }); await mapUserRole(zbhResult[0], 'ZBH', { zoneId: zone1.id }); const rmResult = await User.findOrCreate({ where: { email: 'rbm.delhi@example.com' }, defaults: { fullName: 'Delhi Regional Manager', roleCode: 'RM', password: hashedPassword, employeeId: 'RBM001' } }); await mapUserRole(rmResult[0], 'RM', { regionId: region1.id }); // ZM is now mapped to Regions (not Districts) — multi-region support const zmResult = await User.findOrCreate({ where: { email: 'zm.north@example.com' }, defaults: { fullName: 'North Zonal Manager', roleCode: 'DD-ZM', password: hashedPassword, employeeId: 'ZM001' } }); // One UserRole entry per region managed by this ZM await mapUserRole(zmResult[0], 'DD-ZM', { zoneId: zone1.id, regionId: region1.id }); const asmResult = await User.findOrCreate({ where: { email: 'asm.sdelhi@example.com' }, defaults: { fullName: 'South Delhi ASM', roleCode: 'ASM', password: hashedPassword, employeeId: 'ASM001' } }); await mapUserRole(asmResult[0], 'ASM', { districtId: district1.id }); // Mock Users alignment const mockUsers = [ { email: 'ddlead@royalenfield.com', name: 'Meera Iyer', roleCode: 'DD Lead', assignment: { zoneId: zone1.id } }, { email: 'finance@royalenfield.com', name: 'Rahul Verma', roleCode: 'Finance', assignment: {} }, { email: 'dealer@royalenfield.com', name: 'Amit Sharma', roleCode: 'Dealer', assignment: { districtId: district1.id }, isExt: true }, { email: 'admin@royalenfield.com', name: 'Laxman H', roleCode: 'DD Lead', assignment: { zoneId: zone2.id } }, { email: 'yashwin@gmail.com', name: 'Yashwin', roleCode: 'ZBH', assignment: { zoneId: zone1.id } }, { email: 'kenil@gmail.com', name: 'Kenil', roleCode: 'DD Lead', assignment: { zoneId: zone1.id } }, { email: 'lince@gmail.com', name: 'Lince', roleCode: 'DD Admin', assignment: {} } ]; for (const m of mockUsers) { const [u] = await User.findOrCreate({ where: { email: m.email }, defaults: { fullName: m.name, roleCode: m.roleCode, password: hashedPassword, isExternal: (m as any).isExt || false, status: 'active' } }); await mapUserRole(u, m.roleCode, m.assignment); } console.log('Users and Mappings seeded.'); console.log('--- Triggering Hierarchy Synchronization ---'); // syncLocationManagers now resolves zmId from the region parent — so districts get updated automatically const districtList = await District.findAll({ attributes: ['id'] }); for (const d of districtList) await syncLocationManagers(d.id); const regionList = await Region.findAll({ attributes: ['id'] }); for (const r of regionList) await syncRegionManager(r.id); const zoneList = await Zone.findAll({ attributes: ['id'] }); for (const z of zoneList) await syncZoneManager(z.id); console.log('--- Seeding & Synchronization Complete ---'); } seed().catch(err => { console.error(err); process.exit(1); }).then(() => process.exit(0));