polysignal_hackaton / backend /docs /WATCHLIST.md
blackmistcode's picture
Add files using upload-large-folder tool
71b8eb2 verified
|
Raw
History Blame Contribute Delete
3.76 kB
# WATCHLIST.md — Módulo de watchlist
Mercados favoritos del usuario con umbral de alerta opcional. Cuando `yesPrice >= alertThreshold`, el job `processAlerts` crea una `Alert` y envía notificación por Telegram.
**Todos los endpoints requieren `Authorization: Bearer <token>`.**
---
## Endpoints
### `POST /api/v1/watchlist`
Añade un mercado a la watchlist del usuario.
**Body**
```json
{
"marketId": "559677",
"alertThreshold": 0.75
}
```
| Campo | Tipo | Descripción |
|---|---|---|
| `marketId` | string | ID del mercado (debe existir en DB) |
| `alertThreshold` | float (0–1) \| null | Precio YES que dispara la alerta; `null` para no alertar |
**Respuesta `201`**
```json
{
"ok": true,
"data": {
"id": 2,
"userId": 1,
"marketId": "559677",
"alertThreshold": 0.75,
"createdAt": "2026-05-16T09:21:41.606Z",
"market": {
"id": "559677",
"question": "Will Hillary Clinton win the 2028 Democratic presidential nomination?",
"yesPrice": 0.0075,
"noPrice": 0.9925,
"status": "active"
}
}
}
```
**Respuesta `409`** — mercado ya está en la watchlist del usuario:
```json
{
"ok": false,
"error": { "code": "CONFLICT", "message": "Market already in watchlist" }
}
```
---
### `GET /api/v1/watchlist`
Lista todos los mercados en la watchlist del usuario con datos de mercado embebidos.
**Respuesta `200`**
```json
{
"ok": true,
"data": [
{
"id": 2,
"userId": 1,
"marketId": "559677",
"alertThreshold": 0.001,
"createdAt": "2026-05-16T09:21:41.606Z",
"market": {
"id": "559677",
"question": "Will Hillary Clinton win the 2028 Democratic presidential nomination?",
"yesPrice": 0.0075,
"noPrice": 0.9925,
"status": "active"
}
}
]
}
```
---
### `DELETE /api/v1/watchlist/:marketId`
Elimina un mercado de la watchlist del usuario.
**Params**
| Param | Tipo | Descripción |
|---|---|---|
| `marketId` | string | ID del mercado |
**Respuesta `204`** — sin body.
**Respuesta `404`**
```json
{
"ok": false,
"error": { "code": "NOT_FOUND", "message": "Watchlist entry not found" }
}
```
---
## Lógica de alertas
El job `processAlerts` (cron `* * * * *`) evalúa cada entrada de watchlist con `alertThreshold` definido:
- Si `market.yesPrice >= alertThreshold` → crea `Alert` + envía Telegram + emite `price_alert` por socket.
- Deduplicación: no se crea una segunda alerta si ya existe una para el mismo mercado en los últimos 5 min.
Para recibir alertas por Telegram, el usuario debe tener `telegramChatId` configurado en su perfil (campo opcional en `User`).
---
## Ejemplos `curl`
```bash
TOKEN=$(curl -s -X POST http://localhost:7860/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"admin@polysignal.test","password":"Admin123!"}' | jq -r '.data.token')
# Añadir a watchlist con umbral 75%
curl -s -X POST http://localhost:7860/api/v1/watchlist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"marketId":"559677","alertThreshold":0.75}' | jq
# Listar watchlist
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:7860/api/v1/watchlist | jq
# Eliminar de watchlist
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
"http://localhost:7860/api/v1/watchlist/559677"
```
---
## Códigos de error
| HTTP | Código | Cuándo |
|---|---|---|
| `400` | `VALIDATION_ERROR` | Body inválido (marketId vacío, threshold fuera de 0–1) |
| `401` | `UNAUTHORIZED` | Sin token o token inválido |
| `404` | `NOT_FOUND` | Mercado no existe en DB o entrada no encontrada al borrar |
| `409` | `CONFLICT` | Mercado ya en watchlist |
| `500` | `INTERNAL` | Error inesperado |