Files
MinglarBackendNestJS/src/modules/host/services/hostRolePermission.service.ts
2026-04-27 16:41:35 +05:30

255 lines
6.1 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { ROLE } from '../../../common/utils/constants/common.constant';
import ApiError from '../../../common/utils/helper/ApiError';
function normalizeIdArray(values: unknown): number[] {
if (!Array.isArray(values)) {
return [];
}
return Array.from(
new Set(
values
.map((item) => Number(item))
.filter((item) => Number.isInteger(item) && item > 0),
),
);
}
@Injectable()
export class HostRolePermissionService {
constructor(private prisma: PrismaClient) {}
async saveRolePermissions(input: {
hostUserXid: number;
roleXid: number;
permissionMasterXids: unknown;
}) {
const permissionMasterXids = normalizeIdArray(input.permissionMasterXids);
if (!permissionMasterXids.length) {
throw new ApiError(400, 'permissionMasterXids is required.');
}
return this.prisma.$transaction(async (tx) => {
const host = await tx.hostHeader.findFirst({
where: {
userXid: input.hostUserXid,
isActive: true,
deletedAt: null,
},
select: {
id: true,
companyName: true,
userXid: true,
},
});
if (!host) {
throw new ApiError(404, 'Host company not found for the logged-in user.');
}
const role = await tx.roles.findFirst({
where: {
id: input.roleXid,
isActive: true,
deletedAt: null,
},
select: {
id: true,
roleName: true,
},
});
if (!role) {
throw new ApiError(400, 'Invalid roleXid.');
}
const selectedPermissions = await tx.hostPermissionMasters.findMany({
where: {
id: { in: permissionMasterXids },
isActive: true,
deletedAt: null,
},
select: {
id: true,
permissionKey: true,
permissionGroup: true,
permissionSection: true,
permissionAction: true,
displayLabel: true,
displayOrder: true,
},
orderBy: {
displayOrder: 'asc',
},
});
if (selectedPermissions.length !== permissionMasterXids.length) {
throw new ApiError(400, 'One or more permissionMasterXids are invalid.');
}
const saved = await tx.hostRolePermissionMasters.upsert({
where: {
hostXid_roleXid: {
hostXid: host.id,
roleXid: role.id,
},
},
create: {
hostXid: host.id,
roleXid: role.id,
permissionMasterXids,
isActive: true,
},
update: {
permissionMasterXids,
isActive: true,
deletedAt: null,
},
select: {
id: true,
hostXid: true,
roleXid: true,
permissionMasterXids: true,
createdAt: true,
updatedAt: true,
},
});
return {
host,
role,
saved,
selectedPermissions,
};
});
}
async getMemberPermissions(input: {
hostUserXid: number;
memberUserXid: number;
}) {
return this.prisma.$transaction(async (tx) => {
// Find the host
const host = await tx.hostHeader.findFirst({
where: {
userXid: input.hostUserXid,
isActive: true,
deletedAt: null,
},
select: {
id: true,
companyName: true,
userXid: true,
},
});
if (!host) {
throw new ApiError(404, 'Host company not found for the logged-in user.');
}
// Find the host member
const hostMember = await tx.hostMembers.findFirst({
where: {
hostXid: host.id,
userXid: input.memberUserXid,
isActive: true,
deletedAt: null,
memberStatus: 'accepted',
},
select: {
id: true,
userXid: true,
roleXid: true,
role: {
select: {
id: true,
roleName: true,
},
},
hostRolePermissionMasterXid: true,
},
});
if (!hostMember) {
throw new ApiError(404, 'Host member not found or not active.');
}
// Check if role is operator or co-admin
if (hostMember.roleXid !== ROLE.CO_ADMIN && hostMember.roleXid !== ROLE.OPERATOR) {
throw new ApiError(400, 'Member is not an operator or co-admin.');
}
if (!hostMember.hostRolePermissionMasterXid) {
// Return empty permissions if no role permissions assigned
return {
host,
member: {
userXid: hostMember.userXid,
role: hostMember.role,
},
permissions: [],
};
}
// Get the role permissions
const rolePermissions = await tx.hostRolePermissionMasters.findFirst({
where: {
id: hostMember.hostRolePermissionMasterXid,
isActive: true,
deletedAt: null,
},
select: {
id: true,
permissionMasterXids: true,
},
});
if (!rolePermissions) {
return {
host,
member: {
userXid: hostMember.userXid,
role: hostMember.role,
},
permissions: [],
};
}
// Get the actual permissions
const permissionIds = rolePermissions.permissionMasterXids as number[];
const permissions = await tx.hostPermissionMasters.findMany({
where: {
id: { in: permissionIds },
isActive: true,
deletedAt: null,
},
select: {
id: true,
permissionKey: true,
permissionGroup: true,
permissionSection: true,
permissionAction: true,
displayLabel: true,
displayOrder: true,
},
orderBy: {
displayOrder: 'asc',
},
});
return {
host,
member: {
userXid: hostMember.userXid,
role: hostMember.role,
},
permissions,
};
});
}
}