This commit is contained in:
2025-12-13 10:35:15 +03:30
parent 85b4e5bb6a
commit 3eb6b889a4
20 changed files with 114 additions and 20 deletions
@@ -2,7 +2,7 @@ import { Controller, Post, Body, HttpCode, HttpStatus, Get, UseGuards, Patch, Pa
import { AdminService } from '../providers/admin.service'; import { AdminService } from '../providers/admin.service';
import { CreateAdminDto } from '../dto/create-admin.dto'; import { CreateAdminDto } from '../dto/create-admin.dto';
import { UpdateAdminDto } from '../dto/update-admin.dto'; import { UpdateAdminDto } from '../dto/update-admin.dto';
import { ApiTags, ApiOperation, ApiBody, ApiBearerAuth, ApiParam } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBody, ApiBearerAuth, ApiParam, ApiHeader } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators'; import { RestId } from 'src/common/decorators';
import { AdminId } from 'src/common/decorators/admin-id.decorator'; import { AdminId } from 'src/common/decorators/admin-id.decorator';
@@ -8,7 +8,7 @@ import { SetPaymentMethodDto } from '../dto/set-payment-method.dto';
import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto'; import { SetDeliveryMethodDto } from '../dto/set-delivery-method.dto';
import { SetDescriptionDto } from '../dto/set-description.dto'; import { SetDescriptionDto } from '../dto/set-description.dto';
import { SetTableNumberDto } from '../dto/set-table-number.dto'; import { SetTableNumberDto } from '../dto/set-table-number.dto';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiParam } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiParam, ApiHeader } from '@nestjs/swagger';
import { AuthGuard } from '../../auth/guards/auth.guard'; import { AuthGuard } from '../../auth/guards/auth.guard';
import { UserId } from 'src/common/decorators/user-id.decorator'; import { UserId } from 'src/common/decorators/user-id.decorator';
import { RestId } from 'src/common/decorators/rest-id.decorator'; import { RestId } from 'src/common/decorators/rest-id.decorator';
@@ -22,12 +22,14 @@ export class CartController {
@Get() @Get()
@ApiOperation({ summary: 'Get cart for current user and restaurant' }) @ApiOperation({ summary: 'Get cart for current user and restaurant' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
async findOne(@UserId() userId: string, @RestId() restaurantId: string) { async findOne(@UserId() userId: string, @RestId() restaurantId: string) {
return this.cartService.getOrCreateCart(userId, restaurantId); return this.cartService.getOrCreateCart(userId, restaurantId);
} }
@Post('items/:foodId/increment') @Post('items/:foodId/increment')
@ApiOperation({ summary: 'Increment item quantity in cart by 1' }) @ApiOperation({ summary: 'Increment item quantity in cart by 1' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'foodId', description: 'Food ID to increment in cart' }) @ApiParam({ name: 'foodId', description: 'Food ID to increment in cart' })
async incrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) { async incrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
return this.cartService.incrementItem(userId, restaurantId, foodId); return this.cartService.incrementItem(userId, restaurantId, foodId);
@@ -35,6 +37,7 @@ export class CartController {
@Post('items/:foodId/decrement') @Post('items/:foodId/decrement')
@ApiOperation({ summary: 'Decrement item quantity in cart by 1 (removes item if quantity reaches 0)' }) @ApiOperation({ summary: 'Decrement item quantity in cart by 1 (removes item if quantity reaches 0)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'foodId', description: 'Food ID to decrement in cart' }) @ApiParam({ name: 'foodId', description: 'Food ID to decrement in cart' })
async decrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) { async decrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
return this.cartService.decrementItem(userId, restaurantId, foodId); return this.cartService.decrementItem(userId, restaurantId, foodId);
@@ -42,6 +45,7 @@ export class CartController {
@Post('items/bulk') @Post('items/bulk')
@ApiOperation({ summary: 'Bulk add items to cart (increments quantity if items exist)' }) @ApiOperation({ summary: 'Bulk add items to cart (increments quantity if items exist)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: BulkAddItemsToCartDto }) @ApiBody({ type: BulkAddItemsToCartDto })
bulkAddItems( bulkAddItems(
@UserId() userId: string, @UserId() userId: string,
@@ -53,6 +57,7 @@ export class CartController {
@Patch('items/:foodId') @Patch('items/:foodId')
@ApiOperation({ summary: 'Update item quantity in cart' }) @ApiOperation({ summary: 'Update item quantity in cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'foodId', description: 'Food ID in the cart' }) @ApiParam({ name: 'foodId', description: 'Food ID in the cart' })
@ApiBody({ type: UpdateItemQuantityDto }) @ApiBody({ type: UpdateItemQuantityDto })
async updateItemQuantity( async updateItemQuantity(
@@ -66,6 +71,7 @@ export class CartController {
@Delete('items/:foodId') @Delete('items/:foodId')
@ApiOperation({ summary: 'Remove item from cart' }) @ApiOperation({ summary: 'Remove item from cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'foodId', description: 'Food ID in the cart' }) @ApiParam({ name: 'foodId', description: 'Food ID in the cart' })
async removeItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) { async removeItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
return this.cartService.removeItem(userId, restaurantId, foodId); return this.cartService.removeItem(userId, restaurantId, foodId);
@@ -73,12 +79,14 @@ export class CartController {
@Delete() @Delete()
@ApiOperation({ summary: 'Clear entire cart' }) @ApiOperation({ summary: 'Clear entire cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
async clearCart(@UserId() userId: string, @RestId() restaurantId: string) { async clearCart(@UserId() userId: string, @RestId() restaurantId: string) {
return this.cartService.clearCart(userId, restaurantId); return this.cartService.clearCart(userId, restaurantId);
} }
@Post('apply-coupon') @Post('apply-coupon')
@ApiOperation({ summary: 'Apply coupon to cart' }) @ApiOperation({ summary: 'Apply coupon to cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: ApplyCouponDto }) @ApiBody({ type: ApplyCouponDto })
async applyCoupon(@UserId() userId: string, @RestId() restaurantId: string, @Body() applyCouponDto: ApplyCouponDto) { async applyCoupon(@UserId() userId: string, @RestId() restaurantId: string, @Body() applyCouponDto: ApplyCouponDto) {
return this.cartService.applyCoupon(userId, restaurantId, applyCouponDto); return this.cartService.applyCoupon(userId, restaurantId, applyCouponDto);
@@ -86,12 +94,14 @@ export class CartController {
@Delete('coupon') @Delete('coupon')
@ApiOperation({ summary: 'Remove coupon from cart' }) @ApiOperation({ summary: 'Remove coupon from cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) { async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) {
return this.cartService.removeCoupon(userId, restaurantId); return this.cartService.removeCoupon(userId, restaurantId);
} }
@Patch('address') @Patch('address')
@ApiOperation({ summary: 'Set address for cart' }) @ApiOperation({ summary: 'Set address for cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: SetAddressDto }) @ApiBody({ type: SetAddressDto })
async setAddress(@UserId() userId: string, @RestId() restaurantId: string, @Body() setAddressDto: SetAddressDto) { async setAddress(@UserId() userId: string, @RestId() restaurantId: string, @Body() setAddressDto: SetAddressDto) {
return this.cartService.setAddress(userId, restaurantId, setAddressDto); return this.cartService.setAddress(userId, restaurantId, setAddressDto);
@@ -99,6 +109,7 @@ export class CartController {
@Patch('payment-method') @Patch('payment-method')
@ApiOperation({ summary: 'Set payment method for cart' }) @ApiOperation({ summary: 'Set payment method for cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: SetPaymentMethodDto }) @ApiBody({ type: SetPaymentMethodDto })
async setPaymentMethod( async setPaymentMethod(
@UserId() userId: string, @UserId() userId: string,
@@ -110,6 +121,7 @@ export class CartController {
@Patch('delivery-method') @Patch('delivery-method')
@ApiOperation({ summary: 'Set delivery method for cart' }) @ApiOperation({ summary: 'Set delivery method for cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: SetDeliveryMethodDto }) @ApiBody({ type: SetDeliveryMethodDto })
setDeliveryMethod( setDeliveryMethod(
@UserId() userId: string, @UserId() userId: string,
@@ -121,6 +133,7 @@ export class CartController {
@Patch('description') @Patch('description')
@ApiOperation({ summary: 'Set description for cart' }) @ApiOperation({ summary: 'Set description for cart' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: SetDescriptionDto }) @ApiBody({ type: SetDescriptionDto })
setDescription( setDescription(
@UserId() userId: string, @UserId() userId: string,
@@ -132,6 +145,7 @@ export class CartController {
@Patch('table-number') @Patch('table-number')
@ApiOperation({ summary: 'Set table number for cart (required when delivery method is DineIn)' }) @ApiOperation({ summary: 'Set table number for cart (required when delivery method is DineIn)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: SetTableNumberDto }) @ApiBody({ type: SetTableNumberDto })
setTableNumber( setTableNumber(
@UserId() userId: string, @UserId() userId: string,
@@ -15,7 +15,7 @@ import { ContactService } from '../providers/contact.service';
import { CreateContactDto } from '../dto/create-contact.dto'; import { CreateContactDto } from '../dto/create-contact.dto';
import { FindContactsDto } from '../dto/find-contacts.dto'; import { FindContactsDto } from '../dto/find-contacts.dto';
import { UpdateContactStatusDto } from '../dto/update-contact-status.dto'; import { UpdateContactStatusDto } from '../dto/update-contact-status.dto';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
@ApiTags('contact') @ApiTags('contact')
@@ -25,6 +25,7 @@ export class ContactController {
@Post('public/contact') @Post('public/contact')
@ApiOperation({ summary: 'Create a new contact (public endpoint)' }) @ApiOperation({ summary: 'Create a new contact (public endpoint)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
async create(@Body() createContactDto: CreateContactDto) { async create(@Body() createContactDto: CreateContactDto) {
return this.contactService.create(createContactDto); return this.contactService.create(createContactDto);
} }
@@ -13,6 +13,7 @@ import {
ApiBody, ApiBody,
ApiParam, ApiParam,
ApiBearerAuth, ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators'; import { RestId } from 'src/common/decorators';
@@ -27,6 +28,7 @@ export class CouponController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/coupons/me') @Get('public/coupons/me')
@ApiOperation({ summary: 'Get paginated list of restaurant coupons' }) @ApiOperation({ summary: 'Get paginated list of restaurant coupons' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'Paginated list of restaurant coupons' }) @ApiOkResponse({ description: 'Paginated list of restaurant coupons' })
@ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number }) @ApiQuery({ name: 'limit', required: false, type: Number })
@@ -8,6 +8,7 @@ import {
ApiParam, ApiParam,
ApiBody, ApiBody,
ApiBearerAuth, ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { DeliveryService } from '../providers/delivery.service'; import { DeliveryService } from '../providers/delivery.service';
import { CreateDeliveryDto } from '../dto/create-delivery.dto'; import { CreateDeliveryDto } from '../dto/create-delivery.dto';
@@ -26,6 +27,7 @@ export class DeliveryController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/delivery-methods/restaurant') @Get('public/delivery-methods/restaurant')
@ApiOperation({ summary: 'Get restaurant delivery methods' }) @ApiOperation({ summary: 'Get restaurant delivery methods' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ @ApiOkResponse({
description: 'List of restaurant delivery methods', description: 'List of restaurant delivery methods',
type: [Delivery], type: [Delivery],
@@ -12,6 +12,7 @@ import {
ApiBody, ApiBody,
ApiQuery, ApiQuery,
ApiBearerAuth, ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { UseGuards } from '@nestjs/common'; import { UseGuards } from '@nestjs/common';
@@ -24,6 +25,7 @@ export class CategoryController {
@Get('public/categories/restaurant/:slug') @Get('public/categories/restaurant/:slug')
@ApiOperation({ summary: 'Get all categories by restaurant slug' }) @ApiOperation({ summary: 'Get all categories by restaurant slug' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' }) @ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' })
@ApiOkResponse({ description: 'List of all categories for the restaurant' }) @ApiOkResponse({ description: 'List of all categories for the restaurant' })
findAllByRestaurant(@Param('slug') slug: string) { findAllByRestaurant(@Param('slug') slug: string) {
@@ -13,6 +13,7 @@ import {
ApiBody, ApiBody,
ApiParam, ApiParam,
ApiBearerAuth, ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators'; import { RestId } from 'src/common/decorators';
@@ -24,6 +25,7 @@ export class FoodController {
@Get('public/foods/restaurant/:slug') @Get('public/foods/restaurant/:slug')
@ApiOperation({ summary: 'Get all foods by restaurant slug' }) @ApiOperation({ summary: 'Get all foods by restaurant slug' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' }) @ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' })
@ApiOkResponse({ description: 'List of all foods for the restaurant' }) @ApiOkResponse({ description: 'List of all foods for the restaurant' })
findAllByRestaurant(@Param('slug') slug: string) { findAllByRestaurant(@Param('slug') slug: string) {
@@ -1,5 +1,5 @@
import { Controller, Post, Get, Body, Param, UseGuards, Query, Patch, Delete } from '@nestjs/common'; import { Controller, Post, Get, Body, Param, UseGuards, Query, Patch, Delete } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
import { NotificationService } from '../services/notification.service'; import { NotificationService } from '../services/notification.service';
import { NotificationPreferenceService } from '../services/notification-preference.service'; import { NotificationPreferenceService } from '../services/notification-preference.service';
import { CreatePreferenceDto } from '../dto/create-preference.dto'; import { CreatePreferenceDto } from '../dto/create-preference.dto';
@@ -21,6 +21,7 @@ export class NotificationsController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/notifications') @Get('public/notifications')
@ApiOperation({ summary: 'Get user restaurant notifications' }) @ApiOperation({ summary: 'Get user restaurant notifications' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiQuery({ name: 'limit', required: false, type: Number }) @ApiQuery({ name: 'limit', required: false, type: Number })
async getUserNotifications(@UserId() userId: string, @RestId() restaurantId: string, @Query('limit') limit?: number) { async getUserNotifications(@UserId() userId: string, @RestId() restaurantId: string, @Query('limit') limit?: number) {
return await this.notificationService.findByUserAndRestaurant( return await this.notificationService.findByUserAndRestaurant(
@@ -1,5 +1,5 @@
import { Controller, Get, Post, Param, UseGuards, Patch, Query } from '@nestjs/common'; import { Controller, Get, Post, Param, UseGuards, Patch, Query } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiHeader } from '@nestjs/swagger';
import { OrdersService } from '../providers/orders.service'; import { OrdersService } from '../providers/orders.service';
import { AuthGuard } from '../../auth/guards/auth.guard'; import { AuthGuard } from '../../auth/guards/auth.guard';
import { UserId } from '../../../common/decorators/user-id.decorator'; import { UserId } from '../../../common/decorators/user-id.decorator';
@@ -16,6 +16,7 @@ export class OrdersController {
@ApiBearerAuth() @ApiBearerAuth()
@Post('public/checkout') @Post('public/checkout')
@ApiOperation({ summary: 'Checkout : create order and payment record' }) @ApiOperation({ summary: 'Checkout : create order and payment record' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
checkout(@UserId() userId: string, @RestId() restaurantId: string) { checkout(@UserId() userId: string, @RestId() restaurantId: string) {
return this.ordersService.checkout(userId, restaurantId); return this.ordersService.checkout(userId, restaurantId);
} }
@@ -24,6 +25,7 @@ export class OrdersController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/orders') @Get('public/orders')
@ApiOperation({ summary: 'Get all orders with pagination and filters' }) @ApiOperation({ summary: 'Get all orders with pagination and filters' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
findAll(@RestId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) { findAll(@RestId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) {
return this.ordersService.findAllForUser(restId, dto, userId); return this.ordersService.findAllForUser(restId, dto, userId);
} }
@@ -31,6 +33,7 @@ export class OrdersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Get an order By id for User' }) @ApiOperation({ summary: 'Get an order By id for User' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiParam({ name: 'orderId', description: 'Order ID' })
@Get('public/orders/:orderId') @Get('public/orders/:orderId')
findOne(@Param('orderId') orderId: string, @RestId() restId: string) { findOne(@Param('orderId') orderId: string, @RestId() restId: string) {
@@ -41,6 +44,7 @@ export class OrdersController {
@ApiBearerAuth() @ApiBearerAuth()
@Patch('public/orders/:id/cancel') @Patch('public/orders/:id/cancel')
@ApiOperation({ summary: 'Cancel an order By User' }) @ApiOperation({ summary: 'Cancel an order By User' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'id', description: 'Order ID' }) @ApiParam({ name: 'id', description: 'Order ID' })
cancelOrder(@Param('id') id: string, @RestId() restId: string) { cancelOrder(@Param('id') id: string, @RestId() restId: string) {
return this.ordersService.cancelOrderAsUser(id, restId); return this.ordersService.cancelOrderAsUser(id, restId);
@@ -57,7 +57,7 @@ export class PagerController {
@UseGuards(OptionalAuthGuard) @UseGuards(OptionalAuthGuard)
@Get('public/pager') @Get('public/pager')
@ApiOperation({ summary: 'Get all pager requests for the current session' }) @ApiOperation({ summary: 'Get all pager requests for the current session' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier' }) @ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiHeader({ name: 'Authorization', required: false, description: 'Bearer token (optional authentication)' }) @ApiHeader({ name: 'Authorization', required: false, description: 'Bearer token (optional authentication)' })
async findAll(@Req() request: FastifyRequest) { async findAll(@Req() request: FastifyRequest) {
const cookieId = request.cookies['pagerId'] || undefined; const cookieId = request.cookies['pagerId'] || undefined;
@@ -1,6 +1,14 @@
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common'; import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common';
import { PaymentsService } from '../services/payments.service'; import { PaymentsService } from '../services/payments.service';
import { ApiTags, ApiOperation, ApiNotFoundResponse, ApiBody, ApiParam, ApiBearerAuth } from '@nestjs/swagger'; import {
ApiTags,
ApiOperation,
ApiNotFoundResponse,
ApiBody,
ApiParam,
ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { PaymentMethodService } from '../services/payment-method.service'; import { PaymentMethodService } from '../services/payment-method.service';
import { CreatePaymentMethodDto } from '../dto/create-payment-method.dto'; import { CreatePaymentMethodDto } from '../dto/create-payment-method.dto';
@@ -21,6 +29,7 @@ export class PaymentsController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/payments/methods/restaurant') @Get('public/payments/methods/restaurant')
@ApiOperation({ summary: 'Get the restaurant payment methods' }) @ApiOperation({ summary: 'Get the restaurant payment methods' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiNotFoundResponse({ description: 'Restaurant payment methods not found' }) @ApiNotFoundResponse({ description: 'Restaurant payment methods not found' })
getTheRestaurantPaymentMethods(@RestId() restId: string) { getTheRestaurantPaymentMethods(@RestId() restId: string) {
return this.paymentMethodService.findByRestaurant(restId); return this.paymentMethodService.findByRestaurant(restId);
@@ -30,6 +39,7 @@ export class PaymentsController {
@ApiBearerAuth() @ApiBearerAuth()
@Get('public/payments') @Get('public/payments')
@ApiOperation({ summary: 'Get all the restaurant payments for user' }) @ApiOperation({ summary: 'Get all the restaurant payments for user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
findAllByRestaurant(@UserId() userId: string, @RestId() restId: string) { findAllByRestaurant(@UserId() userId: string, @RestId() restId: string) {
return this.paymentsService.findAllByRestaurantId(restId, userId); return this.paymentsService.findAllByRestaurantId(restId, userId);
} }
@@ -117,6 +127,7 @@ export class PaymentsController {
@Post('public/payments/verify') @Post('public/payments/verify')
@ApiOperation({ summary: 'Verify a payment' }) @ApiOperation({ summary: 'Verify a payment' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: VerifyPaymentDto }) @ApiBody({ type: VerifyPaymentDto })
@ApiNotFoundResponse({ description: 'Payment not found' }) @ApiNotFoundResponse({ description: 'Payment not found' })
verifyPayment(@Body() verifyPaymentDto: VerifyPaymentDto) { verifyPayment(@Body() verifyPaymentDto: VerifyPaymentDto) {
@@ -3,7 +3,15 @@ import { RestaurantsService } from '../providers/restaurants.service';
import { CreateRestaurantDto } from '../dto/create-restaurant.dto'; import { CreateRestaurantDto } from '../dto/create-restaurant.dto';
import { UpdateRestaurantDto } from '../dto/update-restaurant.dto'; import { UpdateRestaurantDto } from '../dto/update-restaurant.dto';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { ApiBearerAuth, ApiBody, ApiNotFoundResponse, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; import {
ApiBearerAuth,
ApiBody,
ApiNotFoundResponse,
ApiOperation,
ApiParam,
ApiTags,
ApiHeader,
} from '@nestjs/swagger';
import { RestId } from 'src/common/decorators'; import { RestId } from 'src/common/decorators';
@ApiTags('restaurants') @ApiTags('restaurants')
@@ -13,6 +21,7 @@ export class RestaurantsController {
@Get('public/restaurants/:slug') @Get('public/restaurants/:slug')
@ApiOperation({ summary: 'Get restaurant specification by slug' }) @ApiOperation({ summary: 'Get restaurant specification by slug' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'slug', required: true, description: 'Restaurant slug' }) @ApiParam({ name: 'slug', required: true, description: 'Restaurant slug' })
@ApiNotFoundResponse({ description: 'Restaurant not found' }) @ApiNotFoundResponse({ description: 'Restaurant not found' })
findBySlug(@Param('slug') slug: string) { findBySlug(@Param('slug') slug: string) {
@@ -9,6 +9,7 @@ import {
ApiBody, ApiBody,
ApiBearerAuth, ApiBearerAuth,
ApiQuery, ApiQuery,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { ScheduleService } from '../providers/schedule.service'; import { ScheduleService } from '../providers/schedule.service';
import { CreateScheduleDto } from '../dto/create-schedule.dto'; import { CreateScheduleDto } from '../dto/create-schedule.dto';
@@ -25,6 +26,7 @@ export class ScheduleController {
@Get('public/schedules/restaurant/:slug') @Get('public/schedules/restaurant/:slug')
@ApiOperation({ summary: 'Get schedule of a restaurant by slug' }) @ApiOperation({ summary: 'Get schedule of a restaurant by slug' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'slug', description: 'Restaurant Slug' }) @ApiParam({ name: 'slug', description: 'Restaurant Slug' })
@ApiOkResponse({ description: 'Today schedule of the restaurant', type: Schedule }) @ApiOkResponse({ description: 'Today schedule of the restaurant', type: Schedule })
async getTodaySchedules(@Param('slug') slug: string): Promise<Schedule[]> { async getTodaySchedules(@Param('slug') slug: string): Promise<Schedule[]> {
@@ -13,6 +13,7 @@ import {
ApiBody, ApiBody,
ApiParam, ApiParam,
ApiBearerAuth, ApiBearerAuth,
ApiHeader,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard'; import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
@@ -29,6 +30,7 @@ export class ReviewController {
@ApiBearerAuth() @ApiBearerAuth()
@Post('public/reviews') @Post('public/reviews')
@ApiOperation({ summary: 'Create a new review and rating' }) @ApiOperation({ summary: 'Create a new review and rating' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiCreatedResponse({ description: 'The review has been successfully created.' }) @ApiCreatedResponse({ description: 'The review has been successfully created.' })
@ApiBody({ type: CreateReviewDto }) @ApiBody({ type: CreateReviewDto })
create(@Body() createReviewDto: CreateReviewDto, @UserId() userId: string) { create(@Body() createReviewDto: CreateReviewDto, @UserId() userId: string) {
@@ -37,6 +39,7 @@ export class ReviewController {
@Get('public/reviews/:foodId') @Get('public/reviews/:foodId')
@ApiOperation({ summary: 'Get all reviews of food by id(public - only approved)' }) @ApiOperation({ summary: 'Get all reviews of food by id(public - only approved)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'List of approved reviews' }) @ApiOkResponse({ description: 'List of approved reviews' })
@ApiParam({ name: 'foodId', required: true, type: String }) @ApiParam({ name: 'foodId', required: true, type: String })
@ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'page', required: false, type: Number })
@@ -50,6 +53,7 @@ export class ReviewController {
@Get('public/reviews/restuarant/:restuarantSlug') @Get('public/reviews/restuarant/:restuarantSlug')
@ApiOperation({ summary: 'Get all reviews of restuarant by slug(public - only approved)' }) @ApiOperation({ summary: 'Get all reviews of restuarant by slug(public - only approved)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'List of approved reviews' }) @ApiOkResponse({ description: 'List of approved reviews' })
@ApiParam({ name: 'restuarantSlug', required: true, type: String }) @ApiParam({ name: 'restuarantSlug', required: true, type: String })
@ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'page', required: false, type: Number })
@@ -74,6 +78,7 @@ export class ReviewController {
@ApiBearerAuth() @ApiBearerAuth()
@Patch('public/reviews/:reviewId') @Patch('public/reviews/:reviewId')
@ApiOperation({ summary: 'Update a review (own reviews only)' }) @ApiOperation({ summary: 'Update a review (own reviews only)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'reviewId', required: true }) @ApiParam({ name: 'reviewId', required: true })
@ApiBody({ type: UpdateReviewDto }) @ApiBody({ type: UpdateReviewDto })
@ApiOkResponse({ description: 'The updated review' }) @ApiOkResponse({ description: 'The updated review' })
@@ -85,6 +90,7 @@ export class ReviewController {
@ApiBearerAuth() @ApiBearerAuth()
@Delete('public/reviews/:id') @Delete('public/reviews/:id')
@ApiOperation({ summary: 'Delete a review (own reviews only)' }) @ApiOperation({ summary: 'Delete a review (own reviews only)' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiParam({ name: 'id', required: true }) @ApiParam({ name: 'id', required: true })
remove(@Param('id') id: string, @UserId() userId: string) { remove(@Param('id') id: string, @UserId() userId: string) {
return this.reviewService.remove(id, userId, false); return this.reviewService.remove(id, userId, false);
@@ -1,5 +1,5 @@
import { Controller, Get, Post, Body, Param, Patch, Delete, UseGuards } from '@nestjs/common'; import { Controller, Get, Post, Body, Param, Patch, Delete, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBody, ApiBearerAuth } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBody, ApiBearerAuth, ApiHeader } from '@nestjs/swagger';
import { RolesService } from '../providers/roles.service'; import { RolesService } from '../providers/roles.service';
import { PermissionsService } from '../providers/permissions.service'; import { PermissionsService } from '../providers/permissions.service';
import { CreateRoleDto } from '../dto/create-role.dto'; import { CreateRoleDto } from '../dto/create-role.dto';
@@ -1,6 +1,6 @@
import { type File, FileInterceptor, FilesInterceptor } from '@nest-lab/fastify-multer'; import { type File, FileInterceptor, FilesInterceptor } from '@nest-lab/fastify-multer';
import { Controller, Post, UploadedFile, UploadedFiles, UseGuards, UseInterceptors } from '@nestjs/common'; import { Controller, Post, UploadedFile, UploadedFiles, UseGuards, UseInterceptors } from '@nestjs/common';
import { ApiBody, ApiConsumes, ApiOperation, ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { ApiBody, ApiConsumes, ApiOperation, ApiBearerAuth, ApiTags, ApiHeader } from '@nestjs/swagger';
import { UploadMultipleFileDto, UploadSingleFileDto } from '../DTO/upload-file.dto'; import { UploadMultipleFileDto, UploadSingleFileDto } from '../DTO/upload-file.dto';
import { UploaderService } from '../providers/uploader.service'; import { UploaderService } from '../providers/uploader.service';
@@ -1,5 +1,5 @@
import { Controller, Get, UseGuards, Patch, Body, ValidationPipe, Post, Query, Delete, Param } from '@nestjs/common'; import { Controller, Get, UseGuards, Patch, Body, ValidationPipe, Post, Query, Delete, Param } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiBody, ApiOkResponse } from '@nestjs/swagger'; import { ApiTags, ApiBearerAuth, ApiOperation, ApiBody, ApiOkResponse, ApiHeader } from '@nestjs/swagger';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard'; import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { UserService } from '../providers/user.service'; import { UserService } from '../providers/user.service';
import { UpdateUserDto } from '../dto/update-user.dto'; import { UpdateUserDto } from '../dto/update-user.dto';
@@ -19,6 +19,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Get the current authenticated user profile' }) @ApiOperation({ summary: 'Get the current authenticated user profile' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@Get('public/user/me') @Get('public/user/me')
async getUser(@UserId() userId: string) { async getUser(@UserId() userId: string) {
const user = await this.userService.findById(userId); const user = await this.userService.findById(userId);
@@ -27,6 +28,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Update the authenticated user profile' }) @ApiOperation({ summary: 'Update the authenticated user profile' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: UpdateUserDto }) @ApiBody({ type: UpdateUserDto })
@Patch('public/user/update') @Patch('public/user/update')
async updateUser( async updateUser(
@@ -40,6 +42,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Get all addresses for the authenticated user' }) @ApiOperation({ summary: 'Get all addresses for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'List of user addresses' }) @ApiOkResponse({ description: 'List of user addresses' })
@Get('public/user/addresses') @Get('public/user/addresses')
async getUserAddresses(@UserId() userId: string) { async getUserAddresses(@UserId() userId: string) {
@@ -50,6 +53,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Create a new address for the authenticated user' }) @ApiOperation({ summary: 'Create a new address for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: CreateUserAddressDto }) @ApiBody({ type: CreateUserAddressDto })
@ApiOkResponse({ description: 'Created user address' }) @ApiOkResponse({ description: 'Created user address' })
@Post('public/user/addresses') @Post('public/user/addresses')
@@ -64,6 +68,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Get a single address by ID for the authenticated user' }) @ApiOperation({ summary: 'Get a single address by ID for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'User address details' }) @ApiOkResponse({ description: 'User address details' })
@Get('public/user/addresses/:addressId') @Get('public/user/addresses/:addressId')
async getUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) { async getUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) {
@@ -74,6 +79,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Update an address for the authenticated user' }) @ApiOperation({ summary: 'Update an address for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: UpdateUserAddressDto }) @ApiBody({ type: UpdateUserAddressDto })
@ApiOkResponse({ description: 'Updated user address' }) @ApiOkResponse({ description: 'Updated user address' })
@Patch('public/user/addresses/:addressId') @Patch('public/user/addresses/:addressId')
@@ -89,6 +95,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Delete an address for the authenticated user' }) @ApiOperation({ summary: 'Delete an address for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'Address deleted successfully' }) @ApiOkResponse({ description: 'Address deleted successfully' })
@Delete('public/user/addresses/:addressId') @Delete('public/user/addresses/:addressId')
async deleteUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) { async deleteUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) {
@@ -99,6 +106,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Set an address as default for the authenticated user' }) @ApiOperation({ summary: 'Set an address as default for the authenticated user' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiOkResponse({ description: 'Address set as default' }) @ApiOkResponse({ description: 'Address set as default' })
@Patch('public/user/addresses/:addressId/default') @Patch('public/user/addresses/:addressId/default')
async setDefaultAddress(@UserId() userId: string, @Param('addressId') addressId: string) { async setDefaultAddress(@UserId() userId: string, @Param('addressId') addressId: string) {
@@ -122,6 +130,7 @@ export class UsersController {
@UseGuards(AuthGuard) @UseGuards(AuthGuard)
@ApiBearerAuth() @ApiBearerAuth()
@ApiOperation({ summary: 'Convert user score (points) to wallet balance' }) @ApiOperation({ summary: 'Convert user score (points) to wallet balance' })
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier', example: 'zhivan' })
@ApiBody({ type: ConvertScoreToWalletDto }) @ApiBody({ type: ConvertScoreToWalletDto })
@Post('public/user/convert-score-to-wallet') @Post('public/user/convert-score-to-wallet')
async convertScoreToWallet(@UserId() userId: string, @Body() dto: ConvertScoreToWalletDto, @RestId() restId: string) { async convertScoreToWallet(@UserId() userId: string, @Body() dto: ConvertScoreToWalletDto, @RestId() restId: string) {
@@ -321,7 +321,6 @@ export class UserService {
(Number(pointsToConvert) * Number(restaurant.score.purchaseAmount)) / Number(restaurant.score.purchaseScore); (Number(pointsToConvert) * Number(restaurant.score.purchaseAmount)) / Number(restaurant.score.purchaseScore);
// Convert points to wallet (1:1 ratio - can be made configurable) // Convert points to wallet (1:1 ratio - can be made configurable)
// Update user's wallet and points // Update user's wallet and points
user.wallet = (user.wallet || 0) + walletIncreaseAmount; user.wallet = (user.wallet || 0) + walletIncreaseAmount;
user.points = user.points - pointsToConvert; user.points = user.points - pointsToConvert;
+30
View File
@@ -8,6 +8,16 @@ export interface RestaurantData {
type: 'Polygon'; type: 'Polygon';
coordinates: number[][][]; coordinates: number[][][];
}; };
score: {
purchaseAmount: string;
purchaseScore: string;
scoreAmount: string;
scoreCredit: string;
birthdayScore: string;
registerScore: string;
marriageDateScore: string;
referrerScore: string;
};
} }
export const restaurantsData: RestaurantData[] = [ export const restaurantsData: RestaurantData[] = [
@@ -29,6 +39,16 @@ export const restaurantsData: RestaurantData[] = [
], ],
], ],
}, },
score: {
purchaseAmount: '10000',
purchaseScore: '10000',
scoreAmount: '10000',
scoreCredit: '10000',
birthdayScore: '10000',
registerScore: '10000',
marriageDateScore: '10000',
referrerScore: '10000',
},
}, },
{ {
name: 'بوته', name: 'بوته',
@@ -48,5 +68,15 @@ export const restaurantsData: RestaurantData[] = [
], ],
], ],
}, },
score: {
purchaseAmount: '10000',
purchaseScore: '10000',
scoreAmount: '10000',
scoreCredit: '10000',
birthdayScore: '10000',
registerScore: '10000',
marriageDateScore: '10000',
referrerScore: '10000',
},
}, },
]; ];
+8 -8
View File
@@ -21,8 +21,8 @@ export const usersData: UserData[] = [
marriageDate: '2015-01-01', marriageDate: '2015-01-01',
isActive: true, isActive: true,
gender: true, gender: true,
wallet: 0, wallet: 250000,
points: 0, points: 100,
}, },
{ {
phone: '09185290775', phone: '09185290775',
@@ -33,8 +33,8 @@ export const usersData: UserData[] = [
marriageDate: '2017-01-01', marriageDate: '2017-01-01',
isActive: true, isActive: true,
gender: true, gender: true,
wallet: 0, wallet: 250000,
points: 0, points: 100,
}, },
{ {
phone: '09129283395', phone: '09129283395',
@@ -45,8 +45,8 @@ export const usersData: UserData[] = [
marriageDate: '2014-01-01', marriageDate: '2014-01-01',
isActive: true, isActive: true,
gender: true, gender: true,
wallet: 0, wallet: 250000,
points: 0, points: 100,
}, },
{ {
phone: '09184317567', phone: '09184317567',
@@ -57,7 +57,7 @@ export const usersData: UserData[] = [
marriageDate: '2020-01-01', marriageDate: '2020-01-01',
isActive: true, isActive: true,
gender: false, gender: false,
wallet: 0, wallet: 250000,
points: 0, points: 100,
}, },
]; ];