Developer ResourcescatalogFeatured Featured Module API & Integration Guide
HTTP contract reference for catalog featured admin and customer/mobile APIs.
Audience: Mobile/web frontend developers
Scope: Featured content endpoints
- Module: Catalog / Featured
- Admin auth:
JwtAuthGuard + RoleGuard + @Permissions(Featured_*)
- Customer/mobile auth: public endpoint (
@Public())
- Surfaces:
- Admin:
/api/admin/featured
- Customer:
/api/featured
- Mobile:
/api/mobile/featured
Featured APIs allow admins to manage campaign slots tied to products and let public clients fetch active, in-window featured records.
- Featured row: one placement slot with title, linked
productId, optional categoryId, and ordering.
- Active-window filtering: customer responses require active flag + current-time date-window match.
- Date window invariant:
startDate not more than endDate when both values are set.
| Method | Path | Permission |
|---|
GET | /api/admin/featured | Featured_READ |
GET | /api/admin/featured/:id | Featured_READ |
POST | /api/admin/featured | Featured_CREATE |
PATCH | /api/admin/featured/:id | Featured_UPDATE |
DELETE | /api/admin/featured/:id | Featured_DELETE |
GET | /api/featured and /api/mobile/featured | Public |
| Aspect | Details |
|---|
| Endpoint | GET /api/featured or /api/mobile/featured |
| Auth | Public |
| Request | isActive filter |
| Response | ResponseDto<FeaturedDto[]> |
| Errors | - |
- Inherited from
QueryDto: pagination, page, size, search
- Filters:
categoryId, isActive
- Sort:
title | order | isActive | startDate | endDate | createdAt | updatedAt
- Order:
asc | desc
- Inherited from
QueryDto: page, size, search
- Defaults:
pagination=false, sort=order, order=asc, isActive=true
- Filters:
categoryId, optional isActive override
- Sort:
order | createdAt
"
"id": 301,
"title": "Top Picks This Week",
"description": "Campaign slot for high-converting products this week.",
"productId": 101,
"categoryId": 3,
"order": 0,
"isActive": true,
"startDate": "2026-02-21T00:00:00.000Z",
"endDate": "2026-03-21T23:59:59.999Z"
"
"
"title": "Top Picks This Week",
"productId": 101,
"categoryId": 3,
"order": 0,
"isActive": true
"
No module-specific DB enum is used for featured DTOs. Relevant constrained values come from DTO allowlists:
- admin sort:
title | order | isActive | startDate | endDate | createdAt | updatedAt
- customer sort:
order | createdAt
- order:
asc | desc
| Prefix | Usage |
|---|
catalog:featured:list: | customer featured list cache |
Admin write operations invalidate catalog:featured:active* and catalog:featured:list:*.
| HTTP | errorCode | Condition |
|---|
| 400 | FEATURED_INVALID_DATE_RANGE | startDate is after endDate |
| 400 | CATEGORY_NOT_FOUND | Provided categoryId does not exist |
| 400 | FEATURED_INVALID_SORT | Unsupported customer sort field |
| 404 | FEATURED_NOT_FOUND | Featured row not found |
| Method | Path | Auth / Permission | Request DTO / Params | Success DTO | Notes |
|---|
| GET | /api/admin/featured | Admin + Featured_READ | QueryFeaturedAdminDto "" page?, size?, pagination?, search?, categoryId?, isActive?, sort?, order? "" | FeaturedAdminListItemDto[] paginated | Admin featured list |
| GET | /api/admin/featured/:id | Admin + Featured_READ | path: id (int) | FeaturedAdminDetailDto | Admin featured detail |
| POST | /api/admin/featured | Admin + Featured_CREATE | body: CreateFeaturedDto "" title, description?, productId, categoryId?, order?, isActive?, startDate?, endDate? "" | FeaturedAdminDetailDto | Creates new featured slot |
| PATCH | /api/admin/featured/:id | Admin + Featured_UPDATE | path: id (int), body: UpdateFeaturedDto "" title?, description?, productId?, categoryId?, order?, isActive?, startDate?, endDate? "" | FeaturedAdminDetailDto | Updates featured slot |
| DELETE | /api/admin/featured/:id | Admin + Featured_DELETE | path: id (int) | "" success: true "" | Deletes featured slot |
| GET | /api/featured | Public | QueryFeaturedDto "" page?, size?, isActive?, categoryId?, sort?, order? "" | FeaturedResponseDto[] | Customer featured list |
| GET | /api/mobile/featured | Public | QueryFeaturedDto "" page?, size?, isActive?, categoryId?, sort?, order? "" | FeaturedResponseDto[] | Mobile featured list |
| Method | Path | Query Parameters | Notes |
|---|
| GET | /api/admin/featured | (no params) | Default: page=1, size=20, sort=createdAt, order=desc |
| GET | /api/admin/featured | ?page=2&size=10 | Custom page and size |
| GET | /api/admin/featured | ?search=promo | Search by title |
| GET | /api/admin/featured | ?categoryId=3 | Filter by category |
| GET | /api/admin/featured | ?isActive=true | Active featured only |
| GET | /api/admin/featured | ?isActive=false | Inactive featured only |
| GET | /api/admin/featured | ?sort=title&order=asc | Sort by title |
| GET | /api/admin/featured | ?sort=order&order=asc | Sort by order |
| GET | /api/admin/featured | ?sort=startDate&order=asc | Sort by start date |
| GET | /api/admin/featured | ?sort=endDate&order=desc | Sort by end date descending |
| Method | Path | Query Parameters | Notes |
|---|
| GET | /api/featured | (no params) | Default: no pagination, sort=order, order=asc, isActive=true |
| GET | /api/featured | ?page=1&size=10 | Paginated request |
| GET | /api/featured | ?isActive=true | Explicit active filter |
| GET | /api/featured | ?isActive=false | Inactive items |
| GET | /api/featured | ?categoryId=3 | Filter by category |
| GET | /api/featured | ?sort=order&order=asc | Sort by display order |
| GET | /api/featured | ?sort=createdAt&order=desc | Sort by creation date |
| GET | /api/mobile/featured | ?categoryId=1&isActive=true | Mobile: active items in category |
| Scenario | startDate | endDate | isActive | Result |
|---|
| Currently active | 2026-01-01 | 2026-12-31 | true | Returned in customer list |
| Future start | 2026-06-01 | 2026-12-31 | true | Not returned (not in window) |
| Past end | 2026-01-01 | 2026-03-01 | true | Not returned (window expired) |
| Inactive | any | any | false | Not returned (filtered) |
| No dates (always active) | null | null | true | Returned if isActive=true |
| Method | Path | Request Body | Notes |
|---|
| POST | /api/admin/featured | "" "title": "Top Picks", "productId": 101 "" | Minimal create |
| POST | /api/admin/featured | "" "title": "Summer Sale", "productId": 101, "categoryId": 3, "isActive": true "" | With category and active |
| POST | /api/admin/featured | "" "title": "Weekend Deal", "productId": 102, "order": 0 "" | With order |
| POST | /api/admin/featured | "" "title": "Limited Time", "productId": 103, "startDate": "2026-04-01", "endDate": "2026-04-07" "" | With date window |
| POST | /api/admin/featured | "" "title": "Featured Thangka", "productId": 104, "description": "Highlighted this month" "" | With description |
| Method | Path | Request Body | Notes |
|---|
| PATCH | /api/admin/featured/1 | "" "title": "New Title" "" | Update title only |
| PATCH | /api/admin/featured/1 | "" "productId": 102 "" | Change linked product |
| PATCH | /api/admin/featured/1 | "" "isActive": false "" | Deactivate featured slot |
| PATCH | /api/admin/featured/1 | "" "order": 5 "" | Update display order |
| PATCH | /api/admin/featured/1 | "" "startDate": "2026-05-01", "endDate": "2026-05-31" "" | Update date window |
| PATCH | /api/admin/featured/1 | "" "categoryId": null "" | Remove category filter |
| Scenario | Constraint | Error |
|---|
| startDate > endDate | Start date after end date | FEATURED_INVALID_DATE_RANGE |
| Both required for window | If startDate set, endDate must be set | - |
| Category must exist | categoryId must reference valid category | CATEGORY_NOT_FOUND |
| HTTP | errorCode | Message | Scenario |
|---|
| 400 | FEATURED_INVALID_DATE_RANGE | Start date must be before end date. | startDate > endDate |
| 400 | CATEGORY_NOT_FOUND | Category not found. | Invalid categoryId |
| 400 | FEATURED_INVALID_SORT | Invalid sort field. | Unsupported sort |
| 404 | FEATURED_NOT_FOUND | Featured not found. | Invalid ID |
| Cache Key | Pattern | TTL (seconds) | Invalidation |
|---|
| Customer featured list | catalog:featured:list:isActive:"isActive"-categoryId:"categoryId"-sort:"sort"-order:"order" | 300 | Admin create/update/delete |
| Admin featured list | catalog:featured:admin:list:pagination:"page"-size:"size"-filters... | 60 | Admin mutations |
| Route Family | Key Pattern | Limit |
|---|
| Customer list | rl:catalog:featured:customer:list-ip:"ip" | 60 req/min |
| Admin list | rl:catalog:featured:admin:list-key:"adminId" | 60 req/min |
| Admin mutations | rl:catalog:featured:admin:mutate-key:"adminId" | 30 req/min |
| Field | Type | Required | Validation | Notes |
|---|
| title | string | Yes | 1-200 chars | Featured slot title |
| description | string | No | Max 500 chars | Description text |
| productId | integer | Yes | Positive integer | Linked product ID |
| categoryId | number | No | Positive integer | Optional category filter |
| order | number | No | Integer, default 0 | Display order |
| isActive | boolean | No | Default true | Active flag |
| startDate | string | No | ISO 8601 date | Window start date |
| endDate | string | No | ISO 8601 date | Window end date |
| Field | Type | Required | Validation | Notes |
|---|
| title | string | No | 1-200 chars | Featured slot title |
| description | string | No | Max 500 chars | Description text |
| productId | number | No | Positive integer | Linked product ID |
| categoryId | number | No | Positive integer | Optional category filter |
| order | number | No | Integer | Display order |
| isActive | boolean | No | - | Active flag |
| startDate | string | No | ISO 8601 date | Window start date |
| endDate | string | No | ISO 8601 date | Window end date |
| Field | Type | Required | Notes |
|---|
| page | number | No | Page number |
| size | number | No | Page size |
| pagination | boolean | No | (admin only) Enable pagination |
| search | string | No | (admin only) Search query |
| categoryId | number | No | Filter by category |
| isActive | boolean | No | Filter by active status |
| sort | string | No | Sort field |
| order | string | No | Sort order |
- Admin creates featured slot with future startDate; not returned in customer list (outside window).
- Admin creates featured slot with past endDate; not returned in customer list (window expired).
- Featured slot with both dates set and current time within window; returned in customer list.
- Customer list returns only
isActive=true records; inactive slots filtered out.
- Admin attempts to create featured with startDate after endDate; receives
400 FEATURED_INVALID_DATE_RANGE.
- Featured endpoint filtered by categoryId; returns only matching category slots.