1
0

Fix pagination params silently ignored on collection GET endpoints

Hoist `page` and `pageSize` declarations from the per-module DTOs into
the shared DynamicFilterQueryDto base class. Without these declarations,
the global ValidationPipe (whitelist: true) strips the params from the
request before the service layer sees them, so list services fall back
to their default page=1, pageSize=12 regardless of what the client sent.

Affects 10 collection GET endpoints whose query DTOs are empty subclasses
of DynamicFilterQueryDto: expenses, bills, credit-notes, manual-journals,
payments-received, sale-invoices, sale-estimates, sale-receipts,
vendor-credits, item-categories.

The 3 already-working DTOs (Customers, Vendors, Items) keep their local
page/pageSize declarations as redundant overrides — no behavior change.

Closes #1088
This commit is contained in:
Chris
2026-04-29 11:51:49 +00:00
parent 52c97f1401
commit 46012a1b1c
2 changed files with 25 additions and 1 deletions
@@ -1,9 +1,21 @@
import { ToNumber } from '@/common/decorators/Validators';
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsArray, IsOptional, IsString } from 'class-validator';
import { IsArray, IsInt, IsOptional, IsString } from 'class-validator';
import { IFilterRole, ISortOrder } from '../DynamicFilter/DynamicFilter.types';
export class DynamicFilterQueryDto {
@ApiPropertyOptional({ description: 'Page number (1-based)', type: Number })
@IsOptional()
@IsInt()
@ToNumber()
page?: number;
@ApiPropertyOptional({ description: 'Page size', type: Number })
@IsOptional()
@IsInt()
@ToNumber()
pageSize?: number;
@ApiPropertyOptional({ description: 'Custom view ID', type: Number })
@IsOptional()
@ToNumber()
+12
View File
@@ -77,4 +77,16 @@ describe('Expenses (e2e)', () => {
.set('Authorization', AuthorizationHeader)
.expect(200);
});
it('/expenses (GET) honors page and pageSize query params', async () => {
const response = await request(app.getHttpServer())
.get('/expenses?page=2&pageSize=5')
.set('organization-id', orgainzationId)
.set('Authorization', AuthorizationHeader)
.expect(200);
expect(response.body.pagination).toBeDefined();
expect(response.body.pagination.page).toBe(2);
expect(response.body.pagination.page_size).toBe(5);
});
});