import { Injectable, Logger } from '@nestjs/common'; import { hashPassword } from '@tria-plc/api-common/utils/argon'; import { EUserStatus } from '@tria-plc/api-common/utils/enums/user.enum'; import { Employee, Organization, Role, User, UserCredential, UserRole, } from '@tria-plc/iamapi-common'; import { DataSource } from 'typeorm'; const SEED_FLAG = 'SEED_FREIGHT_STAFF'; const EDR_ORG_KEY = 'edr_freight'; const STAFF_USERS = [ { email: 'linestaff@edr.local', username: 'linestaff', roleKey: 'edr_line_staff' }, { email: 'director@edr.local', username: 'director', roleKey: 'edr_director' }, { email: 'ceo@edr.local', username: 'ceo', roleKey: 'edr_ceo' }, { email: 'gl@edr.local', username: 'gl', roleKey: 'edr_global_logistics' }, ] as const; @Injectable() export class FreightStaffUsersSeeder { private readonly logger = new Logger(FreightStaffUsersSeeder.name); constructor(private readonly dataSource: DataSource) {} async run() { if (process.env[SEED_FLAG]?.trim().toLowerCase() !== 'true') { this.logger.log(`Skipping freight staff seed because ${SEED_FLAG} is not enabled`); return; } const password = process.env.DEFAULT_PASSWORD?.trim() || '12345678'; await this.dataSource.transaction(async (manager) => { const organization = await manager.getRepository(Organization).findOne({ where: { key: EDR_ORG_KEY }, select: { id: true, key: true }, }); if (!organization) { throw new Error(`missing_organization:${EDR_ORG_KEY}`); } const roleRepository = manager.getRepository(Role); const userRepository = manager.getRepository(User); const userCredentialRepository = manager.getRepository(UserCredential); const userRoleRepository = manager.getRepository(UserRole); const employeeRepository = manager.getRepository(Employee); const hashedPassword = await hashPassword(password); for (const staff of STAFF_USERS) { const role = await roleRepository.findOne({ where: { key: staff.roleKey }, select: { id: true, key: true }, }); if (!role) { throw new Error(`missing_role:${staff.roleKey}`); } let user = await userRepository.findOne({ where: { email: staff.email }, select: { id: true, email: true }, }); if (!user) { user = await userRepository.save( userRepository.create({ email: staff.email, username: staff.username, name: { en: staff.username }, isActive: true, hasSetPassword: true, status: EUserStatus.ACCEPTED, }), ); this.logger.log(`Seeded freight staff user ${staff.email}`); } const activeCredentialExists = await userCredentialRepository.exists({ where: { userId: user.id, isActive: true }, }); if (!activeCredentialExists) { await userCredentialRepository.insert({ userId: user.id, password: hashedPassword, isActive: true, }); } await userRoleRepository.upsert( { userId: user.id, roleId: role.id, organizationId: organization.id, }, { conflictPaths: { userId: true, roleId: true } }, ); const employeeExists = await employeeRepository.exists({ where: { userId: user.id, organizationId: organization.id, isCurrent: true, }, }); if (!employeeExists) { await employeeRepository.insert({ userId: user.id, organizationId: organization.id, isCurrent: true, name: { en: staff.username }, }); } } }); this.logger.log( 'Ensured freight staff users (linestaff@, director@, ceo@, gl@)', ); } }