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 { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; const SEED_FLAG = 'SEED_PASSENGER_STAFF'; const EDR_ORG_KEY = 'edr'; const STAFF_USERS = [ { email: 'passenger.admin@edr.local', username: 'passenger_admin', roleKey: 'edr_passenger_backoffice_admin' }, { email: 'passenger.staff@edr.local', username: 'passenger_staff', roleKey: 'edr_passenger_backoffice_staff' }, { email: 'passenger.agent@edr.local', username: 'passenger_agent', roleKey: 'edr_passenger_agent' }, { email: 'passenger.finance@edr.local', username: 'passenger_finance', roleKey: 'edr_passenger_finance' }, ] as const; @Injectable() export class PassengerStaffUsersSeeder { private readonly logger = new Logger(PassengerStaffUsersSeeder.name); constructor(@InjectDataSource() private readonly dataSource: DataSource) {} async run() { if (process.env[SEED_FLAG]?.trim().toLowerCase() !== 'true') { this.logger.log(`Skipping passenger 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 hashedPassword = await hashPassword(password); for (const staff of STAFF_USERS) { const role = await manager.getRepository(Role).findOne({ where: { key: staff.roleKey }, select: { id: true, key: true }, }); if (!role) throw new Error(`missing_role:${staff.roleKey}`); let user = await manager.getRepository(User).findOne({ where: { email: staff.email }, select: { id: true, email: true }, }); if (!user) { user = await manager.getRepository(User).save( manager.getRepository(User).create({ email: staff.email, username: staff.username, name: { en: staff.username }, isActive: true, hasSetPassword: true, status: EUserStatus.ACCEPTED, }), ); this.logger.log(`Seeded passenger staff user ${staff.email}`); } const credentialExists = await manager.getRepository(UserCredential).exists({ where: { userId: user.id, isActive: true }, }); if (!credentialExists) { await manager.getRepository(UserCredential).insert({ userId: user.id, password: hashedPassword, isActive: true, }); } await manager.getRepository(UserRole).upsert( { userId: user.id, roleId: role.id, organizationId: organization.id }, { conflictPaths: { userId: true, roleId: true } }, ); const employeeExists = await manager.getRepository(Employee).exists({ where: { userId: user.id, organizationId: organization.id, isCurrent: true }, }); if (!employeeExists) { await manager.getRepository(Employee).insert({ userId: user.id, organizationId: organization.id, isCurrent: true, name: { en: staff.username }, }); } } }); this.logger.log('Ensured passenger staff users'); } }