diff --git a/src/modules/admin/controllers/admin.controller.ts b/src/modules/admin/controllers/admin.controller.ts index 621c6c7..540c207 100644 --- a/src/modules/admin/controllers/admin.controller.ts +++ b/src/modules/admin/controllers/admin.controller.ts @@ -61,7 +61,7 @@ export class AdminController { @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ADMINS) @ApiOperation({ summary: 'Get an admin by ID' }) - @ApiParam({ name: 'id', description: 'Admin ID' }) + @ApiParam({ name: 'adminId', description: 'Admin ID' }) getById(@Param('adminId') adminId: string, @ShopId() shopId: string): Promise { return this.adminService.findById(adminId, shopId); } @@ -70,7 +70,7 @@ export class AdminController { @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ADMINS) @ApiOperation({ summary: 'Delete an admin by ID' }) - @ApiParam({ name: 'id', description: 'Admin ID' }) + @ApiParam({ name: 'adminId', description: 'Admin ID' }) deleteById(@Param('adminId') adminId: string, @ShopId() shopId: string): Promise { return this.adminService.remove(adminId, shopId); } diff --git a/src/modules/admin/providers/admin.service.ts b/src/modules/admin/providers/admin.service.ts index 9ead972..a41dab9 100644 --- a/src/modules/admin/providers/admin.service.ts +++ b/src/modules/admin/providers/admin.service.ts @@ -15,7 +15,7 @@ import { AdminRepository } from '../repositories/admin.repository'; @Injectable() export class AdminService { constructor( - private readonly adminRepository:AdminRepository, + private readonly adminRepository: AdminRepository, @InjectRepository(AdminRole) private readonly adminRoleRepository: EntityRepository, private readonly em: EntityManager, @@ -57,6 +57,11 @@ export class AdminService { const role = await this.em.findOne(Role, { id: roleId, isSystem: false }); if (!role) throw new NotFoundException('Role not found'); + // Validate that role belongs to the shop or is general (shop: null) + if (role.shop && role.shop.id !== shopId) { + throw new BadRequestException('Role does not belong to this shop'); + } + const shop = await this.em.findOne(Shop, { id: shopId }); if (!shop) throw new NotFoundException('Shop not found'); @@ -94,8 +99,10 @@ export class AdminService { }); await this.em.persistAndFlush(admin); } - const role = await this.em.findOne(Role, { id: roleId }); - if (!role) throw new NotFoundException('Role* not found' + roleId); + const role = await this.em.findOne(Role, { id: roleId }, { populate: ['shop'] }); + if (!role) throw new NotFoundException('Role not found'); + + const shop = await this.em.findOne(Shop, { id: shopId }); if (!shop) throw new NotFoundException('Shop not found'); @@ -147,7 +154,10 @@ export class AdminService { } if (rest.phone !== undefined && rest.phone !== admin.phone) { const normalizedPhone = normalizePhone(rest.phone); - const exists = await this.adminRepository.findOne({ phone: normalizedPhone }); + const exists = await this.adminRepository.findOne({ + phone: normalizedPhone, + id: { $ne: adminId }, // Exclude current admin from duplicate check + }); if (exists) { throw new ConflictException('This Phone Number is already taken'); } @@ -156,11 +166,16 @@ export class AdminService { // Update role if roleId is provided if (roleId) { - const role = await this.em.findOne(Role, { id: roleId, isSystem: false }); + const role = await this.em.findOne(Role, { id: roleId, isSystem: false }, { populate: ['shop'] }); if (!role) { throw new NotFoundException('Role not found'); } + // Validate that role belongs to the shop or is general (shop: null) + if (role.shop && role.shop.id !== shopId) { + throw new BadRequestException('Role does not belong to this shop'); + } + // Find existing AdminRole for this admin and shop const existingAdminRole = await this.em.findOne(AdminRole, { admin: { id: adminId }, @@ -173,8 +188,8 @@ export class AdminService { } else { const shop = await this.em.findOne(Shop, { id: shopId }); if (!shop) throw new NotFoundException('Shop not found'); - // Create new AdminRole - const newAdminRole = this.em.create(AdminRole, { + // Create new AdminRole using repository for consistency + const newAdminRole = this.adminRoleRepository.create({ admin, role, shop, @@ -197,7 +212,6 @@ export class AdminService { async findByPhoneAndShopSlug(phone: string, shopSlug: string): Promise { const normalizedPhone = normalizePhone(phone); - console.log(phone, shopSlug); const admin = await this.adminRepository.findOne( { @@ -211,8 +225,6 @@ export class AdminService { { populate: ['roles', 'roles.role', 'roles.shop'] }, ); - console.log(admin); - if (!admin) { throw new BadRequestException('Admin not found'); } diff --git a/src/modules/admin/transformers/admin-detail.transformer.ts b/src/modules/admin/transformers/admin-detail.transformer.ts index 45b4718..5646276 100644 --- a/src/modules/admin/transformers/admin-detail.transformer.ts +++ b/src/modules/admin/transformers/admin-detail.transformer.ts @@ -18,16 +18,22 @@ export interface AdminDetailResponse { } export class AdminDetailTransformer { - static transform(admin: Admin): AdminDetailResponse | null { + static transform(admin: Admin, shopId?: string): AdminDetailResponse | null { if (!admin) { return null; } - // Extract role information - const role = admin.roles.getItems().find(r => r.role)?.role; - if (!role) { + // Extract role information - filter by shop if shopId is provided + const adminRoles = admin.roles.getItems(); + const adminRole = shopId + ? adminRoles.find(r => r.role && r.shop?.id === shopId) + : adminRoles.find(r => r.role); + + if (!adminRole || !adminRole.role) { return null; } + + const role = adminRole.role; return { id: admin.id, firstName: admin.firstName, @@ -39,9 +45,9 @@ export class AdminDetailTransformer { }, permissions: role.permissions.getItems().map(p => p.name) || [], shop: { - id: role.shop?.id || '', - name: role.shop?.name || '', - slug: role.shop?.slug || '', + id: adminRole.shop?.id || '', + name: adminRole.shop?.name || '', + slug: adminRole.shop?.slug || '', }, }; }