This commit is contained in:
2026-02-10 10:46:04 +03:30
parent 32d3559db9
commit 71670ffebf
3 changed files with 37 additions and 19 deletions
@@ -61,7 +61,7 @@ export class AdminController {
@UseGuards(AdminAuthGuard) @UseGuards(AdminAuthGuard)
@Permissions(Permission.MANAGE_ADMINS) @Permissions(Permission.MANAGE_ADMINS)
@ApiOperation({ summary: 'Get an admin by ID' }) @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<Admin | null> { getById(@Param('adminId') adminId: string, @ShopId() shopId: string): Promise<Admin | null> {
return this.adminService.findById(adminId, shopId); return this.adminService.findById(adminId, shopId);
} }
@@ -70,7 +70,7 @@ export class AdminController {
@UseGuards(AdminAuthGuard) @UseGuards(AdminAuthGuard)
@Permissions(Permission.MANAGE_ADMINS) @Permissions(Permission.MANAGE_ADMINS)
@ApiOperation({ summary: 'Delete an admin by ID' }) @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<void> { deleteById(@Param('adminId') adminId: string, @ShopId() shopId: string): Promise<void> {
return this.adminService.remove(adminId, shopId); return this.adminService.remove(adminId, shopId);
} }
+22 -10
View File
@@ -15,7 +15,7 @@ import { AdminRepository } from '../repositories/admin.repository';
@Injectable() @Injectable()
export class AdminService { export class AdminService {
constructor( constructor(
private readonly adminRepository:AdminRepository, private readonly adminRepository: AdminRepository,
@InjectRepository(AdminRole) @InjectRepository(AdminRole)
private readonly adminRoleRepository: EntityRepository<AdminRole>, private readonly adminRoleRepository: EntityRepository<AdminRole>,
private readonly em: EntityManager, private readonly em: EntityManager,
@@ -57,6 +57,11 @@ export class AdminService {
const role = await this.em.findOne(Role, { id: roleId, isSystem: false }); const role = await this.em.findOne(Role, { id: roleId, isSystem: false });
if (!role) throw new NotFoundException('Role not found'); 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 }); const shop = await this.em.findOne(Shop, { id: shopId });
if (!shop) throw new NotFoundException('Shop not found'); if (!shop) throw new NotFoundException('Shop not found');
@@ -94,8 +99,10 @@ export class AdminService {
}); });
await this.em.persistAndFlush(admin); await this.em.persistAndFlush(admin);
} }
const role = await this.em.findOne(Role, { id: roleId }); const role = await this.em.findOne(Role, { id: roleId }, { populate: ['shop'] });
if (!role) throw new NotFoundException('Role* not found' + roleId); if (!role) throw new NotFoundException('Role not found');
const shop = await this.em.findOne(Shop, { id: shopId }); const shop = await this.em.findOne(Shop, { id: shopId });
if (!shop) throw new NotFoundException('Shop not found'); if (!shop) throw new NotFoundException('Shop not found');
@@ -147,7 +154,10 @@ export class AdminService {
} }
if (rest.phone !== undefined && rest.phone !== admin.phone) { if (rest.phone !== undefined && rest.phone !== admin.phone) {
const normalizedPhone = normalizePhone(rest.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) { if (exists) {
throw new ConflictException('This Phone Number is already taken'); throw new ConflictException('This Phone Number is already taken');
} }
@@ -156,11 +166,16 @@ export class AdminService {
// Update role if roleId is provided // Update role if roleId is provided
if (roleId) { 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) { if (!role) {
throw new NotFoundException('Role not found'); 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 // Find existing AdminRole for this admin and shop
const existingAdminRole = await this.em.findOne(AdminRole, { const existingAdminRole = await this.em.findOne(AdminRole, {
admin: { id: adminId }, admin: { id: adminId },
@@ -173,8 +188,8 @@ export class AdminService {
} else { } else {
const shop = await this.em.findOne(Shop, { id: shopId }); const shop = await this.em.findOne(Shop, { id: shopId });
if (!shop) throw new NotFoundException('Shop not found'); if (!shop) throw new NotFoundException('Shop not found');
// Create new AdminRole // Create new AdminRole using repository for consistency
const newAdminRole = this.em.create(AdminRole, { const newAdminRole = this.adminRoleRepository.create({
admin, admin,
role, role,
shop, shop,
@@ -197,7 +212,6 @@ export class AdminService {
async findByPhoneAndShopSlug(phone: string, shopSlug: string): Promise<Admin> { async findByPhoneAndShopSlug(phone: string, shopSlug: string): Promise<Admin> {
const normalizedPhone = normalizePhone(phone); const normalizedPhone = normalizePhone(phone);
console.log(phone, shopSlug);
const admin = await this.adminRepository.findOne( const admin = await this.adminRepository.findOne(
{ {
@@ -211,8 +225,6 @@ export class AdminService {
{ populate: ['roles', 'roles.role', 'roles.shop'] }, { populate: ['roles', 'roles.role', 'roles.shop'] },
); );
console.log(admin);
if (!admin) { if (!admin) {
throw new BadRequestException('Admin not found'); throw new BadRequestException('Admin not found');
} }
@@ -18,16 +18,22 @@ export interface AdminDetailResponse {
} }
export class AdminDetailTransformer { export class AdminDetailTransformer {
static transform(admin: Admin): AdminDetailResponse | null { static transform(admin: Admin, shopId?: string): AdminDetailResponse | null {
if (!admin) { if (!admin) {
return null; return null;
} }
// Extract role information // Extract role information - filter by shop if shopId is provided
const role = admin.roles.getItems().find(r => r.role)?.role; const adminRoles = admin.roles.getItems();
if (!role) { const adminRole = shopId
? adminRoles.find(r => r.role && r.shop?.id === shopId)
: adminRoles.find(r => r.role);
if (!adminRole || !adminRole.role) {
return null; return null;
} }
const role = adminRole.role;
return { return {
id: admin.id, id: admin.id,
firstName: admin.firstName, firstName: admin.firstName,
@@ -39,9 +45,9 @@ export class AdminDetailTransformer {
}, },
permissions: role.permissions.getItems().map(p => p.name) || [], permissions: role.permissions.getItems().map(p => p.name) || [],
shop: { shop: {
id: role.shop?.id || '', id: adminRole.shop?.id || '',
name: role.shop?.name || '', name: adminRole.shop?.name || '',
slug: role.shop?.slug || '', slug: adminRole.shop?.slug || '',
}, },
}; };
} }