Files
trackgo-be/.cursor/rules/pagination-response.mdc
T
shancheas 0550cbe764 Implement pagination response handling and related enhancements
- Introduced `@Pagination()` decorator to mark list endpoints for pagination.
- Added `TransformInterceptor` to wrap responses in a standardized format `{ data, meta }`.
- Created pagination-related utility functions and constants for managing pagination logic.
- Defined `PaginationQueryDto` for handling pagination query parameters.
- Established `PaginationMetaDto` for OpenAPI documentation of pagination metadata.
- Updated existing controller and service structures to support pagination in responses.
- Added unit tests for pagination utilities and interceptor to ensure correct functionality.
2026-08-21 15:56:54 +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`)
- 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`.