Add allocation management features and update permissions for container allocation

This commit is contained in:
Marshal
2026-07-03 04:15:16 +00:00
parent 56de90892d
commit bb2cedc87f
7 changed files with 304 additions and 12 deletions

View File

@@ -3,8 +3,11 @@ import { hashPassword } from '@tria-plc/api-common/utils/argon';
import { EUserStatus } from '@tria-plc/api-common/utils/enums/user.enum';
import {
Employee,
EmployeePosition,
Organization,
Position,
Role,
Unit,
User,
UserCredential,
UserRole,
@@ -13,13 +16,19 @@ import { DataSource } from 'typeorm';
const SEED_FLAG = 'SEED_FREIGHT_STAFF';
const EDR_ORG_KEY = 'edr_freight';
const EDR_UNIT_KEY = 'edr_freight_hq';
// roleKey is kept only for backwards compatibility with existing UserRole rows;
// access is granted via the assigned position (positionKey) + PositionPermission.
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-et@edr.local', username: 'gl_et', roleKey: 'edr_gl_ethiopia' },
{ email: 'gl-dj@edr.local', username: 'gl_dj', roleKey: 'edr_gl_djibouti' },
{ email: 'linestaff@edr.local', username: 'linestaff', roleKey: 'edr_line_staff', positionKey: 'operation' },
{ email: 'chief@edr.local', username: 'chief', roleKey: 'edr_org_manager', positionKey: 'chief' },
{ email: 'director@edr.local', username: 'director', roleKey: 'edr_director', positionKey: 'director' },
{ email: 'ceo@edr.local', username: 'ceo', roleKey: 'edr_ceo', positionKey: 'ceo' },
{ email: 'marketer@edr.local', username: 'marketer', roleKey: 'edr_marketing', positionKey: 'marketer' },
{ email: 'operation@edr.local', username: 'operation', roleKey: 'edr_operations_officer', positionKey: 'operation' },
{ email: 'gl-et@edr.local', username: 'gl_et', roleKey: 'edr_gl_ethiopia', positionKey: 'ethiopian_gl' },
{ email: 'gl-dj@edr.local', username: 'gl_dj', roleKey: 'edr_gl_djibouti', positionKey: 'djibouti_gl' },
] as const;
@Injectable()
@@ -47,11 +56,22 @@ export class FreightStaffUsersSeeder {
throw new Error(`missing_organization:${EDR_ORG_KEY}`);
}
const unit = await manager.getRepository(Unit).findOne({
where: { key: EDR_UNIT_KEY, organizationId: organization.id },
select: { id: true },
});
if (!unit) {
throw new Error(`missing_unit:${EDR_UNIT_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 positionRepository = manager.getRepository(Position);
const employeePositionRepository = manager.getRepository(EmployeePosition);
const hashedPassword = await hashPassword(password);
@@ -105,20 +125,50 @@ export class FreightStaffUsersSeeder {
{ conflictPaths: { userId: true, roleId: true } },
);
const employeeExists = await employeeRepository.exists({
let employee = await employeeRepository.findOne({
where: {
userId: user.id,
organizationId: organization.id,
isCurrent: true,
},
select: { id: true },
});
if (!employeeExists) {
await employeeRepository.insert({
userId: user.id,
organizationId: organization.id,
if (!employee) {
employee = await employeeRepository.save(
employeeRepository.create({
userId: user.id,
organizationId: organization.id,
unitId: unit.id,
isCurrent: true,
name: { en: staff.username },
}),
);
}
// Grant access via the assigned position (positions-as-roles).
const position = await positionRepository.findOne({
where: { key: staff.positionKey, unitId: unit.id },
select: { id: true, key: true },
});
if (!position) {
throw new Error(`missing_position:${staff.positionKey}`);
}
const employeePositionExists = await employeePositionRepository.exists({
where: {
employeeId: employee.id as string,
positionId: position.id as string,
},
});
if (!employeePositionExists) {
await employeePositionRepository.insert({
employeeId: employee.id as string,
positionId: position.id as string,
unitId: unit.id,
isCurrent: true,
name: { en: staff.username },
});
}
}