Files
trackgo-be/.cursor/rules/pagination-response.mdc
shancheas 4c45a4371e Enhance pagination and ordering capabilities in API responses
- Updated pagination-response and read-write-controllers documentation to include `orderBy` and `orderType` parameters for sorting results.
- Introduced new `order-clause` module to handle ordering logic, including validation for order types and columns.
- Enhanced `PaginationQueryDto` to support ordering fields in API requests.
- Updated various repository and service classes to implement ordering in database queries.
- Added unit tests for new ordering functionality and ensured existing tests cover the updated behavior.
- Refactored related DTOs to include user and code relations for better data representation in responses.
2026-08-27 13:09:41 +07:00

63 lines
1.8 KiB
Plaintext

---
description: List endpoints use @Pagination() and return { data, total }; interceptor emits { data, meta }
globs: "src/**/*.controller.ts,src/common/http/**/*.ts,src/common/configure-app.ts"
alwaysApply: false
---
# Pagination Response Envelope
Canonical list HTTP shape (TrackGo-compatible). Shared code lives in `src/common/http/response/`.
## Handler vs public response
```typescript
// Handler return when marked @Pagination()
interface PaginationResponse<T> {
data: T[]
total: number
}
// Public response after TransformInterceptor
interface SuccessResponse<T> {
data: T
meta?: PaginationMeta
}
interface PaginationMeta {
currentPage: number
itemCount: number
itemsPerPage: number
totalItems: number
totalPages: number
}
```
## Mandatory
- Mark every list endpoint with `@Pagination()`
- Return `{ data, total }` from the handler — **never** build `meta` in the service or controller
- Query: `page`/`limit` or `offset`/`limit` (defaults `page=1`, `limit=10`; max limit `200`) plus `orderBy`/`orderType` (`ASC` | `DESC`, default `ASC`)
- Use `@RawResponse()` for file downloads / health probes that must skip wrapping
- Non-list handlers (detail, create, update, delete, status, import) pass through **unwrapped**
```typescript
// BAD — hand-rolled meta / success wrapper
return { success: true, data: items, meta: { total, page, limit } }
// GOOD
@Get()
@Pagination()
list(@Query() query: ListQueryDto): Promise<PaginationResponse<ItemDto>> {
return this.service.list(query) // { data, total }
}
```
## Forbidden
- `success: boolean` response wrappers for lists
- Putting `total` on `meta` instead of `totalItems`
- Computing `PaginationMeta` in feature services
- Documenting the internal `{ data, total }` shape in OpenAPI — document `{ data, meta }` instead
`TransformInterceptor` is registered globally in `configureApp`.