Skip to content

Conversation

@jabibamman
Copy link
Collaborator

@jabibamman jabibamman commented Jul 2, 2025

Summary by CodeRabbit

  • New Features

    • Added paginated endpoints for listing rooms and virtual machines, accessible via new GET endpoints with support for page, limit, and optional includeCounts query parameters.
    • Updated API documentation to reflect new paginated responses.
    • Moved previous endpoints for retrieving all rooms and all virtual machines to /room/all and /vm/all.
    • Introduced paginated response formats for rooms and virtual machines, including optional counts of related entities for rooms.
  • Bug Fixes

    • None.
  • Tests

    • Added comprehensive unit tests for new paginated response DTOs and use cases for both rooms and virtual machines.
    • Extended controller test suites to cover paginated endpoints.
  • Chores

    • Added and updated mock implementations to support pagination in testing environments.

Summary by CodeRabbit

  • New Features

    • Added paginated endpoints for listing rooms, virtual machines (VMs), and user-accessible servers, with support for page and limit query parameters.
    • Responses for room, VM, and server lists now include pagination metadata (total items, current page, total pages).
    • Room list responses can optionally include server and UPS device counts per room.
  • Bug Fixes

    • None.
  • Tests

    • Introduced comprehensive tests for paginated list DTOs and use cases for rooms, VMs, and servers.
    • Updated controller and use case tests to validate pagination behavior and edge cases.
  • Documentation

    • Enhanced API documentation to reflect new paginated endpoints and query parameters.
  • Chores

    • Added and updated mock utilities for improved test coverage.

@coderabbitai
Copy link

coderabbitai bot commented Jul 2, 2025

"""

Walkthrough

Pagination support for both rooms and virtual machines has been introduced across controllers, DTOs, use cases, repositories, and interfaces. New paginated response DTOs and use cases were added, old endpoints for fetching all entities were moved, and comprehensive tests and mocks were implemented to cover the new paginated flows. Additionally, RoomResponseDto was extended to optionally include counts of servers and UPS devices.

Changes

File(s) Change Summary
.../rooms/domain/interfaces/room.repository.interface.ts Added paginate(page, limit) method to RoomRepositoryInterface.
.../rooms/infrastructure/repositories/room.typeorm.repository.ts Implemented paginate method for paginated room retrieval.
.../rooms/mocks/room.repository.mock.ts Added mocked paginate method to the room repository mock.
.../rooms/mocks/room.response.dto.mock.ts Added serverCount and upsCount properties to mocked RoomResponseDto.
.../rooms/application/dto/room.response.dto.ts Extended RoomResponseDto with optional serverCount and upsCount properties and updated factory method.
.../rooms/application/use-cases/get-room-list.use-case.ts Added new GetRoomListUseCase for paginated room listing.
.../rooms/application/use-cases/index.ts Exported and included GetRoomListUseCase in use case exports.
.../rooms/application/controllers/room.controller.ts Added paginated /room GET endpoint; moved all-rooms endpoint to /room/all; updated constructor.
.../rooms/application/dto/room.list.response.dto.ts Added RoomListResponseDto for paginated room responses.
.../rooms/application/dto/index.ts Exported RoomListResponseDto from DTO index.
.../rooms/application/controllers/room.controller.spec.ts Added tests for paginated room listing and default pagination.
.../rooms/application/use-cases/tests/get-room-list.use-case.spec.ts Added tests for GetRoomListUseCase.
.../rooms/application/dto/tests/room.list.response.dto.spec.ts Added tests for RoomListResponseDto.
.../rooms/application/dto/tests/room.response.dto.spec.ts Updated tests to include serverCount and upsCount in RoomResponseDto.
.../vms/domain/interfaces/vm.repository.interface.ts Added paginate(page, limit) method to VmRepositoryInterface.
.../vms/infrastructure/repositories/vm.typeorm.repository.ts Implemented paginate method for paginated VM retrieval.
.../vms/mocks/vm.repository.mock.ts Added mock VM repository with paginate method.
.../vms/mocks/index.ts Centralized exports for VM mocks.
.../vms/application/use-cases/get-vm-list.use-case.ts Added GetVmListUseCase for paginated VM listing.
.../vms/application/use-cases/index.ts Exported and included GetVmListUseCase in use case exports.
.../vms/application/controllers/vm.controller.ts Added paginated /vm GET endpoint; moved all-VMs endpoint to /vm/all; updated constructor.
.../vms/application/dto/vm.list.response.dto.ts Added VmListResponseDto for paginated VM responses.
.../vms/application/dto/index.ts Exported VmListResponseDto and other DTOs from index.
.../vms/application/controllers/tests/vm.controller.spec.ts Added tests for paginated VM listing and default pagination.
.../vms/application/use-cases/tests/get-vm-list.use-case.spec.ts Added tests for GetVmListUseCase.
.../vms/application/dto/tests/vm.list.response.dto.spec.ts Added tests for VmListResponseDto.
.../rooms/application/use-cases/tests/get-room-list.use-case.spec.ts Added tests for GetRoomListUseCase.
.../servers/application/controllers/server.controller.ts Updated getMyServers endpoint to support pagination with query params and return paginated response.
.../servers/application/dto/server.list.response.dto.ts Added ServerListResponseDto for paginated server responses.
.../servers/application/use-cases/get-user-servers.use-case.ts Modified execute method to support pagination and return paginated server list response.
.../servers/domain/interfaces/server.repository.interface.ts Added findAllByFieldPaginated method for paginated server retrieval.
.../servers/infrastructure/repositories/server.typeorm.repository.ts Implemented findAllByFieldPaginated method with pagination and filtering.
.../servers/application/controllers/tests/server.controller.spec.ts Expanded tests for getMyServers to cover pagination scenarios and empty results.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller
    participant UseCase
    participant Repository

    Client->>Controller: GET /room?page=1&limit=10&includeCounts=false (with JWT)
    Controller->>UseCase: execute(page=1, limit=10, includeCounts=false)
    UseCase->>Repository: paginate(page=1, limit=10)
    Repository-->>UseCase: [Room[], totalCount]
    UseCase-->>Controller: RoomListResponseDto (with optional counts)
    Controller-->>Client: Paginated room list

    Client->>Controller: GET /vm?page=1&limit=10 (with JWT)
    Controller->>UseCase: execute(page=1, limit=10)
    UseCase->>Repository: paginate(page=1, limit=10)
    Repository-->>UseCase: [Vm[], totalCount]
    UseCase-->>Controller: VmListResponseDto
    Controller-->>Client: Paginated VM list
Loading

Suggested labels

enhancement

Suggested reviewers

  • chikatetsu

Poem

In the warren of code, new tunnels appear,
Pagination for rooms and VMs is here!
With DTOs and mocks, and tests oh so neat,
Now lists are paged—what a treat!
Hop along, dear dev, and give a cheer,
For paginated queries are finally here!
🐇✨
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
src/modules/rooms/domain/interfaces/room.repository.interface.ts (1)

11-17: Interface design looks good with clear documentation.

The paginate method signature follows common pagination patterns. The JSDoc clearly documents the 1-based page numbering and parameter meanings.

Consider adding input validation in the implementation to handle edge cases like negative page numbers or zero/negative limits.

src/modules/rooms/application/dto/__tests__/room.list.response.dto.spec.ts (1)

5-21: Tests cover basic functionality well.

The test cases verify correct property assignment and totalPages calculation. The math is correct: Math.ceil(5/2) = 3 for the first test and Math.ceil(0/10) = 0 for the empty case.

Consider adding edge case tests for boundary conditions like invalid page numbers or page sizes, though this may depend on validation handled by the base PaginatedResponseDto class.

src/modules/rooms/application/dto/room.list.response.dto.ts (1)

14-21: Remove unnecessary constructor.

The constructor only calls the parent constructor without any additional logic, making it redundant. TypeScript will automatically handle this.

-  constructor(
-    items: RoomResponseDto[],
-    totalItems: number,
-    currentPage: number,
-    pageSize: number,
-  ) {
-    super(items, totalItems, currentPage, pageSize);
-  }
src/modules/rooms/application/use-cases/get-room-list.use-case.ts (1)

2-2: Fix typo in import path.

There's an extra slash in the import path.

-import { RoomRepositoryInterface } from '../..//domain/interfaces/room.repository.interface';
+import { RoomRepositoryInterface } from '../../domain/interfaces/room.repository.interface';
src/modules/vms/application/dto/vm.list.response.dto.ts (1)

14-21: Remove the unnecessary constructor.

The constructor only passes parameters to the parent class without adding any logic. The parent PaginatedResponseDto already handles these parameters appropriately.

-  constructor(
-    items: VmResponseDto[],
-    totalItems: number,
-    currentPage: number,
-    pageSize: number,
-  ) {
-    super(items, totalItems, currentPage, pageSize);
-  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a6fa64 and a182414.

📒 Files selected for processing (23)
  • src/modules/rooms/__mocks__/room.repository.mock.ts (1 hunks)
  • src/modules/rooms/application/controllers/room.controller.spec.ts (4 hunks)
  • src/modules/rooms/application/controllers/room.controller.ts (2 hunks)
  • src/modules/rooms/application/dto/__tests__/room.list.response.dto.spec.ts (1 hunks)
  • src/modules/rooms/application/dto/index.ts (1 hunks)
  • src/modules/rooms/application/dto/room.list.response.dto.ts (1 hunks)
  • src/modules/rooms/application/use-cases/__tests__/get-room-list.use-case.spec.ts (1 hunks)
  • src/modules/rooms/application/use-cases/get-room-list.use-case.ts (1 hunks)
  • src/modules/rooms/application/use-cases/index.ts (2 hunks)
  • src/modules/rooms/domain/interfaces/room.repository.interface.ts (1 hunks)
  • src/modules/rooms/infrastructure/repositories/room.typeorm.repository.ts (1 hunks)
  • src/modules/vms/__mocks__/index.ts (1 hunks)
  • src/modules/vms/__mocks__/vm.repository.mock.ts (1 hunks)
  • src/modules/vms/application/controllers/__tests__/vm.controller.spec.ts (5 hunks)
  • src/modules/vms/application/controllers/vm.controller.ts (3 hunks)
  • src/modules/vms/application/dto/__tests__/vm.list.response.dto.spec.ts (1 hunks)
  • src/modules/vms/application/dto/index.ts (1 hunks)
  • src/modules/vms/application/dto/vm.list.response.dto.ts (1 hunks)
  • src/modules/vms/application/use-cases/__tests__/get-vm-list.use-case.spec.ts (1 hunks)
  • src/modules/vms/application/use-cases/get-vm-list.use-case.ts (1 hunks)
  • src/modules/vms/application/use-cases/index.ts (2 hunks)
  • src/modules/vms/domain/interfaces/vm.repository.interface.ts (1 hunks)
  • src/modules/vms/infrastructure/repositories/vm.typeorm.repository.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
src/modules/rooms/application/dto/__tests__/room.list.response.dto.spec.ts (2)
src/modules/rooms/__mocks__/rooms.mock.ts (1)
  • createMockRoom (3-10)
src/modules/rooms/application/dto/room.list.response.dto.ts (1)
  • RoomListResponseDto (7-22)
src/modules/rooms/application/use-cases/__tests__/get-room-list.use-case.spec.ts (3)
src/modules/rooms/domain/interfaces/room.repository.interface.ts (1)
  • RoomRepositoryInterface (4-18)
src/modules/rooms/application/use-cases/index.ts (1)
  • GetRoomListUseCase (23-23)
src/modules/rooms/__mocks__/rooms.mock.ts (1)
  • createMockRoom (3-10)
src/modules/vms/application/dto/__tests__/vm.list.response.dto.spec.ts (2)
src/modules/vms/__mocks__/index.ts (1)
  • createMockVm (1-1)
src/modules/vms/application/dto/vm.list.response.dto.ts (1)
  • VmListResponseDto (7-22)
src/modules/vms/__mocks__/vm.repository.mock.ts (1)
src/modules/vms/__mocks__/index.ts (1)
  • mockVmRepository (2-2)
src/modules/vms/application/use-cases/__tests__/get-vm-list.use-case.spec.ts (3)
src/modules/vms/domain/interfaces/vm.repository.interface.ts (1)
  • VmRepositoryInterface (4-16)
src/modules/vms/application/use-cases/index.ts (1)
  • GetVmListUseCase (23-23)
src/modules/vms/__mocks__/index.ts (1)
  • createMockVm (1-1)
src/modules/vms/application/use-cases/get-vm-list.use-case.ts (3)
src/modules/vms/infrastructure/repositories/vm.typeorm.repository.ts (1)
  • Injectable (12-88)
src/modules/vms/domain/interfaces/vm.repository.interface.ts (1)
  • VmRepositoryInterface (4-16)
src/modules/vms/application/dto/vm.list.response.dto.ts (1)
  • VmListResponseDto (7-22)
src/modules/rooms/application/controllers/room.controller.spec.ts (1)
src/modules/rooms/application/use-cases/index.ts (1)
  • GetRoomListUseCase (23-23)
src/modules/vms/application/controllers/__tests__/vm.controller.spec.ts (3)
src/modules/vms/application/use-cases/index.ts (1)
  • GetVmListUseCase (23-23)
src/modules/vms/__mocks__/index.ts (1)
  • createMockVm (1-1)
src/modules/vms/__mocks__/vms.mock.ts (1)
  • createMockVm (4-11)
src/modules/rooms/application/controllers/room.controller.ts (2)
src/modules/rooms/application/use-cases/index.ts (1)
  • GetRoomListUseCase (23-23)
src/modules/rooms/application/dto/room.list.response.dto.ts (1)
  • RoomListResponseDto (7-22)
🪛 Biome (1.9.4)
src/modules/vms/application/dto/vm.list.response.dto.ts

[error] 14-21: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

src/modules/rooms/application/dto/room.list.response.dto.ts

[error] 14-21: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (30)
src/modules/rooms/__mocks__/room.repository.mock.ts (1)

13-13: LGTM! Mock method correctly added.

The addition of the paginate mock method aligns perfectly with the interface extension and supports testing of the new pagination functionality.

src/modules/rooms/application/use-cases/index.ts (1)

4-4: LGTM! Use case properly integrated.

The GetRoomListUseCase is correctly imported, added to the array, and exported following the established pattern of other use cases in the module.

Also applies to: 9-9, 23-23

src/modules/rooms/application/dto/index.ts (1)

3-3: LGTM! DTO properly exported.

The RoomListResponseDto is correctly imported and exported, making it available for use throughout the application.

Also applies to: 5-5

src/modules/rooms/infrastructure/repositories/room.typeorm.repository.ts (1)

52-59: LGTM! Clean TypeORM pagination implementation.

The pagination method correctly uses TypeORM's findAndCount with proper skip/take calculation and maintains consistency with the existing findAll method by loading the same relations.

src/modules/rooms/application/use-cases/__tests__/get-room-list.use-case.spec.ts (1)

1-35: LGTM! Comprehensive test coverage for pagination use case.

The test suite properly covers the main scenarios including pagination parameters, empty results, and verifies the correct interaction with the repository interface.

src/modules/rooms/application/use-cases/get-room-list.use-case.ts (1)

13-17: LGTM! Clean use case implementation with proper pagination logic.

The execute method correctly handles pagination parameters with sensible defaults and properly maps entities to DTOs before returning the paginated response.

src/modules/rooms/application/controllers/room.controller.spec.ts (4)

6-6: LGTM! Proper import addition for the new use case.

The import correctly includes the new GetRoomListUseCase needed for pagination functionality.


21-21: LGTM! Proper mock setup for the new use case.

The mock is correctly initialized to support testing the pagination functionality.


39-39: LGTM! Proper test module provider configuration.

The test module correctly provides the mocked GetRoomListUseCase for dependency injection.


59-73: LGTM! Comprehensive pagination test coverage.

The test cases properly verify both explicit pagination parameters and default values, ensuring the controller correctly delegates to the use case with the right parameters.

src/modules/rooms/application/controllers/room.controller.ts (2)

10-10: LGTM: Clean imports and dependency injection setup.

The imports and constructor dependency injection are properly implemented for the pagination functionality.

Also applies to: 17-17, 23-23, 27-27, 41-41


62-69: Verify intentional breaking change for GET /room endpoint

The getAllRooms route was moved from GET /room to GET /room/all, removing the root GET /room path:

  • No references to GET /room were found in API docs or client code.
  • This will break existing API consumers relying on GET /room.

Please confirm this is intentional and that you’ve documented or provided a migration/deprecation strategy (e.g., redirect, client notifications) for downstream users.

src/modules/vms/__mocks__/vm.repository.mock.ts (1)

1-1: LGTM! Clean and focused mock implementation.

The mock repository follows best practices with a simple factory function returning the necessary jest mock for the paginate method. This aligns well with the interface extension shown in other files.

src/modules/vms/application/use-cases/index.ts (3)

6-6: LGTM! Consistent import pattern.

The import follows the established naming convention and module structure.


9-9: Good placement in the use case array.

Adding GetVmListUseCase at the beginning of the array makes sense as it's the primary listing use case, with GetAllVmsUseCase serving as a fallback for non-paginated scenarios.


23-23: LGTM! Complete export pattern.

The export is properly included alongside other use cases, maintaining consistency with the module's export pattern.

src/modules/vms/application/dto/index.ts (1)

1-6: Excellent use of barrel export pattern.

This index file properly centralizes all VM-related DTOs, making imports cleaner throughout the application. The inclusion of the new VmListResponseDto alongside existing DTOs maintains consistency and improves module organization.

src/modules/vms/domain/interfaces/vm.repository.interface.ts (1)

9-15: Well-designed pagination interface.

The paginate method follows established patterns:

  • Clear JSDoc documentation with parameter descriptions
  • Standard tuple return type [Vm[], number] for items and total count
  • Appropriate parameter types with meaningful names

The interface extension maintains consistency with the existing repository pattern.

src/modules/vms/__mocks__/index.ts (1)

1-2: Excellent centralization of mock utilities.

This index file properly organizes mock exports, making it easier for tests to import the necessary mocks. The combination of existing VM mocks (createMockVm, createMockVmDto) with the new repository mock (mockVmRepository) provides comprehensive testing support for the pagination feature.

src/modules/vms/application/dto/__tests__/vm.list.response.dto.spec.ts (1)

5-21: LGTM! Comprehensive test coverage.

The tests properly verify both populated and empty pagination scenarios, including correct totalPages calculation (5 items ÷ 2 per page = 3 pages).

src/modules/vms/application/use-cases/__tests__/get-vm-list.use-case.spec.ts (1)

9-12: LGTM! Efficient mock setup.

The minimal mock approach focusing only on the paginate method is appropriate for unit testing this use case.

src/modules/vms/application/use-cases/get-vm-list.use-case.ts (1)

6-18: LGTM! Clean implementation following established patterns.

The use case correctly implements pagination logic with appropriate defaults, proper dependency injection, and correct DTO mapping.

src/modules/vms/application/controllers/__tests__/vm.controller.spec.ts (5)

7-7: LGTM! Proper test setup for new use case.

The addition of GetVmListUseCase to the imports maintains consistency with the existing test structure.


21-21: LGTM! Consistent mock declaration pattern.

The mock declaration follows the same pattern as other use case mocks in the test.


50-50: LGTM! Proper mock initialization.

The mock initialization is consistent with other use case mocks.


60-60: LGTM! Correct dependency injection setup.

The mock is properly provided in the testing module configuration.


95-111: LGTM! Comprehensive pagination endpoint testing.

The tests properly verify:

  • String-to-number parameter conversion ('1', '5' → 1, 5)
  • Default parameter usage when no arguments provided (1, 10)
  • Correct pass-through of use case results
src/modules/vms/application/dto/vm.list.response.dto.ts (1)

7-12: Well-structured paginated response DTO.

The class properly extends the generic PaginatedResponseDto and includes appropriate validation decorators for the items array. The use of @ValidateNested({ each: true }) ensures each VM response is validated individually.

src/modules/vms/application/controllers/vm.controller.ts (2)

66-71: Good separation of paginated vs. non-paginated endpoints.

Moving the original "get all" functionality to a dedicated /all route maintains backward compatibility while clearly distinguishing between paginated and non-paginated data retrieval.


55-58: Comprehensive API documentation for pagination.

The Swagger documentation properly describes the pagination parameters and response type, which will help API consumers understand the expected behavior.

Comment on lines 48 to 60
@Get()
@ApiOperation({
summary: 'Lister toutes les salles',
description: 'Renvoie la liste de toutes les salles disponibles.',
})
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiOperation({ summary: 'Lister les salles paginées' })
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@ApiResponse({ status: 200, type: RoomListResponseDto })
async getRooms(
@Query('page') page = '1',
@Query('limit') limit = '10',
): Promise<RoomListResponseDto> {
return this.getRoomListUseCase.execute(Number(page), Number(limit));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation for pagination parameters.

The implementation lacks validation for the page and limit query parameters, which could lead to runtime issues if invalid values are passed.

Consider these potential problems:

  • Number('invalid') returns NaN
  • Negative numbers or zero could cause repository issues
  • Very large numbers could impact performance

Apply this diff to add proper validation:

+import { IsOptional, IsPositive, Transform } from 'class-validator';

+class PaginationQueryDto {
+  @IsOptional()
+  @Transform(({ value }) => parseInt(value, 10))
+  @IsPositive()
+  page?: number = 1;
+
+  @IsOptional()
+  @Transform(({ value }) => parseInt(value, 10))
+  @IsPositive()
+  limit?: number = 10;
+}

 async getRooms(
-   @Query('page') page = '1',
-   @Query('limit') limit = '10',
+   @Query() query: PaginationQueryDto,
 ): Promise<RoomListResponseDto> {
-   return this.getRoomListUseCase.execute(Number(page), Number(limit));
+   return this.getRoomListUseCase.execute(query.page, query.limit);
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/modules/rooms/application/controllers/room.controller.ts around lines 48
to 60, the getRooms method lacks validation for the page and limit query
parameters, which can lead to runtime errors or performance issues if invalid
values are passed. To fix this, add validation logic to ensure page and limit
are positive integers within acceptable ranges before calling
getRoomListUseCase.execute. If the values are invalid, set them to default safe
values or throw a validation error. This prevents NaN, negative, zero, or
excessively large numbers from causing problems.

Comment on lines +60 to +67
async paginate(page: number, limit: number): Promise<[Vm[], number]> {
return this.findAndCount({
relations: ['permissions'],
skip: (page - 1) * limit,
take: limit,
order: { name: 'ASC' },
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and input validation.

The paginate method lacks error handling that exists in other repository methods like findAll. Additionally, consider validating input parameters to prevent issues with negative or zero values.

 async paginate(page: number, limit: number): Promise<[Vm[], number]> {
+  if (page < 1 || limit < 1) {
+    throw new Error('Page and limit must be positive numbers');
+  }
+  
+  try {
     return this.findAndCount({
       relations: ['permissions'],
       skip: (page - 1) * limit,
       take: limit,
       order: { name: 'ASC' },
     });
+  } catch (error) {
+    Logger.error('Error retrieving paginated VMs:', error);
+    throw new VmRetrievalException();
+  }
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/modules/vms/infrastructure/repositories/vm.typeorm.repository.ts around
lines 60 to 67, the paginate method currently lacks error handling and input
validation. Add validation to ensure page and limit are positive integers before
proceeding. Wrap the findAndCount call in a try-catch block to handle potential
errors gracefully, logging or rethrowing as appropriate to maintain consistency
with other repository methods.

@@ -0,0 +1,21 @@
import { createMockVm } from '@/modules/vms/__mocks__/vms.mock';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify import path consistency.

The import path '@/modules/vms/__mocks__/vms.mock' may be inconsistent with other files. Based on the relevant code snippets, createMockVm appears to be exported from '@/modules/vms/__mocks__/index.ts'.


🏁 Script executed:

#!/bin/bash
# Check which file exports createMockVm and verify the correct import path
fd -t f "vms.mock.ts" src/modules/vms/__mocks__/
fd -t f "index.ts" src/modules/vms/__mocks__/
rg -A 3 "export.*createMockVm" src/modules/vms/__mocks__/

Length of output: 962


Use the mock directory’s index export

The createMockVm helper is re-exported by src/modules/vms/__mocks__/index.ts. To stay consistent and leverage the directory index, update the import in your test:

• File: src/modules/vms/application/dto/tests/vm.list.response.dto.spec.ts

- import { createMockVm } from '@/modules/vms/__mocks__/vms.mock';
+ import { createMockVm } from '@/modules/vms/__mocks__';

This ensures all mock utilities are imported via the central __mocks__/index.ts.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { createMockVm } from '@/modules/vms/__mocks__/vms.mock';
-import { createMockVm } from '@/modules/vms/__mocks__/vms.mock';
+import { createMockVm } from '@/modules/vms/__mocks__';
🤖 Prompt for AI Agents
In src/modules/vms/application/dto/__tests__/vm.list.response.dto.spec.ts at
line 1, update the import statement to import createMockVm from the central mock
directory index file src/modules/vms/__mocks__/index.ts instead of directly from
vms.mock. This maintains consistency by using the directory’s index export for
all mock utilities.

Comment on lines +26 to +33
it('should handle empty list', async () => {
repo.paginate.mockResolvedValue([[], 0]);

const result = await useCase.execute();

expect(result.items).toEqual([]);
expect(result.totalItems).toBe(0);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve default parameter verification.

The test should explicitly verify that the default values (page=1, limit=10) are used when no parameters are provided.

 it('should handle empty list', async () => {
   repo.paginate.mockResolvedValue([[], 0]);

   const result = await useCase.execute();

+  expect(repo.paginate).toHaveBeenCalledWith(1, 10);
   expect(result.items).toEqual([]);
   expect(result.totalItems).toBe(0);
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('should handle empty list', async () => {
repo.paginate.mockResolvedValue([[], 0]);
const result = await useCase.execute();
expect(result.items).toEqual([]);
expect(result.totalItems).toBe(0);
});
it('should handle empty list', async () => {
repo.paginate.mockResolvedValue([[], 0]);
const result = await useCase.execute();
expect(repo.paginate).toHaveBeenCalledWith(1, 10);
expect(result.items).toEqual([]);
expect(result.totalItems).toBe(0);
});
🤖 Prompt for AI Agents
In src/modules/vms/application/use-cases/__tests__/get-vm-list.use-case.spec.ts
around lines 26 to 33, the test for handling an empty list does not verify that
the default pagination parameters page=1 and limit=10 are used when no
parameters are passed. Update the test to explicitly check that the
useCase.execute method calls the repository's paginate function with these
default values, ensuring the default parameter behavior is correctly tested.

Comment on lines 54 to +64
@Get()
@ApiOperation({
summary: 'Lister toutes les machines virtuelles',
description:
'Renvoie toutes les machines virtuelles enregistrées dans le système.',
})
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiOperation({ summary: 'Lister les VMs paginées' })
@ApiResponse({ status: 200, type: VmListResponseDto })
async getVms(
@Query('page') page = '1',
@Query('limit') limit = '10',
): Promise<VmListResponseDto> {
return this.getVmListUseCase.execute(Number(page), Number(limit));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for pagination parameters.

The pagination parameters lack validation to ensure they are positive integers and within reasonable bounds. Invalid values could cause unexpected behavior or performance issues.

Consider adding validation decorators to the query parameters:

  async getVms(
-    @Query('page') page = '1',
-    @Query('limit') limit = '10',
+    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
+    @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
  ): Promise<VmListResponseDto> {

You'll also need to import the additional pipes:

  ParseUUIDPipe,
  Query,
+ DefaultValuePipe,
+ ParseIntPipe,
  UseGuards,

Additionally, consider adding validation to ensure reasonable limits:

// In the method body
const validatedLimit = Math.min(Math.max(limit, 1), 100); // Cap at 100 items per page
const validatedPage = Math.max(page, 1); // Ensure page >= 1
return this.getVmListUseCase.execute(validatedPage, validatedLimit);
🤖 Prompt for AI Agents
In src/modules/vms/application/controllers/vm.controller.ts lines 54 to 64, the
pagination query parameters 'page' and 'limit' lack validation to ensure they
are positive integers and within reasonable bounds. Fix this by adding
validation decorators such as ParseIntPipe and Min(1) to the parameters, and
import these pipes from '@nestjs/common'. Also, inside the method, clamp 'limit'
to a maximum of 100 and ensure 'page' is at least 1 before passing them to
getVmListUseCase.execute.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/modules/rooms/application/dto/__tests__/room.response.dto.spec.ts (1)

8-21: Consider adding comprehensive test coverage for the new optional properties.

While the current test validates the DTO with count fields, additional test cases would improve coverage:

  1. Test DTO validation without count fields (since they're optional)
  2. Test invalid count values (negative numbers, non-numbers)
  3. Test the static from method with includeCounts true/false
+  it('should be valid without count fields', async () => {
+    const dto = plainToInstance(RoomResponseDto, {
+      id: '7c3dda0a-e6fb-4fd5-a8be-23fd45c77c8c',
+      name: 'Salle 1',
+      servers: [],
+      ups: [],
+    });
+
+    const errors = await validate(dto);
+    expect(errors.length).toBe(0);
+  });
+
+  it('should be invalid with non-numeric count fields', async () => {
+    const dto = plainToInstance(RoomResponseDto, {
+      id: '7c3dda0a-e6fb-4fd5-a8be-23fd45c77c8c',
+      name: 'Salle 1',
+      servers: [],
+      ups: [],
+      serverCount: 'invalid',
+      upsCount: 'invalid',
+    });
+
+    const errors = await validate(dto);
+    expect(errors.length).toBeGreaterThan(0);
+    expect(errors.some((e) => e.property === 'serverCount')).toBe(true);
+    expect(errors.some((e) => e.property === 'upsCount')).toBe(true);
+  });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a182414 and 0ab7674.

📒 Files selected for processing (7)
  • src/modules/rooms/__mocks__/room.response.dto.mock.ts (1 hunks)
  • src/modules/rooms/application/controllers/room.controller.spec.ts (4 hunks)
  • src/modules/rooms/application/controllers/room.controller.ts (2 hunks)
  • src/modules/rooms/application/dto/__tests__/room.response.dto.spec.ts (1 hunks)
  • src/modules/rooms/application/dto/room.response.dto.ts (2 hunks)
  • src/modules/rooms/application/use-cases/__tests__/get-room-list.use-case.spec.ts (1 hunks)
  • src/modules/rooms/application/use-cases/get-room-list.use-case.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/modules/rooms/mocks/room.response.dto.mock.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/modules/rooms/application/use-cases/tests/get-room-list.use-case.spec.ts
  • src/modules/rooms/application/use-cases/get-room-list.use-case.ts
  • src/modules/rooms/application/controllers/room.controller.spec.ts
  • src/modules/rooms/application/controllers/room.controller.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (5)
src/modules/rooms/application/dto/room.response.dto.ts (4)

8-9: LGTM! Imports are correctly added for new validation decorators.

The IsOptional and IsNumber imports are properly included to support the new optional count properties.


43-52: LGTM! Property declarations follow NestJS best practices.

The new optional properties are properly decorated with:

  • @ApiProperty({ required: false }) for Swagger documentation
  • @IsOptional() for validation flexibility
  • @IsNumber() for type safety

58-59: LGTM! Constructor properly handles the new optional parameters.

The constructor signature and assignment logic correctly handle the new optional count parameters.

Also applies to: 65-66


69-83: Pagination eagerly loads related entities for accurate counts
The RoomTypeormRepository.paginate method (src/modules/rooms/infrastructure/repositories/room.typeorm.repository.ts) already calls

this.repo.findAndCount({
  relations: ['servers', 'servers.ilo', 'ups'],});

so when RoomResponseDto.from(room, includeCounts) runs, both room.servers and room.ups are fully loaded and servers.length/ups.length will be correct. No further changes required.

src/modules/rooms/application/dto/__tests__/room.response.dto.spec.ts (1)

15-16: LGTM! Test correctly includes new optional properties.

The test appropriately includes serverCount: 0 and upsCount: 0 to validate the complete DTO structure with the new optional fields.

@jabibamman jabibamman removed the codex label Jul 2, 2025
@jabibamman jabibamman self-assigned this Jul 2, 2025
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jul 2, 2025

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
src/modules/servers/application/dto/server.list.response.dto.ts (1)

14-21: Remove unnecessary constructor.

The static analysis correctly identifies that this constructor is redundant since it only passes parameters to the superclass without any additional logic.

Apply this diff to remove the unnecessary constructor:

export class ServerListResponseDto extends PaginatedResponseDto<ServerResponseDto> {
  @ApiProperty({ type: () => ServerResponseDto, isArray: true })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ServerResponseDto)
  readonly items: ServerResponseDto[];
-
-  constructor(
-    items: ServerResponseDto[],
-    totalItems: number,
-    currentPage: number,
-    pageSize: number,
-  ) {
-    super(items, totalItems, currentPage, pageSize);
-  }
}

The base class constructor will be called automatically with the same parameters when instantiating this class.

src/modules/servers/infrastructure/repositories/server.typeorm.repository.ts (1)

98-104: Consider making the ordering configurable.

The implementation is correct, but the hardcoded order: { name: 'ASC' } might not be flexible enough for different use cases.

Consider adding an optional ordering parameter to the interface and method:

  async findAllByFieldPaginated<T extends PrimitiveFields<Server>>(
    {
      field,
      value,
      disableThrow = false,
      relations = [],
    }: FindAllByFieldOptions<Server, T>,
    page: number,
    limit: number,
+   order?: { [key: string]: 'ASC' | 'DESC' },
  ): Promise<[Server[], number]> {
    // ...
    return await this.findAndCount({
      where: whereClause,
      relations,
      skip: (page - 1) * limit,
      take: limit,
-     order: { name: 'ASC' },
+     order: order || { name: 'ASC' },
    });
src/modules/servers/application/use-cases/__tests__/get-user-servers.use-case.spec.ts (1)

115-117: Consider cleaning up the spy after each test.

The jest.spyOn(ServerResponseDto, 'fromEntity') is used in multiple tests but there's no visible cleanup. This could cause test pollution.

Add cleanup in an afterEach block:

+  afterEach(() => {
+    jest.restoreAllMocks();
+  });

Alternatively, consider using mockImplementationOnce if the mock is only needed for a single assertion.

Also applies to: 157-159, 194-196, 280-282

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab7674 and d4f90eb.

📒 Files selected for processing (10)
  • src/core/filters/__tests__/role.filter.spec.ts (1 hunks)
  • src/modules/rooms/application/use-cases/__tests__/get-room-by-id.use-case.spec.ts (2 hunks)
  • src/modules/servers/application/controllers/__tests__/server.controller.spec.ts (2 hunks)
  • src/modules/servers/application/controllers/server.controller.ts (4 hunks)
  • src/modules/servers/application/dto/server.list.response.dto.ts (1 hunks)
  • src/modules/servers/application/use-cases/__tests__/get-user-servers.use-case.spec.ts (2 hunks)
  • src/modules/servers/application/use-cases/get-user-servers.use-case.ts (5 hunks)
  • src/modules/servers/domain/interfaces/server.repository.interface.ts (1 hunks)
  • src/modules/servers/infrastructure/repositories/server.typeorm.repository.ts (1 hunks)
  • src/modules/users/domain/exceptions/user.exception.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/core/filters/tests/role.filter.spec.ts
  • src/modules/users/domain/exceptions/user.exception.ts
  • src/modules/rooms/application/use-cases/tests/get-room-by-id.use-case.spec.ts
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/modules/servers/domain/interfaces/server.repository.interface.ts (2)
src/core/types/primitive-fields.interface.ts (1)
  • PrimitiveFields (1-11)
src/core/utils/find-all-by-field.options.ts (1)
  • FindAllByFieldOptions (3-11)
src/modules/servers/application/controllers/server.controller.ts (3)
src/modules/servers/application/dto/server.list.response.dto.ts (1)
  • ServerListResponseDto (7-22)
src/core/decorators/current-user.decorator.ts (1)
  • CurrentUser (3-9)
src/core/types/jwt-payload.interface.ts (1)
  • JwtPayload (1-4)
src/modules/servers/infrastructure/repositories/server.typeorm.repository.ts (4)
src/core/types/primitive-fields.interface.ts (1)
  • PrimitiveFields (1-11)
src/core/utils/find-all-by-field.options.ts (1)
  • FindAllByFieldOptions (3-11)
src/core/exceptions/repository.exception.ts (1)
  • InvalidQueryValueException (1-6)
src/modules/servers/domain/exceptions/server.exception.ts (1)
  • ServerRetrievalException (25-29)
src/modules/servers/application/controllers/__tests__/server.controller.spec.ts (3)
src/modules/servers/__mocks__/servers.mock.ts (1)
  • createMockServerDto (37-42)
src/core/types/jwt-payload.interface.ts (1)
  • JwtPayload (1-4)
src/modules/servers/application/dto/server.list.response.dto.ts (1)
  • ServerListResponseDto (7-22)
src/modules/servers/application/use-cases/get-user-servers.use-case.ts (1)
src/modules/servers/application/dto/server.list.response.dto.ts (1)
  • ServerListResponseDto (7-22)
src/modules/servers/application/dto/server.list.response.dto.ts (1)
src/modules/servers/application/dto/server.response.dto.ts (1)
  • ServerResponseDto (12-92)
🪛 Biome (1.9.4)
src/modules/servers/application/dto/server.list.response.dto.ts

[error] 14-21: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (9)
src/modules/servers/domain/interfaces/server.repository.interface.ts (1)

12-16: LGTM! Clean interface extension for pagination support.

The new findAllByFieldPaginated method follows the established pattern and correctly returns a tuple containing both the results and total count, which is the standard approach for paginated queries.

src/modules/servers/application/use-cases/get-user-servers.use-case.ts (3)

24-28: LGTM! Well-designed pagination parameter handling.

The method signature properly defines default values for pagination parameters, maintaining backward compatibility while enabling pagination functionality.


63-72: Excellent implementation of paginated repository call.

The use of destructuring assignment to capture both the servers array and total count from the paginated repository method is clean and follows established patterns.


85-90: Consistent response handling with proper pagination metadata.

The construction of ServerListResponseDto correctly includes all pagination metadata (items, total count, current page, and page size), ensuring clients receive complete pagination information.

src/modules/servers/infrastructure/repositories/server.typeorm.repository.ts (1)

74-83: LGTM! Solid method signature and parameter handling.

The method signature correctly follows the established pattern and includes proper input validation for null/undefined values.

src/modules/servers/application/controllers/__tests__/server.controller.spec.ts (1)

216-288: Well-structured pagination tests!

The test cases comprehensively cover default pagination, custom parameters, and empty results. The assertions properly verify all pagination metadata fields.

src/modules/servers/application/use-cases/__tests__/get-user-servers.use-case.spec.ts (3)

4-4: Import added for pagination support.

The ServerListResponseDto import is correctly added to support the new paginated response format.


24-91: Excellent test organization for empty result scenarios.

The tests comprehensively cover all edge cases where empty paginated responses should be returned. The logical grouping improves test maintainability.


216-258: Robust error handling tests.

Good approach to return empty paginated responses on errors rather than throwing, ensuring consistent API responses. The tests verify that pagination parameters are preserved even in error cases.

Comment on lines +104 to +111
@Query('page') page = '1',
@Query('limit') limit = '10',
): Promise<ServerListResponseDto> {
return this.getUserServersUseCase.execute(
user.userId,
Number(page),
Number(limit),
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for pagination parameters.

The current implementation doesn't validate the page and limit parameters, which could lead to issues with invalid values (e.g., negative numbers, zero, or non-numeric strings).

Consider adding validation using NestJS validation pipes:

  async getMyServers(
    @CurrentUser() user: JwtPayload,
-   @Query('page') page = '1',
-   @Query('limit') limit = '10',
+   @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
+   @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
  ): Promise<ServerListResponseDto> {
-   return this.getUserServersUseCase.execute(
-     user.userId,
-     Number(page),
-     Number(limit),
-   );
+   // Add bounds validation
+   const validatedPage = Math.max(1, page);
+   const validatedLimit = Math.min(Math.max(1, limit), 100); // Cap at 100
+   
+   return this.getUserServersUseCase.execute(
+     user.userId,
+     validatedPage,
+     validatedLimit,
+   );
  }

Don't forget to import DefaultValuePipe and ParseIntPipe from @nestjs/common.

🤖 Prompt for AI Agents
In src/modules/servers/application/controllers/server.controller.ts around lines
104 to 111, the pagination parameters 'page' and 'limit' are currently accepted
as strings without validation, which can cause issues with invalid inputs. To
fix this, import DefaultValuePipe and ParseIntPipe from '@nestjs/common' and
apply them to the 'page' and 'limit' query parameters to ensure they are parsed
as integers with default values and validated to be positive numbers. This will
prevent negative, zero, or non-numeric values from being processed.

Comment on lines +101 to +102
skip: (page - 1) * limit,
take: limit,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add upper limit validation for performance protection.

Consider validating the limit parameter to prevent potential performance issues with very large page sizes.

Add validation at the beginning of the method:

  async findAllByFieldPaginated<T extends PrimitiveFields<Server>>(
    // ... parameters
  ): Promise<[Server[], number]> {
    if (value === undefined || value === null) {
      throw new InvalidQueryValueException(String(field), value);
    }
+   
+   // Validate pagination parameters
+   if (page < 1) {
+     throw new InvalidQueryValueException('page', page);
+   }
+   if (limit < 1 || limit > 1000) { // Cap at reasonable limit
+     throw new InvalidQueryValueException('limit', limit);
+   }

    try {
      // ... rest of implementation
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
skip: (page - 1) * limit,
take: limit,
async findAllByFieldPaginated<T extends PrimitiveFields<Server>>(
field: T,
value: Server[T],
page: number,
limit: number,
): Promise<[Server[], number]> {
if (value === undefined || value === null) {
throw new InvalidQueryValueException(String(field), value);
}
// Validate pagination parameters
if (page < 1) {
throw new InvalidQueryValueException('page', page);
}
if (limit < 1 || limit > 1000) { // Cap at reasonable limit
throw new InvalidQueryValueException('limit', limit);
}
try {
const [items, count] = await this.repository.findAndCount({
where: { [field]: value },
skip: (page - 1) * limit,
take: limit,
});
return [items, count];
} catch (error) {
// ... existing error handling ...
}
}
🤖 Prompt for AI Agents
In src/modules/servers/infrastructure/repositories/server.typeorm.repository.ts
around lines 101 to 102, the pagination parameters skip and take use the limit
value directly without validation, which can cause performance issues if limit
is too large. Add validation at the start of the method to enforce an upper
limit on the limit parameter, such as capping it to a maximum allowed value, to
prevent excessively large page sizes from degrading performance.

Comment on lines +293 to +311
it('should handle zero limit gracefully', async () => {
userRepo.findOneByField.mockResolvedValue({
id: 'user-zero',
roles: [{ id: 'role-zero' }],
});
permissionRepo.findAllByField.mockResolvedValue([
{ serverId: 'srv-zero', bitmask: PermissionBit.READ },
]);

serverRepo.findAllByFieldPaginated.mockResolvedValue([[], 1]);

const result = await useCase.execute('user-zero', 1, 0);

expect(result).toBeInstanceOf(ServerListResponseDto);
expect(result.items).toEqual([]);
expect(result.totalItems).toBe(1);
expect(result.currentPage).toBe(1);
expect(result.totalPages).toBe(Infinity);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle the zero limit edge case more gracefully.

When limit=0, the test expects totalPages=Infinity, which could cause issues with JSON serialization and frontend handling.

Consider handling this edge case in the use case implementation by either:

  1. Rejecting limit=0 with a validation error
  2. Defaulting to a minimum limit (e.g., 1)
  3. Returning totalPages=0 or totalPages=1 for this edge case

The current behavior with Infinity may not serialize properly in API responses.

🤖 Prompt for AI Agents
In
src/modules/servers/application/use-cases/__tests__/get-user-servers.use-case.spec.ts
around lines 293 to 311, the test expects totalPages to be Infinity when limit
is zero, which can cause serialization and frontend issues. Update the use case
implementation to handle limit=0 more gracefully by either rejecting it with a
validation error, defaulting the limit to a minimum value like 1, or returning
totalPages as 0 or 1 instead of Infinity. Adjust the test accordingly to reflect
this improved handling.

@jabibamman jabibamman merged commit 9382da7 into master Jul 2, 2025
3 checks passed
@jabibamman jabibamman deleted the pagine-endpoints-get-de-room,-ups-et-vms branch July 2, 2025 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants