Skip to content

Commit 569a0e7

Browse files
authored
Merge pull request #801 from Mimah97/feat/users-swagger-paginated-response
fix(backend): Swagger pagination for users list uses concrete respons…
2 parents beda1e2 + 11d258c commit 569a0e7

3 files changed

Lines changed: 53 additions & 7 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2+
import { UserProfileDto } from './user-profile.dto';
3+
4+
/**
5+
* OpenAPI response shape for GET /users (cursor pagination).
6+
* Use this class in @ApiResponse({ type: ... }) so Swagger receives a runtime
7+
* constructor with a concrete `data` item type (avoid generic-only schemas).
8+
*/
9+
export class PaginatedUsersResponseDto {
10+
@ApiProperty({ description: 'Users for this page', type: [UserProfileDto] })
11+
data: UserProfileDto[];
12+
13+
@ApiPropertyOptional({
14+
description: 'Cursor for next page (last item ID)',
15+
nullable: true,
16+
})
17+
cursor: string | null;
18+
19+
@ApiProperty({ description: 'Number of items per page' })
20+
limit: number;
21+
22+
@ApiPropertyOptional({ description: 'Cursor token for the next page', nullable: true })
23+
nextCursor: string | null;
24+
25+
@ApiProperty({ description: 'Whether more items exist after this page' })
26+
hasMore: boolean;
27+
28+
@ApiPropertyOptional({ description: 'Total number of matching items (when known)' })
29+
total?: number;
30+
31+
@ApiPropertyOptional({ description: 'Current page number (1-based), page-mode responses' })
32+
page?: number;
33+
34+
@ApiPropertyOptional({ description: 'Total pages, page-mode responses' })
35+
totalPages?: number;
36+
}

backend/src/users-module/users.controller.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { UsersController } from './users.controller';
33
import { UsersService } from './users.service';
44
import { CreateUserDto } from './create-user.dto';
55
import { UpdateUserDto } from './update-user.dto';
6-
import { UserProfileDto, PaginationDto } from './user-profile.dto';
6+
import { UserProfileDto } from './user-profile.dto';
7+
import { PaginationDto } from '../common/dto';
8+
import { PaginatedUsersResponseDto } from './paginated-users-response.dto';
79

810
const mockProfile = (): UserProfileDto => ({
911
id: 'uuid-1',
@@ -40,6 +42,11 @@ describe('UsersController', () => {
4042
expect(controller).toBeDefined();
4143
});
4244

45+
it('uses PaginatedUsersResponseDto as a runtime Swagger response type', () => {
46+
expect(typeof PaginatedUsersResponseDto).toBe('function');
47+
expect(PaginatedUsersResponseDto.name).toBe('PaginatedUsersResponseDto');
48+
});
49+
4350
describe('create', () => {
4451
it('should create a user and return profile', async () => {
4552
const dto: CreateUserDto = {

backend/src/users-module/users.controller.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ import { CreateUserDto } from './create-user.dto';
2525
import { UpdateUserDto } from './update-user.dto';
2626
import { PaginationDto, PaginatedResponseDto } from '../common/dto';
2727
import { UserProfileDto } from './user-profile.dto';
28-
29-
type PaginatedUsersDto = PaginatedResponseDto<UserProfileDto> & {
30-
data: UserProfileDto[];
31-
};
28+
import { PaginatedUsersResponseDto } from './paginated-users-response.dto';
3229

3330
@ApiTags('Users')
3431
@Controller({ path: 'users', version: '1' })
@@ -50,8 +47,14 @@ export class UsersController {
5047
// GET /users
5148
@Get()
5249
@ApiOperation({ summary: 'List all users (paginated)' })
53-
@ApiResponse({ status: 200, description: 'Paginated users list', type: PaginatedResponseDto })
54-
findAll(@Query() pagination: PaginationDto): Promise<PaginatedUsersDto> {
50+
@ApiResponse({
51+
status: 200,
52+
description: 'Paginated users list (cursor-based)',
53+
type: PaginatedUsersResponseDto,
54+
})
55+
findAll(
56+
@Query() pagination: PaginationDto,
57+
): Promise<PaginatedResponseDto<UserProfileDto>> {
5558
return this.usersService.findAll(pagination);
5659
}
5760

0 commit comments

Comments
 (0)