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.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
---
|
||||
description: All status data must use the Status value object; extend CORE_STATUSES via allowed list — do not invent parallel helpers
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Status Value Object
|
||||
|
||||
## Mandatory
|
||||
|
||||
ALL status fields on primary entities in the domain and application layers MUST use `Status` from `src/common/value-objects/status/`.
|
||||
|
||||
- Construct via `Status.create(raw)` (core set) or `Status.create(raw, allowed)` (module extensions)
|
||||
- Default new records with `Status.DEFAULT` (`draft`) when status is omitted
|
||||
- Compare with `equals()`, serialize with `value` / `toString()` / `toJSON()`
|
||||
- Persist and transmit the canonical string from `status.value`
|
||||
|
||||
Core statuses (source of truth): `draft`, `active`, `archived`. Modules may pass an `allowed` list that adds values (e.g. `in_transit`).
|
||||
|
||||
## Forbidden
|
||||
|
||||
Do NOT:
|
||||
|
||||
- Store or pass status as an unvalidated plain `string` in domain models or services (beyond the DTO/HTTP or DB string boundary)
|
||||
- Add status enums, validators, maps, or helpers that bypass the VO
|
||||
- Create new files for status validation or normalization
|
||||
- Echo raw invalid input in error messages
|
||||
|
||||
```typescript
|
||||
// BAD
|
||||
user.status = 'Draft'
|
||||
function normalizeStatus(raw: string): string { /* ... */ }
|
||||
|
||||
// GOOD
|
||||
const status = Status.create(dto.status ?? Status.DEFAULT)
|
||||
entity.status = status
|
||||
await repo.save({ status: status.value })
|
||||
|
||||
// GOOD — module extension
|
||||
const status = Status.create(dto.status, [...CORE_STATUSES, 'in_transit'])
|
||||
```
|
||||
|
||||
## When the VO is not enough
|
||||
|
||||
1. **Update** `src/common/value-objects/status/` (implementation + colocated tests), or pass a wider `allowed` list at the call site
|
||||
2. Do **not** invent a parallel status type or module
|
||||
|
||||
## Boundaries
|
||||
|
||||
- HTTP DTOs may accept `string`; map to `Status.create()` at the service boundary
|
||||
- Database columns may store `text` (default `'draft'`); map to/from `Status` in the repository
|
||||
- `InvalidStatusError` is the only status validation error; do not echo raw input in messages
|
||||
Reference in New Issue
Block a user