feat(freight:backoffice): temp add user UI

This commit is contained in:
Michael Abebe
2026-06-01 17:17:54 +03:00
parent 57776c4fef
commit fab6819151
7 changed files with 964 additions and 6 deletions

View File

@@ -4,21 +4,29 @@ import {
NotFoundException,
} from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { hashPassword } from "@tria-plc/api-common/utils/argon";
import { EUserStatus } from "@tria-plc/api-common/utils/enums/user.enum";
import { DataSource, In, IsNull, Repository } from "typeorm";
import { Employee, Organization, UserCredential } from "@tria-plc/iamapi-common";
import { Role } from "@tria-plc/iamapi-common/entities/iam/user/role.entity";
import { UserRole } from "@tria-plc/iamapi-common/entities/iam/user/user-role.entity";
import { User } from "@tria-plc/iamapi-common/entities/iam/user/user.entity";
import { CreateOrganizationUserDto } from "./dto/create-organization-user.dto";
const RESERVED_ROLE_KEYS = new Set([
"super_admin",
"organization_admin",
"unit_admin",
]);
const DEFAULT_USER_PASSWORD = "12345678";
@Injectable()
export class BackofficeService {
constructor(
@InjectRepository(Organization)
private readonly organizationRepository: Repository<Organization>,
@InjectRepository(Role)
private readonly roleRepository: Repository<Role>,
@InjectRepository(UserRole)
@@ -28,6 +36,142 @@ export class BackofficeService {
private readonly dataSource: DataSource,
) {}
async createOrganizationUser(
organizationId: string,
dto: CreateOrganizationUserDto,
) {
const organizationExists = await this.organizationRepository.exists({
where: { id: organizationId },
});
if (!organizationExists) {
throw new NotFoundException("organization_not_found");
}
const email = dto.email.trim().toLowerCase();
const username = dto.username.trim().toLowerCase();
const phoneNumber = dto.phoneNumber?.trim() || undefined;
const name = {
en: dto.name.en.trim(),
...(dto.name.am?.trim() ? { am: dto.name.am.trim() } : {}),
};
const existingUsers = await this.userRepository.find({
where: [{ email }, { username }],
select: { id: true, email: true, username: true },
});
const emailUser = existingUsers.find((user) => user.email === email);
const usernameUser = existingUsers.find((user) => user.username === username);
if (emailUser && usernameUser && emailUser.id !== usernameUser.id) {
throw new BadRequestException("email_or_username_already_in_use");
}
const existingUser = emailUser ?? usernameUser;
const hashedPassword = await hashPassword(DEFAULT_USER_PASSWORD);
return this.dataSource.transaction(async (manager) => {
let user = existingUser;
if (!user) {
user = await manager.getRepository(User).save(
manager.getRepository(User).create({
email,
username,
phoneNumber,
name,
isActive: true,
hasSetPassword: true,
status: EUserStatus.ACCEPTED,
}),
);
} else {
await manager.getRepository(User).update(
{ id: user.id },
{
email,
username,
phoneNumber,
name,
isActive: true,
hasSetPassword: true,
status: EUserStatus.ACCEPTED,
},
);
}
const activeCredentialExists = await manager.getRepository(UserCredential).exists({
where: {
userId: user.id,
isActive: true,
},
});
if (!activeCredentialExists) {
await manager.getRepository(UserCredential).insert({
userId: user.id,
password: hashedPassword,
isActive: true,
});
}
let employee = await manager.getRepository(Employee).findOne({
where: {
userId: user.id,
organizationId,
isCurrent: true,
},
relations: {
user: true,
employeePositions: {
position: true,
},
},
});
if (!employee) {
const insertResult = await manager.getRepository(Employee).insert({
userId: user.id,
organizationId,
isCurrent: true,
name,
});
employee = await manager.getRepository(Employee).findOne({
where: { id: insertResult.identifiers[0]?.id as string },
relations: {
user: true,
employeePositions: {
position: true,
},
},
});
} else {
await manager.getRepository(Employee).update(
{ id: employee.id },
{ name },
);
employee = await manager.getRepository(Employee).findOne({
where: { id: employee.id },
relations: {
user: true,
employeePositions: {
position: true,
},
},
});
}
if (!employee) {
throw new NotFoundException("employee_create_failed");
}
return employee;
});
}
async getEmployeeUserRoles(organizationId: string, userId: string) {
await this.assertUserBelongsToOrganization(organizationId, userId);