import { Injectable } from '@nestjs/common' ; import { InjectRepository } from '@nestjs/typeorm' ; import { NewGroupInput , UpdateGroupInput , UpdateGroupPermissionInput , } from '../../schema/graphql.schema' ; import { createQueryBuilder , Repository } from 'typeorm' ; import Group from '../entity/group.entity' ; import GroupPermission from '../entity/groupPermission.entity' ; import Permission from '../entity/permission.entity' ; import UserGroup from '../entity/userGroup.entity' ; import { GroupNotFoundException , GroupDeleteNotAllowedException , } from '../exception/group.exception' ; import { PermissionNotFoundException } from '../exception/permission.exception' ; import GroupCacheService from './groupcache.service' ; @ Injectable ( ) export class GroupService { constructor ( @ InjectRepository ( Group ) private groupsRepository , @ InjectRepository ( UserGroup ) private userGroupRepository , @ InjectRepository ( GroupPermission ) private groupPermissionRepository , @ InjectRepository ( Permission ) private permissionRepository , private groupCacheService ) { } getAllGroups ( ) { return this . groupsRepository . find ( ) ; } async getGroupById ( id ) { const group = await this . groupsRepository . findOne ( id ) ; if ( group ) { return group ; } throw new GroupNotFoundException ( id ) ; } async createGroup ( group ) { const newGroup = await this . groupsRepository . create ( group ) ; await this . groupsRepository . insert ( newGroup ) ; return newGroup ; } async updateGroup ( id , group ) { const existingGroup = await this . groupsRepository . findOne ( id ) ; if ( ! existingGroup ) { throw new GroupNotFoundException ( id ) ; } const groupToUpdate = this . groupsRepository . create ( group ) ; await this . groupsRepository . update ( id , groupToUpdate ) ; return { ... existingGroup , ... groupToUpdate , } ; } async deleteGroup ( id ) { const existingGroup = await this . groupsRepository . findOne ( id ) ; if ( ! existingGroup ) { throw new GroupNotFoundException ( id ) ; } const usage = await this . checkGroupUsage ( id ) ; if ( usage ) { throw new GroupDeleteNotAllowedException ( id ) ; } await this . groupsRepository . softDelete ( id ) ; await this . groupCacheService . invalidateGroupPermissionsByGroupId ( id ) ; return existingGroup ; } async updateGroupPermissions ( id , request ) { const updatedGroup = await this . groupsRepository . findOne ( id ) ; if ( ! updatedGroup ) { throw new GroupNotFoundException ( id ) ; } const permissionsInRequest = await this . permissionRepository . findByIds ( request . permissions ) ; if ( permissionsInRequest . length !== request . permissions . length ) { const validPermissions = permissionsInRequest . map ( ( p ) => p . id ) ; throw new PermissionNotFoundException ( request . permissions . filter ( ( p ) => ! validPermissions . includes ( p ) ) . toString ( ) ) ; } const groupPermission = this . groupPermissionRepository . create ( request . permissions . map ( ( permission ) => ( { groupId : id , permissionId : permission , } ) ) ) ; const savedGroupPermissions = await this . groupPermissionRepository . save ( groupPermission ) ; const permissions = await this . permissionRepository . findByIds ( savedGroupPermissions . map ( ( g ) => g . permissionId ) ) ; await this . groupCacheService . invalidateGroupPermissionsByGroupId ( id ) ; return permissions ; } async getGroupPermissions ( id ) { const permissions = await createQueryBuilder < Permission > ( 'permission' ) . leftJoinAndSelect ( GroupPermission , 'groupPermission' , 'Permission.id = groupPermission.permissionId' ) . where ( 'groupPermission.groupId = :groupId' , { groupId : id } ) . getMany ( ) ; return permissions ; } private async checkGroupUsage ( id ) { const userCount = await this . userGroupRepository . count ( { where : { groupId : id } , } ) ; return userCount != 0 ; } }