Rules Hub
Coding Rules Library
← Back to all rules
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
backend ruleP1universalStack: node
api-designrestpaginationreadability
Do not overload pagination parameters with a hidden mode meaning
A numeric pagination parameter like limit or offset should carry only its literal, conventional meaning; never repurpose a special value (e.g. limit=0) to silently switch the endpoint into a different mode such as 'return counts only'.
PR: hegnar-shareholders-ws · org-mining-2026-06Created: Jun 17, 2026
Bad example
Old codetypescript
| 1 | // limit=0 secretly means 'don't return rows, just give me the total count' |
| 2 | @Get('transactions') |
| 3 | async list(@Query('limit') limit: number) { |
| 4 | if (limit === 0) { |
| 5 | const total = await this.repo.count(); |
| 6 | return { count: total }; // surprising: shape changes based on a magic value |
| 7 | } |
| 8 | return this.repo.find({ take: limit }); |
| 9 | } |
Explanation (EN)
Objašnjenje (HR)
Good example
New codetypescript
| 1 | // limit means what it says; a dedicated param/endpoint expresses intent |
| 2 | @Get('transactions') |
| 3 | async list( |
| 4 | @Query('limit') limit = 50, |
| 5 | @Query('countOnly') countOnly = false, |
| 6 | ) { |
| 7 | if (countOnly) { |
| 8 | return { total: await this.repo.count() }; |
| 9 | } |
| 10 | const [items, total] = await this.repo.findAndCount({ take: limit }); |
| 11 | return { items, total }; // stable, predictable response shape |
| 12 | } |
Explanation (EN)
Objašnjenje (HR)