Context:
The feed must load signals quickly (<2s) and support infinite scrolling. Users should see fresh, relevant signals prioritized by quality and recency.
Problem:
Build a paginated API that returns signals efficiently with cursor-based pagination and smart filtering.
What Done Looks Like:
- GET
/signals/feed with cursor pagination
- Filtering by asset, provider, performance
- Sorting by recency, popularity, success rate
- Response time under 2 seconds
- Cache frequently accessed pages
Folder Structure:
src/
├── signals/
│ ├── signals.controller.ts
│ ├── signals.service.ts
│ └── dto/
│ ├── signal-feed-query.dto.ts
│ └── signal-feed-response.dto.ts
Implementation Guidelines:
- Use cursor-based pagination (not offset/limit)
- Return 20 signals per page by default
- Include
nextCursor in response for infinite scroll
- Cache feed pages in Redis (30s TTL)
- Eager load related data (provider stats, asset info)
- Apply default filter: status=ACTIVE, not expired
Query Parameters:
cursor: string (optional, for pagination)
limit: number (default 20, max 50)
asset: string (e.g., "USDC/XLM")
provider: string (wallet address)
sortBy: "recent" | "popular" | "performance"
Response Format:
{
"signals": [...],
"nextCursor": "eyJpZCI6MTIzNH0=",
"hasMore": true
}
Validation:
- First page loads under 2s
- Pagination works correctly
- Cache reduces database hits
- Filters apply correctly
Context:
The feed must load signals quickly (<2s) and support infinite scrolling. Users should see fresh, relevant signals prioritized by quality and recency.
Problem:
Build a paginated API that returns signals efficiently with cursor-based pagination and smart filtering.
What Done Looks Like:
/signals/feedwith cursor paginationFolder Structure:
Implementation Guidelines:
nextCursorin response for infinite scrollQuery Parameters:
cursor: string (optional, for pagination)limit: number (default 20, max 50)asset: string (e.g., "USDC/XLM")provider: string (wallet address)sortBy: "recent" | "popular" | "performance"Response Format:
{ "signals": [...], "nextCursor": "eyJpZCI6MTIzNH0=", "hasMore": true }Validation: