From 9abab789fccfc13288110ee15985e2b346ffcfb3 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Tue, 18 Nov 2025 15:43:24 +0330 Subject: [PATCH] Refactor Admin module by removing role and permission controllers, services, and DTOs; update imports to utilize Roles module for role and permission entities; adjust AdminService and AdminModule accordingly. --- src/app.module.ts | 2 + src/modules/admin/admin.module.ts | 18 ++++---- .../controllers/permission.controller.ts | 19 --------- src/modules/admin/entities/admin.entity.ts | 2 +- src/modules/admin/providers/admin.service.ts | 2 +- ...rest.repository.ts => admin.repository.ts} | 0 src/modules/auth/services/auth.service.ts | 2 +- .../{admin => roles}/dto/create-role.dto.ts | 0 .../{admin => roles}/dto/find-roles.dto.ts | 0 .../{admin => roles}/dto/update-role.dto.ts | 0 .../roles/entities/permission.entity.ts | 16 ++++++++ src/modules/roles/entities/role.entity.ts | 21 ++++++++++ .../roles/entities/rolePermission.entity.ts | 17 ++++++++ .../providers/permissions.service.ts} | 3 +- .../providers/roles.service.ts} | 2 +- .../roles.controller.ts} | 41 ++++++++++++------- src/modules/roles/roles.module.ts | 20 +++++++++ src/seeders/DatabaseSeeder.ts | 4 +- 18 files changed, 116 insertions(+), 53 deletions(-) delete mode 100644 src/modules/admin/controllers/permission.controller.ts rename src/modules/admin/repositories/{rest.repository.ts => admin.repository.ts} (100%) rename src/modules/{admin => roles}/dto/create-role.dto.ts (100%) rename src/modules/{admin => roles}/dto/find-roles.dto.ts (100%) rename src/modules/{admin => roles}/dto/update-role.dto.ts (100%) create mode 100755 src/modules/roles/entities/permission.entity.ts create mode 100755 src/modules/roles/entities/role.entity.ts create mode 100644 src/modules/roles/entities/rolePermission.entity.ts rename src/modules/{admin/providers/permission.service.ts => roles/providers/permissions.service.ts} (93%) rename src/modules/{admin/providers/role.service.ts => roles/providers/roles.service.ts} (99%) rename src/modules/{admin/controllers/role.controller.ts => roles/roles.controller.ts} (68%) create mode 100644 src/modules/roles/roles.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index b792bc6..399e604 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -17,6 +17,7 @@ import { ThrottlerModule } from '@nestjs/throttler'; import { RestaurantsModule } from './modules/restaurants/restaurants.module'; import { FoodModule } from './modules/foods/food.module'; import { CartModule } from './modules/cart/cart.module'; +import { RolesModule } from './modules/roles/roles.module'; @Module({ imports: [ @@ -47,6 +48,7 @@ import { CartModule } from './modules/cart/cart.module'; RestaurantsModule, FoodModule, CartModule, + RolesModule, ], controllers: [], providers: [], diff --git a/src/modules/admin/admin.module.ts b/src/modules/admin/admin.module.ts index aabe91c..ce0b205 100644 --- a/src/modules/admin/admin.module.ts +++ b/src/modules/admin/admin.module.ts @@ -3,25 +3,21 @@ import { AdminService } from './providers/admin.service'; import { MikroOrmModule } from '@mikro-orm/nestjs'; import { Admin } from './entities/admin.entity'; import { JwtModule } from '@nestjs/jwt'; -import { AdminRepository } from './repositories/rest.repository'; -import { Role } from './entities/role.entity'; -import { Permission } from './entities/permission.entity'; -import { RolePermission } from './entities/rolePermission.entity'; +import { AdminRepository } from './repositories/admin.repository'; +import { Role } from '../roles/entities/role.entity'; +import { Permission } from '../roles/entities/permission.entity'; +import { RolePermission } from '../roles/entities/rolePermission.entity'; import { AdminController } from './controllers/admin.controller'; -import { RoleService } from './providers/role.service'; -import { RoleController } from './controllers/role.controller'; -import { PermissionService } from './providers/permission.service'; -import { PermissionController } from './controllers/permission.controller'; import { UtilsModule } from '../utils/utils.module'; @Module({ - providers: [AdminService, AdminRepository, RoleService, PermissionService], - controllers: [AdminController, RoleController, PermissionController], + providers: [AdminService, AdminRepository], + controllers: [AdminController], imports: [ MikroOrmModule.forFeature([Admin, Role, Permission, RolePermission]), JwtModule, UtilsModule, ], - exports: [AdminService, AdminRepository, RoleService, PermissionService], + exports: [AdminService, AdminRepository], }) export class AdminModule {} diff --git a/src/modules/admin/controllers/permission.controller.ts b/src/modules/admin/controllers/permission.controller.ts deleted file mode 100644 index 5465071..0000000 --- a/src/modules/admin/controllers/permission.controller.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; -import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger'; -import { PermissionService } from '../providers/permission.service'; -import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; - -@UseGuards(AdminAuthGuard) -@ApiBearerAuth() -@ApiTags('admin/permissions') -@Controller('admin/permissions') -export class PermissionController { - constructor(private readonly permissionService: PermissionService) {} - - @Get() - @ApiOperation({ summary: 'Get all permissions' }) - @ApiResponse({ status: 200, description: 'Permissions retrieved successfully' }) - async findAll() { - return this.permissionService.findAll(); - } -} diff --git a/src/modules/admin/entities/admin.entity.ts b/src/modules/admin/entities/admin.entity.ts index f1e350c..b3d75cb 100644 --- a/src/modules/admin/entities/admin.entity.ts +++ b/src/modules/admin/entities/admin.entity.ts @@ -1,6 +1,6 @@ import { Entity, ManyToOne, Property } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; -import { Role } from './role.entity'; +import { Role } from '../../roles/entities/role.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; @Entity({ tableName: 'admins' }) diff --git a/src/modules/admin/providers/admin.service.ts b/src/modules/admin/providers/admin.service.ts index c02cd0b..305050a 100644 --- a/src/modules/admin/providers/admin.service.ts +++ b/src/modules/admin/providers/admin.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@mikro-orm/nestjs'; import { EntityRepository } from '@mikro-orm/core'; import { Admin } from '../entities/admin.entity'; -import { Role } from '../entities/role.entity'; +import { Role } from '../../roles/entities/role.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { EntityManager } from '@mikro-orm/postgresql'; import { CacheService } from '../../utils/cache.service'; diff --git a/src/modules/admin/repositories/rest.repository.ts b/src/modules/admin/repositories/admin.repository.ts similarity index 100% rename from src/modules/admin/repositories/rest.repository.ts rename to src/modules/admin/repositories/admin.repository.ts diff --git a/src/modules/auth/services/auth.service.ts b/src/modules/auth/services/auth.service.ts index 4256856..c265383 100644 --- a/src/modules/auth/services/auth.service.ts +++ b/src/modules/auth/services/auth.service.ts @@ -7,7 +7,7 @@ import { randomInt } from 'crypto'; import { TokensService } from './tokens.service'; import { RestRepository } from 'src/modules/restaurants/repositories/rest.repository'; import { AuthMessage, RestMessage } from 'src/common/enums/message.enum'; -import { AdminRepository } from 'src/modules/admin/repositories/rest.repository'; +import { AdminRepository } from 'src/modules/admin/repositories/admin.repository'; import { AdminLoginTransformer } from '../transformers/admin-login.transformer'; import { UserLoginTransformer } from '../transformers/user-login.transformer'; diff --git a/src/modules/admin/dto/create-role.dto.ts b/src/modules/roles/dto/create-role.dto.ts similarity index 100% rename from src/modules/admin/dto/create-role.dto.ts rename to src/modules/roles/dto/create-role.dto.ts diff --git a/src/modules/admin/dto/find-roles.dto.ts b/src/modules/roles/dto/find-roles.dto.ts similarity index 100% rename from src/modules/admin/dto/find-roles.dto.ts rename to src/modules/roles/dto/find-roles.dto.ts diff --git a/src/modules/admin/dto/update-role.dto.ts b/src/modules/roles/dto/update-role.dto.ts similarity index 100% rename from src/modules/admin/dto/update-role.dto.ts rename to src/modules/roles/dto/update-role.dto.ts diff --git a/src/modules/roles/entities/permission.entity.ts b/src/modules/roles/entities/permission.entity.ts new file mode 100755 index 0000000..e50d417 --- /dev/null +++ b/src/modules/roles/entities/permission.entity.ts @@ -0,0 +1,16 @@ +import { Entity, Property, Unique, ManyToMany, Collection } from '@mikro-orm/core'; +import { BaseEntity } from '../../../common/entities/base.entity'; +import { Role } from './role.entity'; + +@Entity({ tableName: 'permissions' }) +export class Permission extends BaseEntity { + @Property() + @Unique() + name!: string; + + @Property() + title!: string; + + @ManyToMany({ entity: () => Role, mappedBy: r => r.permissions }) + roles = new Collection(this); +} diff --git a/src/modules/roles/entities/role.entity.ts b/src/modules/roles/entities/role.entity.ts new file mode 100755 index 0000000..3c92c77 --- /dev/null +++ b/src/modules/roles/entities/role.entity.ts @@ -0,0 +1,21 @@ +// role.entity.ts +import { Collection, Entity, ManyToMany, OneToMany, ManyToOne, Property } from '@mikro-orm/core'; +import { BaseEntity } from '../../../common/entities/base.entity'; +import { Permission } from './permission.entity'; +import { Restaurant } from '../../restaurants/entities/restaurant.entity'; +import { RolePermission } from './rolePermission.entity'; + +@Entity({ tableName: 'roles' }) +export class Role extends BaseEntity { + @Property() + name!: string; + + @Property() + title!: string; + + @ManyToMany({ entity: () => Permission, pivotEntity: () => RolePermission, inversedBy: p => p.roles }) + permissions = new Collection(this); + + @ManyToOne(() => Restaurant, { nullable: true }) + restaurant?: Restaurant; +} diff --git a/src/modules/roles/entities/rolePermission.entity.ts b/src/modules/roles/entities/rolePermission.entity.ts new file mode 100644 index 0000000..75d062d --- /dev/null +++ b/src/modules/roles/entities/rolePermission.entity.ts @@ -0,0 +1,17 @@ +// role-permission.entity.ts (pivot) +import { Entity, ManyToOne } from '@mikro-orm/core'; +import { Role } from './role.entity'; +import { Permission } from './permission.entity'; + +@Entity({ tableName: 'role_permissions' }) +export class RolePermission { + // دو ManyToOne دقیقاً؛ هر کدام می‌تونن primary: true باشند برای composite PK + @ManyToOne(() => Role, { primary: true }) + role!: Role; + + @ManyToOne(() => Permission, { primary: true }) + permission!: Permission; + + // **نکته:** اینجا *فقط* همین دو خصوصیت کافی است — + // از تعریف جداگانه‌ی roleId / permissionId با @PrimaryKey خودداری کن مگر بخوای نام/نوع ستون را سفارشی کنی. +} diff --git a/src/modules/admin/providers/permission.service.ts b/src/modules/roles/providers/permissions.service.ts similarity index 93% rename from src/modules/admin/providers/permission.service.ts rename to src/modules/roles/providers/permissions.service.ts index a561dd5..6b4a7c7 100644 --- a/src/modules/admin/providers/permission.service.ts +++ b/src/modules/roles/providers/permissions.service.ts @@ -4,7 +4,7 @@ import { EntityRepository } from '@mikro-orm/core'; import { Permission } from '../entities/permission.entity'; @Injectable() -export class PermissionService { +export class PermissionsService { constructor( @InjectRepository(Permission) private readonly permissionRepository: EntityRepository, @@ -15,4 +15,3 @@ export class PermissionService { return permissions; } } - diff --git a/src/modules/admin/providers/role.service.ts b/src/modules/roles/providers/roles.service.ts similarity index 99% rename from src/modules/admin/providers/role.service.ts rename to src/modules/roles/providers/roles.service.ts index 3fc454a..a506db9 100644 --- a/src/modules/admin/providers/role.service.ts +++ b/src/modules/roles/providers/roles.service.ts @@ -10,7 +10,7 @@ import { UpdateRoleDto } from '../dto/update-role.dto'; import { FindRolesDto } from '../dto/find-roles.dto'; @Injectable() -export class RoleService { +export class RolesService { constructor( @InjectRepository(Role) private readonly roleRepository: EntityRepository, diff --git a/src/modules/admin/controllers/role.controller.ts b/src/modules/roles/roles.controller.ts similarity index 68% rename from src/modules/admin/controllers/role.controller.ts rename to src/modules/roles/roles.controller.ts index 60a9877..a1b1d6e 100644 --- a/src/modules/admin/controllers/role.controller.ts +++ b/src/modules/roles/roles.controller.ts @@ -1,18 +1,36 @@ import { Controller, Get, Post, Body, Param, Patch, Delete, Query, UseGuards } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBody, ApiResponse, ApiBearerAuth } from '@nestjs/swagger'; -import { RoleService } from '../providers/role.service'; -import { CreateRoleDto } from '../dto/create-role.dto'; -import { UpdateRoleDto } from '../dto/update-role.dto'; -import { FindRolesDto } from '../dto/find-roles.dto'; -import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; -import { Permissions } from 'src/modules/auth/decorators/permissions.decorator'; +import { RolesService } from './providers/roles.service'; +import { PermissionsService } from './providers/permissions.service'; +import { CreateRoleDto } from './dto/create-role.dto'; +import { UpdateRoleDto } from './dto/update-role.dto'; +import { FindRolesDto } from './dto/find-roles.dto'; +import { AdminAuthGuard } from '../auth/guards/adminAuth.guard'; +import { Permissions } from '../auth/decorators/permissions.decorator'; @UseGuards(AdminAuthGuard) @ApiBearerAuth() @ApiTags('admin/roles') @Controller('admin/roles') -export class RoleController { - constructor(private readonly roleService: RoleService) {} +export class RolesController { + constructor( + private readonly roleService: RolesService, + private readonly permissionService: PermissionsService, + ) {} + + @Get() + @ApiOperation({ summary: 'Get all roles with pagination and filters' }) + @ApiResponse({ status: 200, description: 'Roles retrieved successfully' }) + async findAll(@Query() dto: FindRolesDto) { + return this.roleService.findAll(dto); + } + + @Get('permissions') + @ApiOperation({ summary: 'Get all permissions' }) + @ApiResponse({ status: 200, description: 'Permissions retrieved successfully' }) + async findAllPermissions() { + return this.permissionService.findAll(); + } @Permissions('create-role') @Post() @@ -23,13 +41,6 @@ export class RoleController { return this.roleService.create(dto); } - @Get() - @ApiOperation({ summary: 'Get all roles with pagination and filters' }) - @ApiResponse({ status: 200, description: 'Roles retrieved successfully' }) - async findAll(@Query() dto: FindRolesDto) { - return this.roleService.findAll(dto); - } - @Get(':id') @ApiOperation({ summary: 'Get a specific role by ID' }) @ApiResponse({ status: 200, description: 'Role retrieved successfully' }) diff --git a/src/modules/roles/roles.module.ts b/src/modules/roles/roles.module.ts new file mode 100644 index 0000000..474ab8e --- /dev/null +++ b/src/modules/roles/roles.module.ts @@ -0,0 +1,20 @@ +import { Module } from '@nestjs/common'; +import { MikroOrmModule } from '@mikro-orm/nestjs'; +import { RolesService } from './providers/roles.service'; +import { RolesController } from './roles.controller'; +import { PermissionsService } from './providers/permissions.service'; +import { Role } from './entities/role.entity'; +import { Permission } from './entities/permission.entity'; +import { RolePermission } from './entities/rolePermission.entity'; +import { JwtModule } from '@nestjs/jwt'; + +@Module({ + imports: [ + MikroOrmModule.forFeature([Role, Permission, RolePermission]), + JwtModule, + ], + controllers: [RolesController], + providers: [RolesService, PermissionsService], + exports: [RolesService, PermissionsService], +}) +export class RolesModule {} diff --git a/src/seeders/DatabaseSeeder.ts b/src/seeders/DatabaseSeeder.ts index 109b1ae..11ed201 100644 --- a/src/seeders/DatabaseSeeder.ts +++ b/src/seeders/DatabaseSeeder.ts @@ -3,8 +3,8 @@ import { Seeder } from '@mikro-orm/seeder'; import { Category } from '../modules/foods/entities/category.entity'; import { Food } from '../modules/foods/entities/food.entity'; import { Admin } from '../modules/admin/entities/admin.entity'; -import { Permission as PermissionEntity } from '../modules/admin/entities/permission.entity'; -import { Role } from '../modules/admin/entities/role.entity'; +import { Permission as PermissionEntity } from '../modules/roles/entities/permission.entity'; +import { Role } from '../modules/roles/entities/role.entity'; import { Restaurant } from '../modules/restaurants/entities/restaurant.entity'; import { User } from '../modules/users/entities/user.entity'; import { Permission, PermissionTitles } from '../common/enums/permission.enum';