import 'dotenv/config'; import db from '../src/database/models/index.js'; import bcrypt from 'bcryptjs'; import { ROLES, APPLICATION_STAGES, APPLICATION_STATUS } from '../src/common/config/constants.js'; import { resolveManagerCode } from '../src/services/userRoleCode.service.js'; const { Role, User, UserRole, Zone, State, Region, Location } = db; async function masterReset() { console.log('--- RELOADING DATABASE FOR OFFBOARDING TEST ---'); try { await db.sequelize.authenticate(); // 1. Force Sync (Drop and Recreate) await db.sequelize.sync({ force: true }); console.log('✅ Schema reset complete.'); const hashedPassword = await bcrypt.hash('Admin@123', 10); // 2. Seed All Roles const rolesToSeed = Object.values(ROLES).map(code => ({ roleCode: code, roleName: code, category: 'SYSTEM' })); for (const r of rolesToSeed) { await Role.create(r); } console.log('✅ Roles seeded.'); // 3. Seed Basic Hierarchy const { District } = db; const zone = await Zone.create({ name: 'North', code: 'N' }); const state = await State.create({ name: 'Delhi', zoneId: zone.id }); const region = await Region.create({ name: 'NCR', zoneId: zone.id }); // Create South Delhi District and link to NCR Region const district = await District.create({ name: 'South Delhi', stateId: state.id, regionId: region.id, zoneId: zone.id, isActive: true }); const loc = await Location.create({ name: 'Central Delhi', stateId: state.id, regionId: region.id, zoneId: zone.id, districtId: district.id }); console.log('✅ Hierarchy seeded with South Delhi District.'); // 4. Seed Essential Users const users = [ { email: 'admin@royalenfield.com', fullName: 'Super Admin', roleCode: ROLES.SUPER_ADMIN }, { email: 'ddlead@royalenfield.com', fullName: 'Meera Iyer (DD Lead)', roleCode: ROLES.DD_LEAD }, { email: 'nbh@royalenfield.com', fullName: 'NBH Head', roleCode: ROLES.NBH }, { email: 'cco@royalenfield.com', fullName: 'Ashok Singh (CCO)', roleCode: ROLES.CCO }, { email: 'ceo@royalenfield.com', fullName: 'Siddhartha Lal (CEO)', roleCode: ROLES.CEO }, { email: 'spares@royalenfield.com', fullName: 'Spares Clearance Mgr', roleCode: ROLES.SPARES_MANAGER }, { email: 'service@royalenfield.com', fullName: 'Service Clearance Mgr', roleCode: ROLES.SERVICE_MANAGER }, { email: 'accounts@royalenfield.com', fullName: 'Accounts Clearance Mgr', roleCode: ROLES.ACCOUNTS_MANAGER }, { email: 'finance@royalenfield.com', fullName: 'Rahul Verma (Finance)', roleCode: ROLES.FINANCE }, { email: 'legal@royalenfield.com', fullName: 'Legal Admin', roleCode: ROLES.LEGAL_ADMIN }, { email: 'dealer@royalenfield.com', fullName: 'Dealer One', roleCode: ROLES.DEALER, isExternal: true }, { email: 'asm@royalenfield.com', fullName: 'Sales Manager (ASM)', roleCode: ROLES.ASM }, { email: 'rbm@royalenfield.com', fullName: 'Regional Business Mgr', roleCode: ROLES.RBM }, { email: 'ddzm@royalenfield.com', fullName: 'Zonal Manager (DD ZM)', roleCode: ROLES.DD_ZM }, { email: 'zbh@royalenfield.com', fullName: 'Zonal Head (ZBH)', roleCode: ROLES.ZBH }, { email: 'ddhead@royalenfield.com', fullName: 'Vikram Singh (DD Head)', roleCode: ROLES.DD_HEAD } ]; for (const u of users) { const user = await User.create({ ...u, password: hashedPassword, status: 'active' }); const role = await Role.findOne({ where: { roleCode: u.roleCode } }); if (role) { // Map assignments based on role category (Regional vs Granular) const isRegionalRole = [ROLES.RBM, ROLES.DD_ZM, ROLES.ZBH].includes(u.roleCode as any); const isGranularRole = [ROLES.ASM].includes(u.roleCode as any); const managerCode = await resolveManagerCode(role.id, u.roleCode as string, null); await UserRole.create({ userId: user.id, roleId: role.id, isActive: true, isPrimary: true, zoneId: isRegionalRole || isGranularRole ? zone.id : null, regionId: isRegionalRole ? region.id : null, districtId: isGranularRole ? district.id : null, managerCode }); } } console.log('✅ Standard Users seeded.'); // 5. Seed a Dealer record for testing const { Application, Dealer, Outlet } = db; const dealerUser = await User.findOne({ where: { email: 'dealer@royalenfield.com' } }); if (dealerUser) { // First create a mandatory Application as per model constraints // We use 'Approved' stage and 'Onboarded' status to simulate a completed onboarding const [application] = await Application.findOrCreate({ where: { applicationId: 'APP-STABLE-001' }, defaults: { applicationId: 'APP-STABLE-001', applicantName: dealerUser.fullName, email: dealerUser.email, phone: '9876543210', businessType: 'Dealership', userId: dealerUser.id, currentStage: APPLICATION_STAGES.APPROVED, overallStatus: APPLICATION_STATUS.ONBOARDED, progressPercentage: 100, isShortlisted: true } }); const dealer = await Dealer.create({ applicationId: application.id, legalName: 'Dealer One Motors Private Limited', businessName: 'Dealer One Motors', constitutionType: 'Private Limited', dealerCode: 'D001', status: 'Active', onboardedAt: new Date() }); // Update user to link to dealer profile await dealerUser.update({ dealerId: dealer.id }); await db.Outlet.create({ dealerId: dealer.id, name: 'Main Outlet', code: 'O001', type: 'Dealership', address: '123, MG Road, South Delhi', city: 'Delhi', state: 'Delhi', pincode: '110001', establishedDate: '2020-01-01', districtId: district.id, status: 'Active' }); } console.log('✅ Test Application, Dealer & Outlet created.'); console.log('--- SYSTEM READY FOR OFFBOARDING TESTING ---'); process.exit(0); } catch (error) { console.error('❌ Reset failed:', error); process.exit(1); } } masterReset();