Repository: hngprojects/hng_boilerplate_nestjs

Issue:
[FEAT] Pagination for Get All Waitlist
## Description
The `getAllWaitlist` endpoint currently retrieves all waitlist members without any pagination. As the number of waitlist members grows, this could lead to performance issues and increased database load. Implementing pagination will enhance efficiency and scalability for this endpoint.

## Acceptance Criteria

- [ ] The `getAllWaitlist` endpoint should accept optional page and limit query parameters.

- [ ] The `WaitlistService.getAllWaitlist` method should implement pagination using the page and limit parameters via skip and take (or equivalent ORM methods).

- [ ] The API should return a paginated response with a subset of waitlist members based on the `page` and `limit` parameters.

- [ ] API documentation (Swagger) should be updated to reflect the new page and limit parameters for the `getAllWaitlist ` endpoint.

- [ ] Default values for page and limit should be defined (e.g., page=1, limit=10) if the parameters are not provided in the request.

- [ ] The response should include the total number of waitlist members available.

## Purpose
Implementing pagination for the `getAllWaitlist` endpoint will improve the performance and scalability of the application by reducing the amount of data retrieved from the database and transmitted over the network. This is especially important as the number of waitlist members grows.

## Requirements

- Modify the `getAllWaitlist` method in `WaitlistController` to accept optional page and limit query parameters.

- Modify the `WaitlistService.getAllWaitlist` method to use the page and limit parameters to implement pagination using skip and take.

- Update the API documentation (Swagger) to reflect the new page and limit parameters.

- Ensure that the existing functionality of `getAllWaitlist` remains intact when `page` and `limit` parameters are not provided.

- Update DTOs to include the total number of waitlist members found.

Expected Outcome
The `getAllWaitlist` endpoint will return a paginated response with a subset of waitlist members based on the `page` and `limit` parameters. The API documentation will be updated to reflect the new parameters, improving performance and scalability.

JSON Response Example:
```bash
{
  "status": "success",
  "status_code": 200,
  "message": "Waitlist retrieved successfully",
  "data": {
    "waitlist": [
      {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "full_name": "John Doe",
        "email": "johndoe@example.com"
      },
     {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "full_name": "John Doe",
        "email": "johndoe@example.com"
      },
    ],
  }
  total: 150
}


Discussion:
@AdeGneus: Format the markdown properly and complete the fields for the issue

Solution patch:
diff --git a/src/modules/comments/comments.controller.ts b/src/modules/comments/comments.controller.ts
index a0d6f48d..c9a4b623 100644
--- a/src/modules/comments/comments.controller.ts
+++ b/src/modules/comments/comments.controller.ts
@@ -1,4 +1,4 @@
-import { Controller, Body, Post, Request, Get, Param } from '@nestjs/common';
+import { Controller, Body, Post, Request, Get, Param, Delete } from '@nestjs/common';
 import { CommentsService } from './comments.service';
 import { CreateCommentDto } from './dtos/create-comment.dto';
 import { CommentResponseDto } from './dtos/comment-response.dto';
@@ -25,4 +25,11 @@ export class CommentsController {
   async getAComment(@Param('id') id: string): Promise<any> {
     return await this.commentsService.getAComment(id);
   }
+
+  @ApiOperation({ summary: 'Delete a comment' })
+  @ApiResponse({ status: 200, description: 'The comment has been deleted successfully.' })
+  @Delete(':id/delete')
+  async deleteAComment(@Param('id') id: string, @Request() req): Promise<any> {
+    return await this.commentsService.deleteAComment(id, req.user.userId);
+  }
 }
diff --git a/src/modules/comments/comments.service.ts b/src/modules/comments/comments.service.ts
index 14469c78..c6cec2f7 100644
--- a/src/modules/comments/comments.service.ts
+++ b/src/modules/comments/comments.service.ts
@@ -53,4 +53,25 @@ export class CommentsService {
       data: { comment },
     };
   }
+
+  async deleteAComment(commentId: string, userId: string) {
+    const comment = await this.commentRepository.findOne({ where: { id: commentId }, relations: ['user'] });
+    if (!comment) {
+      throw new CustomHttpException('Comment not found', HttpStatus.NOT_FOUND);
+    }
+
+    const isOwner = comment.user.id === userId;
+
+    if (!isOwner) {
+      throw new CustomHttpException('You are not authorized to delete this comment', HttpStatus.FORBIDDEN);
+    }
+
+    await this.commentRepository.delete(comment);
+
+    return {
+      message: 'Comment deleted successfully!',
+      status: HttpStatus.OK,
+      data: { comment },
+    };
+  }
 }
diff --git a/src/modules/products/products.controller.ts b/src/modules/products/products.controller.ts
index f03ce781..8e00f1c2 100644
--- a/src/modules/products/products.controller.ts
+++ b/src/modules/products/products.controller.ts
@@ -171,6 +171,28 @@ export class ProductsController {
     return this.productsService.addCommentToProduct(productId, commentDto, user.sub);
   }
 
+  @ApiBearerAuth()
+  @UseGuards(SuperAdminGuard)
+  @Post('organisations/:productId/comments/:commentId')
+  @ApiBearerAuth()
+  @ApiOperation({ summary: 'Edits a comment for a product' })
+  @ApiParam({ name: 'id', description: 'organisation ID', example: '870ccb14-d6b0-4a50-b459-9895af803i89' })
+  @ApiParam({ name: 'productId', description: 'product ID', example: '126ccb14-d6b0-4a50-b459-9895af803h6y' })
+  @ApiBody({ type: AddCommentDto, description: 'Comment to be edited' })
+  @ApiResponse({ status: 201, description: 'Comment updated successfully' })
+  @ApiResponse({ status: 400, description: 'Bad request' })
+  @ApiResponse({ status: 404, description: 'Not found' })
+  @ApiResponse({ status: 500, description: 'Internal server error' })
+  async editProductComment(
+    @Param('productId') productId: string,
+    @Param('commentId') commentId: string,
+    @Body() commentDto: AddCommentDto,
+    @Req() req: any
+  ) {
+    const user = req.user;
+    return this.productsService.editProductComment(productId, commentId, commentDto, user.sub);
+  }
+
   @ApiBearerAuth()
   @UseGuards(OwnershipGuard)
   @Get('organisations/:orgId/products/:productId/stock')
diff --git a/src/modules/products/products.service.ts b/src/modules/products/products.service.ts
index 0482ea83..cc28301b 100644
--- a/src/modules/products/products.service.ts
+++ b/src/modules/products/products.service.ts
@@ -239,6 +239,41 @@ export class ProductsService {
     };
   }
 
+  async editProductComment(productId: string, commentId: string, commentDto: AddCommentDto, userId: string) {
+    const c = commentDto;
+
+    const product = await this.productRepository.findOne({ where: { id: productId } });
+
+    if (!product) {
+      throw new CustomHttpException(SYS_MSG.PRODUCT_NOT_FOUND, HttpStatus.NOT_FOUND);
+    }
+
+    const comment = await this.commentRepository.findOne({ where: { id: commentId } });
+
+    if (!comment) {
+      throw new CustomHttpException(SYS_MSG.COMMENT_NOT_FOUND, HttpStatus.NOT_FOUND);
+    }
+
+    if (comment.user.id !== userId) {
+      throw new CustomHttpException(SYS_MSG.COMMENT_NOT_FOUND, HttpStatus.NOT_FOUND);
+    }
+
+    await this.commentRepository.update(commentId, { comment: c.comment });
+
+    const responsePayload = {
+      id: comment.id,
+      product_id: product.id,
+      comment: c.comment,
+      user_id: userId,
+      created_at: new Date(),
+    };
+
+    return {
+      message: SYS_MSG.COMMENT_EDITED,
+      data: responsePayload,
+    };
+  }
+
   async getProductStock(productId: string) {
     const product = await this.productRepository.findOne({ where: { id: productId } });
     if (!product) {
diff --git a/src/modules/timezones/timezones.controller.ts b/src/modules/timezones/timezones.controller.ts
index f739fb34..ae2c9653 100644
--- a/src/modules/timezones/timezones.controller.ts
+++ b/src/modules/timezones/timezones.controller.ts
@@ -1,4 +1,4 @@
-import { Controller, Post, Body, Get, Res, HttpStatus, Patch, Param } from '@nestjs/common';
+import { Controller, Post, Body, Get, Res, HttpStatus, Patch, Param, Delete } from '@nestjs/common';
 import { ApiTags, ApiOperation, ApiResponse, ApiBody, ApiBearerAuth } from '@nestjs/swagger';
 import { CreateTimezoneDto } from './dto/create-timezone.dto';
 import { UpdateTimezoneDto } from './dto/update-timezone.dto';
@@ -38,4 +38,12 @@ export class TimezonesController {
   async updateTimezone(@Param('id') id: string, @Body() updateTimezoneDto: UpdateTimezoneDto) {
     return this.timezonesService.updateTimezone(id, updateTimezoneDto);
   }
+  @Delete(':id')
+  @ApiBearerAuth()
+  @ApiOperation({ summary: 'Delete a timezone' })
+  @ApiResponse({ status: 200, description: 'Timezone successfully deleted.' })
+  @ApiResponse({ status: 404, description: 'Timezone not found.' })
+  async deleteTimezone(@Param('id') id: string) {
+    return this.timezonesService.deleteTimezone(id);
+  }
 }
diff --git a/src/modules/timezones/timezones.service.spec.ts b/src/modules/timezones/timezones.service.spec.ts
index 6f712e06..33f5094c 100644
--- a/src/modules/timezones/timezones.service.spec.ts
+++ b/src/modules/timezones/timezones.service.spec.ts
@@ -3,6 +3,7 @@ import { TimezonesService } from './timezones.service';
 import { getRepositoryToken } from '@nestjs/typeorm';
 import { Repository } from 'typeorm';
 import { Timezone } from './entities/timezone.entity';
+import { NotFoundException } from '@nestjs/common';
 
 const mockTimezoneRepository = {
   findOne: jest.fn(),
@@ -34,3 +35,51 @@ describe('TimezonesService', () => {
     expect(service).toBeDefined();
   });
 });
+
+describe('TimezonesService - deleteTimezone', () => {
+  let service: TimezonesService;
+  let timezoneRepository: Repository<Timezone>;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [
+        TimezonesService,
+        {
+          provide: getRepositoryToken(Timezone),
+          useClass: Repository,
+        },
+      ],
+    }).compile();
+
+    service = module.get<TimezonesService>(TimezonesService);
+    timezoneRepository = module.get<Repository<Timezone>>(getRepositoryToken(Timezone));
+  });
+
+  it('should successfully delete a timezone', async () => {
+    const mockId = '123';
+
+    const mockTimezone: Timezone = {
+      id: '123',
+      timezone: 'UTC',
+      gmtOffset: '0',
+      description: 'Coordinated Universal Time',
+      created_at: new Date(),
+      updated_at: new Date(),
+    };
+    jest.spyOn(timezoneRepository, 'findOne').mockResolvedValue(mockTimezone);
+    jest.spyOn(timezoneRepository, 'delete').mockResolvedValue({ affected: 1 } as any);
+
+    const result = await service.deleteTimezone(mockId);
+
+    expect(result).toEqual({
+      status_code: 200,
+      message: 'Timezone deleted successfully',
+    });
+  });
+
+  it('should throw NotFoundException if timezone is not found', async () => {
+    jest.spyOn(timezoneRepository, 'findOne').mockResolvedValue(null);
+
+    await expect(service.deleteTimezone('invalid-id')).rejects.toThrow(NotFoundException);
+  });
+});
diff --git a/src/modules/timezones/timezones.service.ts b/src/modules/timezones/timezones.service.ts
index 4c6b4548..f5057de5 100644
--- a/src/modules/timezones/timezones.service.ts
+++ b/src/modules/timezones/timezones.service.ts
@@ -17,6 +17,7 @@ import {
   TIMEZONE_CREATED_SUCCESSFULLY,
   SUCCESS,
   FETCH_TIMEZONE_FAILURE,
+  TIMEZONE_DELETED_SUCCESSFULLY,
 } from '@shared/constants/SystemMessages';
 
 @Injectable()
@@ -61,6 +62,7 @@ export class TimezonesService {
     try {
       const timezones = await this.timezoneRepository.find();
       const formattedTimezones = timezones.map(tz => ({
+        id: tz.id,
         timezone: tz.timezone,
         gmtOffset: tz.gmtOffset,
         description: tz.description,
@@ -106,4 +108,33 @@ export class TimezonesService {
       });
     }
   }
+
+  async deleteTimezone(id: string): Promise<any> {
+    try {
+      const timezone = await this.timezoneRepository.findOne({ where: { id } });
+      if (!timezone) {
+        throw new NotFoundException({
+          status_code: HttpStatus.NOT_FOUND,
+          message: 'Timezone not found',
+        });
+      }
+
+      await this.timezoneRepository.delete(id);
+
+      return {
+        status_code: HttpStatus.OK,
+        message: TIMEZONE_DELETED_SUCCESSFULLY,
+      };
+    } catch (error) {
+      Logger.error('TimezonesServiceError ~ deleteTimezone ~', error);
+      if (error instanceof NotFoundException) {
+        throw error;
+      }
+
+      throw new InternalServerErrorException({
+        message: ERROR_OCCURED,
+        status_code: HttpStatus.INTERNAL_SERVER_ERROR,
+      });
+    }
+  }
 }
diff --git a/src/modules/waitlist/waitlist.service.ts b/src/modules/waitlist/waitlist.service.ts
index 49f5ba19..656d1c39 100644
--- a/src/modules/waitlist/waitlist.service.ts
+++ b/src/modules/waitlist/waitlist.service.ts
@@ -7,6 +7,7 @@ import { CreateWaitlistDto } from './dto/create-waitlist.dto';
 import { WaitlistResponseDto } from './dto/create-waitlist-response.dto';
 import * as SYS_MSG from '@shared/constants/SystemMessages';
 import { CustomHttpException } from '@shared/helpers/custom-http-filter';
+import { STATUS_CODES } from 'http';
 
 @Injectable()
 export default class WaitlistService {
@@ -34,8 +35,25 @@ export default class WaitlistService {
     return { message: 'You are all signed up!' };
   }
 
-  async getAllWaitlist() {
-    const waitlist = await this.waitlistRepository.find();
-    return { message: 'Waitlist found successfully', data: { waitlist } };
+  async getAllWaitlist(page: number = 1, limit: number = 10) {
+    if (page < 1) page = 1;
+    if (limit < 1) limit = 10;
+
+    const [waitlist, total] = await this.waitlistRepository.findAndCount({
+      skip: (page - 1) * limit,
+      take: limit,
+    });
+
+    return {
+      status: 'Success',
+      status_code: 200,
+      message: 'Waitlist found successfully',
+      data: {
+        waitlist,
+        total_waitlist_count: total,
+        current_page: page,
+        total_pages: Math.ceil(total / limit),
+      },
+    };
   }
 }
diff --git a/src/shared/constants/SystemMessages.ts b/src/shared/constants/SystemMessages.ts
index 64b9f74f..97c04837 100644
--- a/src/shared/constants/SystemMessages.ts
+++ b/src/shared/constants/SystemMessages.ts
@@ -23,6 +23,7 @@ export const WORK_IN_PROGRESS = 'Work in progress';
 export const FETCH_LANGUAGE_FAILURE = 'Failed to fetch language';
 export const UNAUTHORISED_TOKEN = 'Invalid token or email';
 export const TIMEZONE_CREATED_SUCCESSFULLY = 'Timezone created Successfully';
+export const TIMEZONE_DELETED_SUCCESSFULLY = 'Timezone deleted successfully';
 export const FETCH_TIMEZONE_FAILURE = 'Error Occured while creating Timezone, kindly try again';
 export const SUCCESS = 'Timezone fetched successfully';
 export const TIMEZONE_ALREADY_EXISTS = 'Timezone already exists';
@@ -46,6 +47,8 @@ export const REQUEST_SUCCESSFUL = 'Request completed successfully';
 export const PAYMENT_NOTFOUND = 'Payment plan not found';
 export const PRODUCT_NOT_FOUND = 'Product not found!';
 export const COMMENT_CREATED = 'Comment added successfully';
+export const COMMENT_NOT_FOUND = 'Comment not found';
+export const COMMENT_EDITED = 'Comment edited successfully';
 export const ORG_UPDATE = 'Organisation updated successfully';
 export const ORG_MEMBER_NOT_FOUND = 'Member not found';
 export const ORG_MEMBER_DOES_NOT_BELONG = 'Member does not belong to the specified organisation';



Test patch:
diff --git a/src/modules/comments/tests/comments.service.spec.ts b/src/modules/comments/tests/comments.service.spec.ts
index 02a34b91..403ce827 100644
--- a/src/modules/comments/tests/comments.service.spec.ts
+++ b/src/modules/comments/tests/comments.service.spec.ts
@@ -11,6 +11,8 @@ import { HttpStatus } from '@nestjs/common';
 const mockCommentRepository = () => ({
   create: jest.fn(),
   save: jest.fn(),
+  findOne: jest.fn(),
+  delete: jest.fn(),
 });
 
 const mockUserRepository = () => ({
@@ -75,5 +77,58 @@ describe('CommentsService', () => {
         commentedBy: 'John Doe',
       });
     });
+
+    describe('deleteComment', () => {
+      it('should throw CustomHttpException if comment is not found', async () => {
+        commentRepository.findOne.mockResolvedValue(null);
+
+        await expect(service.deleteAComment('comment-id', 'user-id')).rejects.toThrow(CustomHttpException);
+        await expect(service.deleteAComment('comment-id', 'user-id')).rejects.toMatchObject({
+          message: 'Comment not found',
+          status: HttpStatus.NOT_FOUND,
+        });
+      });
+
+      it('should throw CustomHttpException if user is not the owner of the comment', async () => {
+        const mockOwner = { id: 'owner-id' };
+        const mockComment = { id: 'comment-id', user: mockOwner };
+
+        commentRepository.findOne.mockResolvedValue(mockComment);
+
+        await expect(service.deleteAComment('comment-id', 'another-user-id')).rejects.toThrow(CustomHttpException);
+        await expect(service.deleteAComment('comment-id', 'another-user-id')).rejects.toMatchObject({
+          message: 'You are not authorized to delete this comment',
+          status: HttpStatus.FORBIDDEN,
+        });
+      });
+
+      it('should delete a comment successfully', async () => {
+        const commentId = 'comment-id';
+        const userId = 'user-id';
+        const mockUser = { id: 'user-id' };
+        const mockComment = {
+          id: 'comment-id',
+          model_id: '1',
+          model_type: 'post',
+          comment: 'A valid comment',
+          user: mockUser,
+        };
+
+        commentRepository.findOne.mockResolvedValue(mockComment);
+        commentRepository.delete.mockResolvedValue(mockComment);
+
+        console.log(await commentRepository.findOne({ where: { id: commentId }, relations: ['user'] })); // Debugging
+
+        const result = await service.deleteAComment(commentId, userId);
+
+        expect(commentRepository.findOne).toHaveBeenCalledWith({ where: { id: commentId }, relations: ['user'] });
+        expect(commentRepository.delete).toHaveBeenCalledWith(mockComment);
+        expect(result).toEqual({
+          message: 'Comment deleted successfully!',
+          status: HttpStatus.OK,
+          data: { comment: mockComment },
+        });
+      });
+    });
   });
 });
diff --git a/src/modules/timezones/tests/timezones.controller.spec.ts b/src/modules/timezones/tests/timezones.controller.spec.ts
index e0f8fe8e..17b55e01 100644
--- a/src/modules/timezones/tests/timezones.controller.spec.ts
+++ b/src/modules/timezones/tests/timezones.controller.spec.ts
@@ -5,7 +5,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
 import { Repository } from 'typeorm';
 import { Timezone } from '../entities/timezone.entity';
 import { CreateTimezoneDto } from '../dto/create-timezone.dto';
-import { HttpException, HttpStatus } from '@nestjs/common';
+import { HttpException, HttpStatus, NotFoundException } from '@nestjs/common';
 
 const mockTimezoneRepository = {
   findOne: jest.fn(),
@@ -175,3 +175,44 @@ describe('TimezonesController', () => {
     });
   });
 });
+
+describe('TimezonesController - deleteTimezone', () => {
+  let controller: TimezonesController;
+  let service: TimezonesService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      controllers: [TimezonesController],
+      providers: [
+        {
+          provide: TimezonesService,
+          useValue: {
+            deleteTimezone: jest.fn(),
+          },
+        },
+      ],
+    }).compile();
+
+    controller = module.get<TimezonesController>(TimezonesController);
+    service = module.get<TimezonesService>(TimezonesService);
+  });
+
+  it('should successfully delete a timezone', async () => {
+    jest.spyOn(service, 'deleteTimezone').mockResolvedValue({
+      status_code: 200,
+      message: 'Timezone deleted successfully',
+    });
+
+    const response = await controller.deleteTimezone('123');
+    expect(response).toEqual({
+      status_code: 200,
+      message: 'Timezone deleted successfully',
+    });
+  });
+
+  it('should return NotFoundException if timezone does not exist', async () => {
+    jest.spyOn(service, 'deleteTimezone').mockRejectedValue(new NotFoundException());
+
+    await expect(controller.deleteTimezone('invalid-id')).rejects.toThrow(NotFoundException);
+  });
+});
diff --git a/src/modules/waitlist/tests/waitlist.service.spec.ts b/src/modules/waitlist/tests/waitlist.service.spec.ts
index f0a2647d..2deeb054 100644
--- a/src/modules/waitlist/tests/waitlist.service.spec.ts
+++ b/src/modules/waitlist/tests/waitlist.service.spec.ts
@@ -15,6 +15,7 @@ describe('WaitlistService', () => {
 
   const mockWaitlistRepository = {
     find: jest.fn(),
+    findAndCount: jest.fn(),
     save: jest.fn(),
     create: jest.fn(),
     findOne: jest.fn(),
@@ -48,10 +49,67 @@ describe('WaitlistService', () => {
   });
 
   describe('getAllWaitlist', () => {
-    it('should return all waitlist', async () => {
-      await waitlistService.getAllWaitlist();
+    it('should return paginated waitlist results with default values when no parameters are provided', async () => {
+      // Arrange: setup default values (page = 1, limit = 10)
+      const mockWaitlistEntries = [
+        { id: '1', full_name: 'Alice', email: 'alice@example.com' },
+        { id: '2', full_name: 'Bob', email: 'bob@example.com' },
+      ];
+      const totalCount = 2;
+      mockWaitlistRepository.findAndCount = jest.fn().mockResolvedValue([mockWaitlistEntries, totalCount]);
 
-      expect(waitlistRepository.find).toHaveBeenCalled();
+      // Act: call service without pagination parameters
+      const result = await waitlistService.getAllWaitlist();
+
+      // Assert: defaults (skip: 0, take: 10) should be used
+      expect(mockWaitlistRepository.findAndCount).toHaveBeenCalledWith({
+        skip: 0,
+        take: 10,
+      });
+      expect(result).toEqual({
+        status: 'Success',
+        status_code: 200,
+        data: {
+          current_page: 1,
+          total_pages: 1, // since totalCount is 2 and default limit is 10
+          total_waitlist_count: totalCount,
+          waitlist: mockWaitlistEntries,
+        },
+        message: 'Waitlist found successfully',
+      });
+    });
+
+    it('should return paginated waitlist results with provided page and limit', async () => {
+      // Arrange: setup custom pagination values
+      const mockWaitlistEntries = [
+        { id: '3', full_name: 'Charlie', email: 'charlie@example.com' },
+        { id: '4', full_name: 'David', email: 'david@example.com' },
+      ];
+      const totalCount = 20;
+      mockWaitlistRepository.findAndCount = jest.fn().mockResolvedValue([mockWaitlistEntries, totalCount]);
+
+      const page = 2;
+      const limit = 5;
+
+      // Act: call service with page and limit parameters
+      const result = await waitlistService.getAllWaitlist(page, limit);
+
+      // Assert: ensure proper skip and take values
+      expect(mockWaitlistRepository.findAndCount).toHaveBeenCalledWith({
+        skip: (page - 1) * limit, // (2-1)*5 = 5
+        take: limit, // 5
+      });
+      expect(result).toEqual({
+        status: 'Success',
+        status_code: 200,
+        data: {
+          current_page: page, // e.g., 2
+          total_pages: Math.ceil(totalCount / limit), // e.g., 4 if totalCount is 20 and limit is 5
+          total_waitlist_count: totalCount,
+          waitlist: mockWaitlistEntries,
+        },
+        message: 'Waitlist found successfully',
+      });
     });
   });