---
id: ET-MKT-002
title: Especificacion de API - Marketplace
type: technical-spec
status: Draft
priority: High
epic: OQI-009
project: trading-platform
version: 1.0.0
dates:
  created: 2026-01-04
  updated: 2026-01-04
tags:
  - marketplace
  - api
  - rest
  - endpoints
---

# ET-MKT-002: Especificacion de API

## Resumen

Este documento define los endpoints REST API para el modulo de Marketplace (OQI-009). Incluye endpoints para productos, compras, suscripciones, asesoria y visualizacion premium.

## Base URL

```
/api/v1/marketplace
```

## Autenticacion

Todos los endpoints requieren autenticacion via JWT Bearer token, excepto los marcados como publicos.

```http
Authorization: Bearer <jwt_token>
```

## Endpoints de Productos

### GET /products

Lista productos del marketplace.

**Query Parameters:**
| Parametro | Tipo | Requerido | Descripcion |
|-----------|------|-----------|-------------|
| category | string | No | Filtrar por categoria (slug) |
| type | string | No | Filtrar por tipo de producto |
| search | string | No | Busqueda en nombre/descripcion |
| featured | boolean | No | Solo productos destacados |
| sort | string | No | Ordenamiento: price_asc, price_desc, rating, newest |
| page | number | No | Pagina (default: 1) |
| limit | number | No | Items por pagina (default: 12, max: 50) |

**Response 200:**
```json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Pro Signal Pack",
      "slug": "pro-signal-pack",
      "shortDescription": "200 senales ML de alta confianza",
      "type": "signal_pack",
      "price": 29.00,
      "currency": "USD",
      "billingType": "one_time",
      "category": {
        "id": "cat-001",
        "name": "Senales",
        "slug": "signals"
      },
      "isFeatured": true,
      "metadata": {
        "credits": 200,
        "validityDays": 60,
        "minConfidence": 80
      }
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 12,
    "total": 7,
    "totalPages": 1
  }
}
```

### GET /products/:id

Obtiene detalle de un producto.

**Response 200:**
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "name": "Pro Signal Pack",
  "slug": "pro-signal-pack",
  "description": "Paquete de 200 senales ML de alta confianza...",
  "shortDescription": "200 senales ML de alta confianza",
  "type": "signal_pack",
  "price": 29.00,
  "currency": "USD",
  "billingType": "one_time",
  "subscriptionInterval": null,
  "category": {
    "id": "cat-001",
    "name": "Senales",
    "slug": "signals"
  },
  "isFeatured": true,
  "isActive": true,
  "metadata": {
    "credits": 200,
    "validityDays": 60,
    "minConfidence": 80
  },
  "relatedProducts": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Basic Signal Pack",
      "price": 9.00
    }
  ],
  "createdAt": "2026-01-04T00:00:00Z"
}
```

### GET /categories

Lista categorias de productos.

**Response 200:**
```json
{
  "data": [
    {
      "id": "cat-001",
      "name": "Senales",
      "slug": "signals",
      "description": "Paquetes de senales ML premium",
      "icon": "signal",
      "productCount": 3
    }
  ]
}
```

---

## Endpoints de Compras

### POST /purchases

Crea una nueva compra.

**Request Body:**
```json
{
  "productId": "550e8400-e29b-41d4-a716-446655440001",
  "paymentMethodId": "pm_1234567890",
  "quantity": 1,
  "acceptedTerms": true
}
```

**Response 201:**
```json
{
  "id": "purchase-001",
  "status": "completed",
  "product": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "name": "Pro Signal Pack"
  },
  "quantity": 1,
  "unitPrice": 29.00,
  "totalPrice": 29.00,
  "currency": "USD",
  "paymentId": "pi_abc123",
  "completedAt": "2026-01-04T12:00:00Z",
  "receipt": {
    "url": "https://receipts.stripe.com/...",
    "emailSent": true
  },
  "activation": {
    "type": "signal_credits",
    "creditsAdded": 200,
    "newBalance": 215,
    "expiresAt": "2026-03-04T12:00:00Z"
  }
}
```

**Response 402 (Pago Fallido):**
```json
{
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "El pago no pudo ser procesado",
    "details": {
      "declineCode": "insufficient_funds"
    }
  }
}
```

### GET /purchases

Lista compras del usuario autenticado.

**Query Parameters:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| status | string | Filtrar por estado |
| productType | string | Filtrar por tipo de producto |
| from | date | Fecha desde |
| to | date | Fecha hasta |
| page | number | Pagina |
| limit | number | Items por pagina |

**Response 200:**
```json
{
  "data": [
    {
      "id": "purchase-001",
      "product": {
        "id": "prod-001",
        "name": "Pro Signal Pack",
        "type": "signal_pack"
      },
      "totalPrice": 29.00,
      "currency": "USD",
      "status": "completed",
      "completedAt": "2026-01-04T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 5
  }
}
```

### GET /purchases/:id

Obtiene detalle de una compra.

**Response 200:**
```json
{
  "id": "purchase-001",
  "product": {
    "id": "prod-001",
    "name": "Pro Signal Pack",
    "type": "signal_pack",
    "price": 29.00
  },
  "quantity": 1,
  "unitPrice": 29.00,
  "totalPrice": 29.00,
  "currency": "USD",
  "status": "completed",
  "paymentMethod": "visa ****4242",
  "completedAt": "2026-01-04T12:00:00Z",
  "receipt": {
    "url": "https://receipts.stripe.com/..."
  }
}
```

---

## Endpoints de Suscripciones

### POST /subscriptions

Crea una nueva suscripcion.

**Request Body:**
```json
{
  "productId": "550e8400-e29b-41d4-a716-446655440003",
  "paymentMethodId": "pm_1234567890",
  "acceptedTerms": true
}
```

**Response 201:**
```json
{
  "id": "sub-001",
  "status": "active",
  "product": {
    "id": "prod-003",
    "name": "Unlimited Signals"
  },
  "price": 49.00,
  "currency": "USD",
  "interval": "monthly",
  "currentPeriodStart": "2026-01-04T00:00:00Z",
  "currentPeriodEnd": "2026-02-04T00:00:00Z",
  "cancelAtPeriodEnd": false
}
```

### GET /subscriptions

Lista suscripciones del usuario.

**Response 200:**
```json
{
  "data": [
    {
      "id": "sub-001",
      "product": {
        "id": "prod-003",
        "name": "Unlimited Signals",
        "type": "signal_pack"
      },
      "status": "active",
      "price": 49.00,
      "interval": "monthly",
      "currentPeriodEnd": "2026-02-04T00:00:00Z",
      "cancelAtPeriodEnd": false
    }
  ]
}
```

### DELETE /subscriptions/:id

Cancela una suscripcion.

**Request Body:**
```json
{
  "reason": "No longer needed",
  "cancelImmediately": false
}
```

**Response 200:**
```json
{
  "id": "sub-001",
  "status": "active",
  "cancelAtPeriodEnd": true,
  "canceledAt": "2026-01-04T12:00:00Z",
  "accessEndsAt": "2026-02-04T00:00:00Z",
  "message": "Tu suscripcion se cancelara al final del periodo actual"
}
```

---

## Endpoints de Creditos de Senales

### GET /credits

Obtiene creditos de senales del usuario.

**Response 200:**
```json
{
  "totalAvailable": 150,
  "hasUnlimited": false,
  "credits": [
    {
      "id": "credit-001",
      "productName": "Pro Signal Pack",
      "initialAmount": 200,
      "remainingAmount": 150,
      "expiresAt": "2026-03-04T12:00:00Z",
      "isUnlimited": false
    }
  ],
  "usage": {
    "today": 3,
    "thisWeek": 15,
    "thisMonth": 50
  }
}
```

### GET /credits/history

Historial de uso de creditos.

**Response 200:**
```json
{
  "data": [
    {
      "id": "delivery-001",
      "signal": {
        "id": "sig-001",
        "symbol": "BTC/USDT",
        "action": "BUY",
        "confidence": 87.5
      },
      "deliveredAt": "2026-01-04T14:30:00Z",
      "channel": "both"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 50
  }
}
```

---

## Endpoints de Asesoria

### GET /advisors

Lista asesores disponibles.

**Query Parameters:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| specialty | string | Filtrar por especialidad |
| language | string | Filtrar por idioma |
| minRating | number | Rating minimo |
| sort | string | rating, price, experience |
| page | number | Pagina |
| limit | number | Items por pagina |

**Response 200:**
```json
{
  "data": [
    {
      "id": "advisor-001",
      "displayName": "Maria Garcia, CFA",
      "title": "Crypto Trading Expert",
      "shortBio": "10 anos de experiencia en mercados crypto...",
      "specialties": ["crypto", "defi", "technical_analysis"],
      "experienceYears": 10,
      "languages": ["es", "en"],
      "rating": 4.9,
      "reviewCount": 85,
      "completedSessions": 120,
      "priceFrom": 49.00,
      "profileImageUrl": "https://...",
      "nextAvailable": "2026-01-05T09:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 5
  }
}
```

### GET /advisors/:id

Obtiene perfil completo de un asesor.

**Response 200:**
```json
{
  "id": "advisor-001",
  "displayName": "Maria Garcia, CFA",
  "title": "Crypto Trading Expert",
  "bio": "Analista certificada CFA con 10 anos de experiencia...",
  "shortBio": "10 anos de experiencia en mercados crypto...",
  "specialties": ["crypto", "defi", "technical_analysis"],
  "experienceYears": 10,
  "languages": ["es", "en"],
  "rating": 4.9,
  "reviewCount": 85,
  "completedSessions": 120,
  "profileImageUrl": "https://...",
  "isVerified": true,
  "sessionOptions": [
    {
      "duration": 30,
      "price": 49.00,
      "currency": "USD",
      "includes": ["video", "notes"]
    },
    {
      "duration": 60,
      "price": 89.00,
      "currency": "USD",
      "includes": ["video", "notes", "action_plan"]
    },
    {
      "duration": 90,
      "price": 119.00,
      "currency": "USD",
      "includes": ["video", "notes", "action_plan", "follow_up"]
    }
  ],
  "reviews": [
    {
      "id": "review-001",
      "rating": 5,
      "comment": "Excelente sesion, muy profesional",
      "userName": "Juan P.",
      "createdAt": "2026-01-03T00:00:00Z"
    }
  ]
}
```

### GET /advisors/:id/availability

Obtiene disponibilidad de un asesor.

**Query Parameters:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| duration | number | Duracion de sesion en minutos |
| timezone | string | Zona horaria del usuario |
| from | date | Fecha desde |
| to | date | Fecha hasta |

**Response 200:**
```json
{
  "advisorId": "advisor-001",
  "duration": 60,
  "timezone": "America/Mexico_City",
  "slots": [
    {
      "date": "2026-01-06",
      "times": ["09:00", "10:00", "11:00", "14:00", "15:00"]
    },
    {
      "date": "2026-01-07",
      "times": ["09:00", "10:00", "14:00"]
    }
  ]
}
```

### POST /advisory-sessions

Agenda una sesion de asesoria.

**Request Body:**
```json
{
  "advisorId": "advisor-001",
  "productId": "prod-advisory-60",
  "scheduledAt": "2026-01-06T10:00:00-06:00",
  "timezone": "America/Mexico_City",
  "paymentMethodId": "pm_1234567890",
  "notes": "Quiero discutir mi estrategia de DeFi"
}
```

**Response 201:**
```json
{
  "id": "session-001",
  "advisor": {
    "id": "advisor-001",
    "displayName": "Maria Garcia, CFA"
  },
  "duration": 60,
  "scheduledAt": "2026-01-06T16:00:00Z",
  "scheduledAtLocal": "2026-01-06T10:00:00-06:00",
  "timezone": "America/Mexico_City",
  "status": "scheduled",
  "price": 89.00,
  "currency": "USD",
  "calEventId": "cal-event-123",
  "joinUrl": null,
  "confirmationEmailSent": true
}
```

### GET /advisory-sessions

Lista sesiones del usuario.

**Query Parameters:**
| Parametro | Tipo | Descripcion |
|-----------|------|-------------|
| status | string | scheduled, completed, cancelled |
| from | date | Fecha desde |
| to | date | Fecha hasta |

**Response 200:**
```json
{
  "data": [
    {
      "id": "session-001",
      "advisor": {
        "id": "advisor-001",
        "displayName": "Maria Garcia, CFA",
        "profileImageUrl": "https://..."
      },
      "duration": 60,
      "scheduledAt": "2026-01-06T16:00:00Z",
      "status": "scheduled",
      "joinUrl": "https://daily.co/room-xyz",
      "canReschedule": true,
      "canCancel": true
    }
  ]
}
```

### GET /advisory-sessions/:id

Obtiene detalle de una sesion.

**Response 200:**
```json
{
  "id": "session-001",
  "advisor": {
    "id": "advisor-001",
    "displayName": "Maria Garcia, CFA",
    "profileImageUrl": "https://..."
  },
  "duration": 60,
  "scheduledAt": "2026-01-06T16:00:00Z",
  "endedAt": null,
  "status": "scheduled",
  "joinUrl": "https://daily.co/room-xyz",
  "recordingUrl": null,
  "notes": {
    "summary": null,
    "recommendations": [],
    "resources": [],
    "followUpActions": []
  },
  "review": null,
  "canReschedule": true,
  "canCancel": true,
  "cancellationPolicy": {
    "fullRefundBefore": "2026-01-05T16:00:00Z",
    "partialRefundBefore": "2026-01-06T04:00:00Z"
  }
}
```

### PATCH /advisory-sessions/:id

Reagenda una sesion.

**Request Body:**
```json
{
  "scheduledAt": "2026-01-07T14:00:00-06:00",
  "timezone": "America/Mexico_City"
}
```

**Response 200:**
```json
{
  "id": "session-001",
  "scheduledAt": "2026-01-07T20:00:00Z",
  "status": "scheduled",
  "message": "Sesion reagendada exitosamente"
}
```

### DELETE /advisory-sessions/:id

Cancela una sesion.

**Request Body:**
```json
{
  "reason": "Schedule conflict"
}
```

**Response 200:**
```json
{
  "id": "session-001",
  "status": "cancelled",
  "cancelledAt": "2026-01-04T12:00:00Z",
  "refund": {
    "amount": 89.00,
    "percentage": 100,
    "status": "processing"
  }
}
```

### POST /advisory-sessions/:id/notes

Asesor agrega notas a la sesion.

**Request Body:**
```json
{
  "summary": "Discutimos estrategias de DeFi y riesgos...",
  "recommendations": [
    "Diversificar en multiples protocolos",
    "Implementar stop-loss automaticos"
  ],
  "resources": [
    {
      "title": "Guia de DeFi Seguro",
      "url": "https://..."
    }
  ],
  "followUpActions": [
    "Revisar portfolio actual",
    "Configurar alertas de precio"
  ]
}
```

**Response 201:**
```json
{
  "id": "notes-001",
  "sessionId": "session-001",
  "createdAt": "2026-01-06T18:00:00Z",
  "notificationSent": true
}
```

### POST /advisory-sessions/:id/reviews

Usuario deja review de la sesion.

**Request Body:**
```json
{
  "rating": 5,
  "comment": "Excelente sesion, Maria es muy profesional y conocedora",
  "isPublic": true
}
```

**Response 201:**
```json
{
  "id": "review-001",
  "rating": 5,
  "comment": "Excelente sesion...",
  "isPublic": true,
  "createdAt": "2026-01-06T19:00:00Z"
}
```

---

## Endpoints de Visualizacion Premium

### GET /visualization/subscription

Obtiene estado de suscripcion de visualizacion.

**Response 200:**
```json
{
  "isActive": true,
  "subscription": {
    "id": "vis-sub-001",
    "startedAt": "2026-01-01T00:00:00Z",
    "expiresAt": "2026-02-01T00:00:00Z",
    "cancelAtPeriodEnd": false
  },
  "features": [
    "ml_indicators",
    "unlimited_backtest",
    "unlimited_alerts",
    "multi_chart_4"
  ],
  "limits": {
    "alerts": -1,
    "layouts": -1,
    "backtestDays": -1,
    "charts": 4
  }
}
```

### POST /visualization/subscribe

Crea suscripcion de visualizacion premium.

**Request Body:**
```json
{
  "paymentMethodId": "pm_1234567890",
  "acceptedTerms": true
}
```

**Response 201:**
```json
{
  "subscription": {
    "id": "vis-sub-001",
    "status": "active",
    "startedAt": "2026-01-04T00:00:00Z",
    "expiresAt": "2026-02-04T00:00:00Z"
  },
  "features": [
    "ml_indicators",
    "unlimited_backtest",
    "unlimited_alerts",
    "multi_chart_4"
  ],
  "message": "Visualizacion Premium activada"
}
```

### GET /visualization/indicators

Lista indicadores disponibles.

**Response 200:**
```json
{
  "basic": [
    {
      "id": "sma",
      "name": "Simple Moving Average",
      "type": "overlay",
      "available": true
    },
    {
      "id": "rsi",
      "name": "Relative Strength Index",
      "type": "panel",
      "available": true
    }
  ],
  "premium": [
    {
      "id": "ml_range_predictor",
      "name": "Range Predictor",
      "type": "overlay",
      "description": "Predice rangos de precio",
      "available": true,
      "requiresPremium": true
    },
    {
      "id": "ml_amd_detector",
      "name": "AMD Detector",
      "type": "overlay",
      "description": "Detecta patrones AMD",
      "available": true,
      "requiresPremium": true
    }
  ]
}
```

### GET /visualization/layouts

Lista layouts guardados del usuario.

**Response 200:**
```json
{
  "data": [
    {
      "id": "layout-001",
      "name": "Mi Layout Principal",
      "isDefault": true,
      "chartCount": 4,
      "createdAt": "2026-01-03T00:00:00Z"
    }
  ],
  "limits": {
    "max": -1,
    "used": 3
  }
}
```

### POST /visualization/layouts

Guarda un nuevo layout.

**Request Body:**
```json
{
  "name": "Crypto Watch",
  "layoutConfig": {
    "grid": "2x2",
    "charts": [
      {"position": 0, "symbol": "BTC/USDT", "timeframe": "4H"},
      {"position": 1, "symbol": "ETH/USDT", "timeframe": "4H"},
      {"position": 2, "symbol": "SOL/USDT", "timeframe": "4H"},
      {"position": 3, "symbol": "AVAX/USDT", "timeframe": "4H"}
    ]
  },
  "indicators": [
    {"chartIndex": 0, "indicators": ["ml_range_predictor", "sma"]},
    {"chartIndex": 1, "indicators": ["ml_amd_detector"]}
  ],
  "isDefault": false
}
```

**Response 201:**
```json
{
  "id": "layout-002",
  "name": "Crypto Watch",
  "isDefault": false,
  "createdAt": "2026-01-04T12:00:00Z"
}
```

### POST /visualization/alerts

Crea una alerta de indicador.

**Request Body:**
```json
{
  "indicatorId": "ml_amd_detector",
  "symbol": "BTC/USDT",
  "conditions": [
    {
      "field": "phase",
      "operator": "equals",
      "value": "distribution"
    }
  ],
  "notificationChannels": ["push", "email"],
  "triggerOnce": false
}
```

**Response 201:**
```json
{
  "id": "alert-001",
  "indicatorId": "ml_amd_detector",
  "symbol": "BTC/USDT",
  "isActive": true,
  "createdAt": "2026-01-04T12:00:00Z"
}
```

### POST /visualization/backtest

Ejecuta un backtest.

**Request Body:**
```json
{
  "symbol": "BTC/USDT",
  "strategyConfig": {
    "indicators": ["ml_amd_detector", "ml_signal_overlay"],
    "entryConditions": [...],
    "exitConditions": [...]
  },
  "periodStart": "2025-10-01",
  "periodEnd": "2026-01-01",
  "initialCapital": 10000
}
```

**Response 200:**
```json
{
  "id": "backtest-001",
  "symbol": "BTC/USDT",
  "periodStart": "2025-10-01",
  "periodEnd": "2026-01-01",
  "initialCapital": 10000.00,
  "finalCapital": 12450.00,
  "totalReturn": 0.245,
  "totalTrades": 45,
  "winningTrades": 30,
  "losingTrades": 15,
  "winRate": 66.67,
  "profitFactor": 2.3,
  "maxDrawdown": -8.5,
  "sharpeRatio": 1.82,
  "trades": [
    {
      "entryDate": "2025-10-05T14:00:00Z",
      "exitDate": "2025-10-06T10:00:00Z",
      "entryPrice": 42150.00,
      "exitPrice": 43200.00,
      "side": "long",
      "pnl": 250.00,
      "pnlPercent": 2.49
    }
  ]
}
```

---

## Webhooks

### POST /webhooks/stripe

Procesa eventos de Stripe.

**Headers:**
```http
Stripe-Signature: t=1234567890,v1=signature...
```

**Eventos Soportados:**
- `payment_intent.succeeded`
- `payment_intent.payment_failed`
- `customer.subscription.created`
- `customer.subscription.updated`
- `customer.subscription.deleted`
- `invoice.paid`
- `invoice.payment_failed`

### POST /webhooks/cal

Procesa eventos de Cal.com.

**Eventos Soportados:**
- `BOOKING_CREATED`
- `BOOKING_CANCELLED`
- `BOOKING_RESCHEDULED`
- `MEETING_ENDED`

**Payload Ejemplo:**
```json
{
  "triggerEvent": "BOOKING_CREATED",
  "payload": {
    "bookingId": 12345,
    "uid": "booking-uid-123",
    "startTime": "2026-01-06T16:00:00Z",
    "endTime": "2026-01-06T17:00:00Z",
    "attendees": [
      {
        "email": "user@example.com",
        "name": "Juan Perez"
      }
    ],
    "metadata": {
      "sessionId": "session-001"
    }
  }
}
```

### POST /webhooks/daily

Procesa eventos de Daily.co.

**Eventos Soportados:**
- `meeting.started`
- `meeting.ended`
- `recording.ready`

---

## Codigos de Error

| Codigo | HTTP Status | Descripcion |
|--------|-------------|-------------|
| PRODUCT_NOT_FOUND | 404 | Producto no encontrado |
| PRODUCT_UNAVAILABLE | 400 | Producto no disponible |
| INSUFFICIENT_CREDITS | 400 | Creditos insuficientes |
| PAYMENT_FAILED | 402 | Pago fallido |
| SUBSCRIPTION_EXISTS | 409 | Ya existe suscripcion activa |
| ADVISOR_NOT_AVAILABLE | 400 | Asesor no disponible |
| SLOT_NOT_AVAILABLE | 409 | Horario no disponible |
| SESSION_NOT_CANCELLABLE | 400 | Sesion no puede cancelarse |
| PREMIUM_REQUIRED | 403 | Requiere suscripcion premium |
| LIMIT_EXCEEDED | 400 | Limite excedido |

**Formato de Error:**
```json
{
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "El pago no pudo ser procesado",
    "details": {
      "declineCode": "insufficient_funds"
    },
    "timestamp": "2026-01-04T12:00:00Z",
    "requestId": "req-abc123"
  }
}
```

---

## Rate Limiting

| Endpoint | Limite | Ventana |
|----------|--------|---------|
| GET /products | 100 | 1 minuto |
| POST /purchases | 10 | 1 minuto |
| POST /subscriptions | 5 | 1 minuto |
| POST /advisory-sessions | 10 | 1 hora |
| POST /visualization/backtest | 20 | 1 hora |

**Headers de Rate Limit:**
```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704369600
```

---

## Referencias

- [ET-MKT-001: Database](./ET-MKT-001-database.md)
- [RF-MKT-001: Catalogo](../requerimientos/RF-MKT-001-catalogo.md)
- [RF-MKT-002: Senales Premium](../requerimientos/RF-MKT-002-senales-premium.md)
- [RF-MKT-003: Asesoria](../requerimientos/RF-MKT-003-asesoria.md)
- [RF-MKT-004: Visualizacion](../requerimientos/RF-MKT-004-visualizacion.md)
