set perms

This commit is contained in:
2025-12-23 13:00:27 +03:30
parent 9916426814
commit 98f973958d
10 changed files with 62 additions and 88 deletions
+2
View File
@@ -30,6 +30,7 @@ export enum Permission {
MANAGE_SETTINGS = 'manage_settings',
MANAGE_SCHEDULES = 'manage_schedules',
MANAGE_REPORTS = 'manage_reports',
MANAGE_CONTACTS = 'manage_contacts',
}
/**
@@ -53,4 +54,5 @@ export const PermissionTitles: Record<Permission, string> = {
[Permission.MANAGE_SETTINGS]: 'مدیریت تنظیمات',
[Permission.MANAGE_SCHEDULES]: 'مدیریت برنامه‌ها',
[Permission.MANAGE_REPORTS]: 'مدیریت گزارشات',
[Permission.MANAGE_CONTACTS]: 'مدیریت تماس‌های کاربران',
};
@@ -7,10 +7,13 @@ import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators';
import { AdminId } from 'src/common/decorators/admin-id.decorator';
import { Admin } from '../entities/admin.entity';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@ApiTags('admin')
@UseGuards(AdminAuthGuard)
@Permissions(Permission.MANAGE_ADMINS)
@Controller('admin/admins')
export class AdminController {
constructor(private readonly adminService: AdminService) {}
+2 -2
View File
@@ -12,7 +12,7 @@ import { Request } from 'express';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { IAdminTokenPayload } from '../interfaces/IToken-payload';
import { PERMISSIONS_KEY } from '../decorators/permissions.decorator';
import { PERMISSIONS_KEY } from '../../../common/decorators/permissions.decorator';
import { PermissionsService } from 'src/modules/roles/providers/permissions.service';
export interface AdminAuthRequest extends Request {
@@ -31,7 +31,7 @@ export class AdminAuthGuard implements CanActivate {
private readonly configService: ConfigService,
private readonly permissionsService: PermissionsService,
private readonly reflector: Reflector,
) {}
) { }
async canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest<AdminAuthRequest>();
@@ -8,8 +8,6 @@ import {
Query,
UseGuards,
Delete,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import { ContactService } from '../providers/contact.service';
import { CreateContactDto } from '../dto/create-contact.dto';
@@ -18,6 +16,9 @@ import { UpdateContactStatusDto } from '../dto/update-contact-status.dto';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { SuperAdminAuthGuard } from 'src/modules/auth/guards/superAdminAuth.guard';
import { API_HEADER_SLUG } from 'src/common/constants';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@ApiTags('contact')
@Controller()
@@ -26,22 +27,15 @@ export class ContactController {
@Post('public/contact')
@ApiOperation({ summary: 'Create a new contact (public endpoint)' })
@ApiHeader({
name: 'X-Slug',
required: true,
schema: {
type: 'string',
default: 'zhivan',
},
})
@ApiHeader(API_HEADER_SLUG)
async create(@Body() createContactDto: CreateContactDto) {
return this.contactService.create(createContactDto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CONTACTS)
@Get('admin/contact')
@ApiOperation({ summary: 'Get paginated list of contacts (admin only)' })
@ApiQuery({ name: 'page', required: false, type: Number })
@@ -56,6 +50,7 @@ export class ContactController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CONTACTS)
@Get('admin/contact/:id')
@ApiOperation({ summary: 'Get contact details by ID (admin only)' })
@ApiParam({ name: 'id', description: 'Contact ID' })
@@ -65,6 +60,7 @@ export class ContactController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CONTACTS)
@Patch('admin/contact/:id/status')
@ApiOperation({ summary: 'Update contact status (admin only)' })
@ApiParam({ name: 'id', description: 'Contact ID' })
@@ -74,14 +70,15 @@ export class ContactController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CONTACTS)
@Delete('admin/contact/:id')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Hard delete a contact (admin only)' })
@ApiParam({ name: 'id', description: 'Contact ID' })
async remove(@Param('id') id: string) {
await this.contactService.remove(id);
}
/*** Super Admin ***/
@UseGuards(SuperAdminAuthGuard)
@ApiBearerAuth()
@Get('super-admin/contact')
@@ -18,25 +18,20 @@ import {
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { API_HEADER_SLUG } from 'src/common/constants';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@ApiTags('coupons')
@Controller()
export class CouponController {
constructor(private readonly couponService: CouponService) {}
constructor(private readonly couponService: CouponService) { }
@UseGuards(AuthGuard)
@ApiBearerAuth()
@Get('public/coupons/me')
@ApiOperation({ summary: 'Get paginated list of restaurant coupons' })
@ApiHeader({
name: 'X-Slug',
required: true,
schema: {
type: 'string',
default: 'zhivan',
},
})
@ApiOkResponse({ description: 'Paginated list of restaurant coupons' })
@ApiHeader(API_HEADER_SLUG)
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiQuery({ name: 'search', required: false, type: String })
@@ -47,9 +42,10 @@ export class CouponController {
getMyCoupons(@Query() dto: FindCouponsDto, @RestId() restId: string) {
return this.couponService.findAll(restId, dto);
}
/*** Admin ***/
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Post('admin/coupons')
@ApiOperation({ summary: 'Create a new coupon' })
@ApiCreatedResponse({ description: 'The coupon has been successfully created.', type: CreateCouponDto })
@@ -60,9 +56,9 @@ export class CouponController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Get('admin/coupons')
@ApiOperation({ summary: 'Get a paginated list of coupons' })
@ApiOkResponse({ description: 'Paginated list of coupons' })
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiQuery({ name: 'search', required: false, type: String })
@@ -76,28 +72,28 @@ export class CouponController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Get('admin/coupons/:id')
@ApiOperation({ summary: 'Get a coupon by id' })
@ApiParam({ name: 'id', required: true })
@ApiOkResponse({ description: 'The coupon', type: CreateCouponDto })
@ApiNotFoundResponse({ description: 'Coupon not found' })
findById(@Param('id') id: string) {
return this.couponService.findById(id);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Patch('admin/coupons/:id')
@ApiOperation({ summary: 'Update a coupon' })
@ApiParam({ name: 'id', required: true })
@ApiBody({ type: UpdateCouponDto })
@ApiOkResponse({ description: 'The updated coupon', type: UpdateCouponDto })
update(@Param('id') id: string, @Body() updateCouponDto: UpdateCouponDto) {
return this.couponService.update(id, updateCouponDto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Delete('admin/coupons/:id')
@ApiOperation({ summary: 'Delete (soft) a coupon' })
@ApiParam({ name: 'id', required: true })
@@ -107,6 +103,7 @@ export class CouponController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_COUPONS)
@Get('admin/coupons/generate-code')
@ApiOperation({ summary: 'generate a coupon code' })
generateCouponCode(@RestId() restId: string) {
@@ -17,6 +17,9 @@ import { RestId } from 'src/common/decorators/rest-id.decorator';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { Delivery } from '../entities/delivery.entity';
import { API_HEADER_SLUG } from 'src/common/constants';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@ApiTags('Delivery')
@Controller()
@@ -27,83 +30,58 @@ export class DeliveryController {
@ApiBearerAuth()
@Get('public/delivery-methods/restaurant')
@ApiOperation({ summary: 'Get restaurant delivery methods' })
@ApiHeader({
name: 'X-Slug',
required: true,
schema: {
type: 'string',
default: 'zhivan',
},
})
@ApiOkResponse({
description: 'List of restaurant delivery methods',
type: [Delivery],
})
findAllDeliveryMethods(@RestId() restId: string) {
@ApiHeader(API_HEADER_SLUG)
findAllDeliveryMethods(@RestId() restId: string) {
return this.deliveryService.findAllForRestaurantId(restId);
}
/*** Admin ***/
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_DELIVERY)
@Post('admin/delivery-methods/restaurant')
@ApiOperation({ summary: 'Create a delivery method for a restaurant' })
@ApiBody({ type: CreateDeliveryDto })
@ApiCreatedResponse({
description: 'Delivery method created successfully',
type: Delivery,
})
create(@Body() createDto: CreateDeliveryDto, @RestId() restId: string) {
return this.deliveryService.create(restId, createDto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_DELIVERY)
@Get('admin/delivery-methods/restaurant')
@ApiOperation({ summary: 'Get the restaurant delivery methods' })
@ApiOkResponse({
description: 'List of restaurant delivery methods',
type: [Delivery],
})
findRestaurantDeliveryMethods(@RestId() restId: string) {
return this.deliveryService.findAllForRestaurantId(restId);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_DELIVERY)
@Get('admin/delivery-methods/restaurant/:deliveryId')
@ApiOperation({ summary: 'Get a restaurant delivery method by delivery ID' })
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
@ApiOkResponse({
description: 'Delivery method details',
type: Delivery,
})
@ApiNotFoundResponse({ description: 'Delivery method not found' })
findOne(@Param('deliveryId') deliveryId: string, @RestId() restId: string) {
return this.deliveryService.findOne(restId, deliveryId);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_DELIVERY)
@Patch('admin/delivery-methods/restaurant/:deliveryId')
@ApiOperation({ summary: 'Update a restaurant delivery method' })
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
@ApiBody({ type: UpdateDeliveryDto })
@ApiOkResponse({
description: 'Delivery method updated successfully',
type: Delivery,
})
@ApiNotFoundResponse({ description: 'Delivery method not found' })
update(@Param('deliveryId') deliveryId: string, @Body() updateDto: UpdateDeliveryDto, @RestId() restId: string) {
return this.deliveryService.update(restId, deliveryId, updateDto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_DELIVERY)
@Delete('admin/delivery-methods/restaurant/:deliveryId')
@ApiOperation({ summary: 'Delete a restaurant delivery method' })
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
@ApiOkResponse({ description: 'Delivery method deleted successfully' })
@ApiNotFoundResponse({ description: 'Delivery method not found' })
remove(@Param('deliveryId') deliveryId: string, @RestId() restId: string) {
return this.deliveryService.remove(restId, deliveryId);
}
@@ -16,11 +16,13 @@ import {
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { UseGuards } from '@nestjs/common';
import { RestId } from 'src/common/decorators';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@ApiTags('category')
@Controller()
export class CategoryController {
constructor(private readonly categoryService: CategoryService) {}
constructor(private readonly categoryService: CategoryService) { }
@Get('public/categories/restaurant/:slug')
@ApiOperation({ summary: 'Get all categories by restaurant slug' })
@@ -38,18 +40,19 @@ export class CategoryController {
return this.categoryService.findAllByRestaurant(slug);
}
/*** Admin ***/
@ApiOperation({ summary: 'Create category' })
@ApiCreatedResponse({ description: 'Category created', type: CreateCategoryDto })
@ApiBody({ type: CreateCategoryDto })
@Permissions(Permission.MANAGE_CATEGORIES)
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Post('admin/categories')
create(@Body() dto: CreateCategoryDto, @RestId() restId: string) {
return this.categoryService.create(restId, dto);
}
@Permissions(Permission.MANAGE_CATEGORIES)
@ApiOperation({ summary: 'my restaurant categories' })
@ApiOkResponse({ description: 'List of categories' })
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Get('admin/categories')
@@ -57,12 +60,11 @@ export class CategoryController {
return this.categoryService.findAllByRestaurantId(restId);
}
@Permissions(Permission.MANAGE_CATEGORIES)
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Get('admin/categories/:id')
@ApiOperation({ summary: 'Get category' })
@ApiOkResponse({ description: 'Category detail', type: CreateCategoryDto })
@ApiNotFoundResponse({ description: 'Category not found' })
@ApiParam({ name: 'id', required: true, type: String })
findOne(@Param('id') id: string, @RestId() restId: string) {
return this.categoryService.findOne(restId, id);
@@ -70,17 +72,18 @@ export class CategoryController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CATEGORIES)
@Patch('admin/categories/:id')
@ApiOperation({ summary: 'Update category' })
@ApiParam({ name: 'id' })
@ApiBody({ type: UpdateCategoryDto })
@ApiOkResponse({ description: 'Updated category', type: UpdateCategoryDto })
update(@Param('id') id: string, @Body() dto: UpdateCategoryDto, @RestId() restId: string) {
return this.categoryService.update(restId, id, dto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_CATEGORIES)
@Delete('admin/categories/:id')
@ApiOperation({ summary: 'Delete category' })
@ApiParam({ name: 'id' })
@@ -89,11 +92,4 @@ export class CategoryController {
return this.categoryService.remove(restId, id);
}
// @Get('restaurant/:restId')
// @ApiOperation({ summary: 'Restaurant categories for user' })
// @ApiOkResponse({ description: 'List of categories' })
// @ApiParam({ name: 'restId', required: true, type: String })
// findAllForRestaurant(@Param('restId') restId: string) {
// return this.categoryService.findRestaurantCategories(restId);
// }
}
@@ -20,6 +20,8 @@ import { RestId, UserId } from 'src/common/decorators';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { OptionalAuthGuard } from 'src/modules/auth/guards/optinalAuth.guard';
import { API_HEADER_SLUG } from 'src/common/constants';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';
@ApiTags('foods')
@Controller()
@@ -30,7 +32,6 @@ export class FoodController {
@ApiOperation({ summary: 'Get all foods by restaurant slug' })
@ApiHeader(API_HEADER_SLUG)
@ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' })
@ApiOkResponse({ description: 'List of all foods for the restaurant' })
findAllByRestaurant(@Param('slug') slug: string) {
return this.foodsService.findByWeekDateAndMealType(slug);
}
@@ -68,9 +69,9 @@ export class FoodController {
/* ---------------------------------- Admin ---------------------------------- */
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_FOODS)
@Post('admin/foods')
@ApiOperation({ summary: 'Create a new food' })
@ApiCreatedResponse({ description: 'The food has been successfully created.', type: CreateFoodDto })
@ApiBody({ type: CreateFoodDto })
create(@Body() createFoodDto: CreateFoodDto, @RestId() restId: string) {
return this.foodsService.create(restId, createFoodDto);
@@ -78,9 +79,9 @@ export class FoodController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_FOODS)
@Get('admin/foods')
@ApiOperation({ summary: 'Get a paginated list of foods' })
@ApiOkResponse({ description: 'Paginated list of foods' })
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiQuery({ name: 'search', required: false, type: String })
@@ -95,27 +96,27 @@ export class FoodController {
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_FOODS)
@Get('admin/foods/:id')
@ApiOperation({ summary: 'Get a food by id' })
@ApiParam({ name: 'id', required: true })
@ApiOkResponse({ description: 'The food', type: CreateFoodDto })
@ApiNotFoundResponse({ description: 'Food not found' })
findById(@Param('id') id: string, @RestId() restId: string) {
return this.foodsService.findAdminById(restId, id);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_FOODS)
@Patch('admin/foods/:id')
@ApiOperation({ summary: 'Update a food' })
@ApiParam({ name: 'id', required: true })
@ApiBody({ type: UpdateFoodDto })
@ApiOkResponse({ description: 'The updated food', type: UpdateFoodDto })
update(@Param('id') id: string, @Body() updateFoodDto: UpdateFoodDto, @RestId() restId: string) {
return this.foodsService.update(restId, id, updateFoodDto);
}
@UseGuards(AdminAuthGuard)
@ApiBearerAuth()
@Permissions(Permission.MANAGE_FOODS)
@Delete('admin/foods/:id')
@ApiOperation({ summary: 'Delete (soft) a food' })
@ApiParam({ name: 'id', required: true })
@@ -5,7 +5,7 @@ import { PermissionsService } from '../providers/permissions.service';
import { CreateRoleDto } from '../dto/create-role.dto';
import { UpdateRoleDto } from '../dto/update-role.dto';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { Permissions } from 'src/modules/auth/decorators/permissions.decorator';
import { Permissions } from 'src/common/decorators/permissions.decorator';
import { RestId } from 'src/common/decorators';
import { AdminId } from 'src/common/decorators/admin-id.decorator';
@@ -17,7 +17,7 @@ export class RolesController {
constructor(
private readonly roleService: RolesService,
private readonly permissionService: PermissionsService,
) {}
) { }
@Get()
@ApiOperation({ summary: 'Get all through restaurant roles with pagination and filters' })