Skip to content

Latest commit

 

History

History
578 lines (456 loc) · 16.1 KB

File metadata and controls

578 lines (456 loc) · 16.1 KB

📚 Documentación de la API

🎯 Documentación Interactiva (Recomendado)

La forma más fácil y rápida de explorar la API es usando Swagger UI:

🌐 URL: http://localhost:4300/api-docs

Swagger proporciona:

  • ✅ Documentación interactiva completa
  • ✅ Prueba de endpoints en tiempo real
  • ✅ Esquemas de datos con ejemplos
  • ✅ Autenticación integrada
  • ✅ Respuestas en vivo

📖 Ver guía completa de Swagger


📋 Resumen de la API

Características Principales

  • Generación de enlaces cortos con códigos personalizados o aleatorios
  • Reserva de enlaces sin URL (para QR codes impresos)
  • Gestión de estados (ACTIVO, RESERVADO, DESHABILITADO, EXPIRADO)
  • Redirección pública optimizada sin autenticación
  • Métricas de uso (clics, última visita)
  • Auditoría completa de cambios
  • Autenticación segura (API Key + Bearer Token)
  • Organización flexible por proyectos, módulos y etiquetas

🔐 Autenticación

Todos los endpoints de gestión requieren autenticación:

Opción 1: API Key (Header)

X-API-Key: dev-key-123

Opción 2: Bearer Token (Header)

Authorization: Bearer dev-token-123

Configuración: Las claves se definen en el archivo .env:

API_KEYS=dev-key-123,prod-key-456
BEARER_TOKENS=dev-token-123,prod-token-456

🚀 Endpoints Principales

Base URL

http://localhost:4300

1️⃣ Gestión de Enlaces (Requiere Autenticación)

Método Endpoint Descripción
POST /v1/short-links Crear enlace corto
GET /v1/short-links Listar enlaces con filtros
GET /v1/short-links/{id} Obtener enlace por ID
PATCH /v1/short-links/{id} Actualizar enlace

2️⃣ Redirección Pública (Sin Autenticación)

Método Endpoint Descripción
GET /r/{codigo} Redirigir a URL destino

3️⃣ Utilidades

Método Endpoint Descripción
GET / Info del servicio
GET /health Health check
GET /api-docs Documentación Swagger

💡 Ejemplos Rápidos

Crear Enlace Estándar

curl -X POST http://localhost:4300/v1/short-links \
  -H "X-API-Key: dev-key-123" \
  -H "Content-Type: application/json" \
  -d '{
    "proyecto": "Marketing",
    "creado_por": "admin",
    "url_destino": "https://example.com/promo"
  }'

Respuesta (201):

{
  "code": 201,
  "message": "Enlace corto creado exitosamente",
  "data": {
    "id": 1,
    "codigo": "a1b2c3",
    "url_corta": "http://localhost:4300/r/a1b2c3",
    "url_destino": "https://example.com/promo",
    "estado": "ACTIVO",
    "proyecto": "Marketing",
    "total_clicks": 0,
    "fecha_creacion": "2025-11-27T12:00:00Z"
  }
}

Reservar Enlace para QR

curl -X POST http://localhost:4300/v1/short-links \
  -H "X-API-Key: dev-key-123" \
  -H "Content-Type: application/json" \
  -d '{
    "proyecto": "Eventos",
    "creado_por": "admin"
  }'

Nota: Sin url_destino, el enlace queda en estado RESERVADO_SIN_DESTINO.

Listar Enlaces con Filtros

curl -X GET "http://localhost:4300/v1/short-links?proyecto=Marketing&estado=ACTIVO" \
  -H "X-API-Key: dev-key-123"

Actualizar Enlace Reservado

curl -X PATCH http://localhost:4300/v1/short-links/1 \
  -H "X-API-Key: dev-key-123" \
  -H "Content-Type: application/json" \
  -d '{
    "url_destino": "https://example.com/evento-2025",
    "estado": "ACTIVO",
    "actualizado_por": "admin"
  }'

Redirección Pública (Browser/QR)

http://localhost:4300/r/a1b2c3

Comportamiento:

  • ACTIVO → HTTP 302 a URL destino + incrementa contador
  • RESERVADO → Muestra página genérica
  • DESHABILITADO/EXPIRADO → HTTP 410 (Gone)

📊 Estados de Enlaces

Estado Código Comportamiento
RESERVADO_SIN_DESTINO 🟡 Muestra página reservada
ACTIVO 🟢 Redirige a URL destino
DESHABILITADO 🔴 Error 410 (Gone)
EXPIRADO Error 410 (Gone)

🔍 Filtros Disponibles (GET /v1/short-links)

Parámetro Tipo Descripción Ejemplo
proyecto string Filtrar por proyecto ?proyecto=Marketing
estado enum Filtrar por estado ?estado=ACTIVO
modulo string Filtrar por módulo ?modulo=Campañas
etiquetas string Filtrar por etiquetas (CSV) ?etiquetas=promo,2025
fecha_creacion_desde date Desde fecha (YYYY-MM-DD) ?fecha_creacion_desde=2025-01-01
fecha_creacion_hasta date Hasta fecha (YYYY-MM-DD) ?fecha_creacion_hasta=2025-12-31

📦 Estructura de Datos

ShortLink (Respuesta)

{
  id: number;                        // ID auto-increment
  codigo: string;                    // Código único (6-8 caracteres)
  url_corta: string;                 // URL completa del enlace corto
  url_destino: string | null;        // URL destino (null si reservado)
  estado: ShortLinkStatus;           // Estado actual
  proyecto: string;                  // Proyecto origen (requerido)
  modulo?: string;                   // Módulo (opcional)
  etiquetas?: string[];              // Tags de categorización
  fecha_creacion: Date;              // Timestamp de creación
  fecha_ultima_actualizacion: Date;  // Timestamp última modificación
  creado_por: string;                // Usuario creador
  actualizado_por: string;           // Usuario última actualización
  historial_cambios: AuditEntry[];   // Auditoría completa
  total_clicks: number;              // Contador de visitas
  fecha_ultimo_click: Date | null;   // Última visita registrada
}

CreateShortLinkDTO (Request POST)

{
  proyecto: string;           // ✅ Requerido
  creado_por: string;         // ✅ Requerido
  codigo?: string;            // Opcional (se genera si no se proporciona)
  url_destino?: string;       // Opcional (null = reservado)
  modulo?: string;            // Opcional
  etiquetas?: string[];       // Opcional
}

UpdateShortLinkDTO (Request PATCH)

{
  actualizado_por: string;    // ✅ Requerido
  url_destino?: string;       // Opcional
  estado?: ShortLinkStatus;   // Opcional
  modulo?: string;            // Opcional
  etiquetas?: string[];       // Opcional
}

⚡ Rate Limiting

Tipo Límite Endpoints
Lectura 300 req/min GET /v1/short-links, GET /v1/short-links/{id}
Escritura 100 req/min POST /v1/short-links
Actualización 30 req/min PATCH /v1/short-links/{id}
Redirección Sin límite GET /r/{codigo}

🛠️ Códigos de Respuesta HTTP

Código Significado Cuándo ocurre
200 OK Operación exitosa (GET, PATCH)
201 Created Enlace creado exitosamente
302 Found Redirección exitosa
400 Bad Request Error de validación
401 Unauthorized Falta autenticación
403 Forbidden Autenticación inválida
404 Not Found Recurso no encontrado
409 Conflict Código duplicado
410 Gone Enlace deshabilitado/expirado
500 Internal Error Error del servidor

📚 Más Información


💡 Tip: Para explorar la API de forma interactiva, usa Swagger UI en lugar de leer esta documentación completa. Es más rápido y te permite probar los endpoints directamente.

🌐 Accede ahora: http://localhost:4300/api-docs


#### Campos
| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| proyecto | string | ✅ Sí | Proyecto origen del enlace |
| creado_por | string | ✅ Sí | Usuario/sistema que crea el enlace |
| codigo | string | ❌ No | Código personalizado (si no se proporciona, se genera automáticamente) |
| url_destino | string | ❌ No | URL de destino (si no se proporciona, queda como RESERVADO) |
| modulo | string | ❌ No | Módulo del proyecto |
| etiquetas | string[] | ❌ No | Etiquetas de campaña/canal |

#### Response (201)
```json
{
  "code": 201,
  "message": "Enlace corto creado exitosamente",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "codigo": "promo2025",
    "url_corta": "https://lnk.simpledatacorp.com/promo2025",
    "url_destino": "https://www.ejemplo.com/promocion",
    "estado": "ACTIVO",
    "proyecto": "marketing-2025",
    "modulo": "campanas",
    "etiquetas": ["promocion", "verano", "descuento"],
    "fecha_creacion": "2025-01-15T10:00:00.000Z",
    "fecha_ultima_actualizacion": "2025-01-15T10:00:00.000Z",
    "total_clicks": 0,
    "fecha_ultimo_click": null
  }
}

2. Obtener Enlace por ID

GET /v1/short-links/:id

Obtiene los detalles de un enlace específico.

Response (200)

{
  "code": 200,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "codigo": "promo2025",
    "url_corta": "https://lnk.simpledatacorp.com/promo2025",
    "url_destino": "https://www.ejemplo.com/promocion",
    "estado": "ACTIVO",
    "proyecto": "marketing-2025",
    "total_clicks": 150,
    "fecha_ultimo_click": "2025-01-20T15:30:00.000Z"
  }
}

3. Listar y Filtrar Enlaces

GET /v1/short-links

Lista y filtra enlaces según diversos criterios.

Query Parameters

Parámetro Tipo Descripción
proyecto string Filtrar por proyecto
estado string Filtrar por estado (ACTIVO, RESERVADO_SIN_DESTINO, etc.)
modulo string Filtrar por módulo
fecha_creacion_desde date Fecha mínima de creación
fecha_creacion_hasta date Fecha máxima de creación
etiquetas string Etiquetas separadas por comas

Ejemplo

GET /v1/short-links?proyecto=marketing-2025&estado=ACTIVO&etiquetas=promocion,verano

Response (200)

{
  "code": 200,
  "total": 2,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "codigo": "promo2025",
      "url_corta": "https://lnk.simpledatacorp.com/promo2025",
      "url_destino": "https://www.ejemplo.com/promocion",
      "estado": "ACTIVO",
      "total_clicks": 150
    },
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "codigo": "verano25",
      "url_corta": "https://lnk.simpledatacorp.com/verano25",
      "url_destino": "https://www.ejemplo.com/verano",
      "estado": "ACTIVO",
      "total_clicks": 89
    }
  ]
}

4. Actualizar Enlace

PATCH /v1/short-links/:id

Actualiza un enlace existente (URL destino, estado, etiquetas).

Request Body

{
  "actualizado_por": "usuario@empresa.com",
  "url_destino": "https://www.ejemplo.com/nueva-promocion",
  "estado": "ACTIVO",
  "etiquetas": ["promocion", "invierno", "nuevo"]
}

Campos

Campo Tipo Requerido Descripción
actualizado_por string ✅ Sí Usuario que actualiza
url_destino string ❌ No Nueva URL de destino
estado string ❌ No Nuevo estado
modulo string ❌ No Actualizar módulo
etiquetas string[] ❌ No Actualizar etiquetas

Response (200)

{
  "code": 200,
  "message": "Enlace actualizado exitosamente",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "codigo": "promo2025",
    "url_corta": "https://lnk.simpledatacorp.com/promo2025",
    "url_destino": "https://www.ejemplo.com/nueva-promocion",
    "estado": "ACTIVO",
    "fecha_ultima_actualizacion": "2025-01-20T16:00:00.000Z"
  }
}

5. Redirección Pública

GET /r/:codigo

Endpoint público de redirección (NO requiere autenticación).

Comportamiento según Estado

Estado Comportamiento
ACTIVO Redirige a url_destino con HTTP 302
RESERVADO_SIN_DESTINO Redirige a página genérica configurada
DESHABILITADO Muestra página de "Enlace deshabilitado"
EXPIRADO Muestra página de "Enlace expirado"

Ejemplo

GET /r/promo2025
→ Redirige a: https://www.ejemplo.com/promocion

Nota: Este endpoint registra automáticamente:

  • Incremento del contador de clics
  • Fecha/hora del último acceso

🔐 Estados de Enlaces

Estado Descripción
RESERVADO_SIN_DESTINO Enlace reservado sin URL de destino (para QR impresos)
ACTIVO Enlace activo que redirige a su URL de destino
DESHABILITADO Enlace deshabilitado, no redirige
EXPIRADO Enlace que ha expirado, no redirige

📊 Casos de Uso

Caso 1: Crear enlace estándar

curl -X POST http://localhost:4100/v1/short-links \
  -H "X-API-Key: tu-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "proyecto": "marketing-2025",
    "creado_por": "admin@empresa.com",
    "url_destino": "https://www.ejemplo.com/landing"
  }'

Caso 2: Reservar enlace para QR

curl -X POST http://localhost:4100/v1/short-links \
  -H "X-API-Key: tu-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "proyecto": "folletos-2025",
    "creado_por": "admin@empresa.com",
    "codigo": "folleto123"
  }'

Caso 3: Actualizar enlace reservado

curl -X PATCH http://localhost:4100/v1/short-links/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-API-Key: tu-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "actualizado_por": "admin@empresa.com",
    "url_destino": "https://www.ejemplo.com/promocion-activa",
    "estado": "ACTIVO"
  }'

Caso 4: Deshabilitar enlace

curl -X PATCH http://localhost:4100/v1/short-links/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-API-Key: tu-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "actualizado_por": "admin@empresa.com",
    "estado": "DESHABILITADO"
  }'

🛡️ Seguridad

  • Todos los endpoints administrativos requieren autenticación
  • El endpoint de redirección es público para permitir acceso directo
  • Las API Keys y tokens se configuran en variables de entorno
  • Historial completo de auditoría de cambios

⚙️ Configuración de Producción

Para producción, actualiza estas variables:

SHORT_DOMAIN=https://lnk.simpledatacorp.com
RESERVED_LINK_URL=https://lnk.simpledatacorp.com/reserved
API_KEYS=key-produccion-segura-1,key-produccion-segura-2
BEARER_TOKENS=token-produccion-seguro-1
NODE_ENV=production

📝 Notas Técnicas

  • Almacenamiento: Actualmente en memoria (implementar base de datos para producción)
  • Códigos cortos: Alfanuméricos, 4-20 caracteres
  • Generación automática: 6 caracteres por defecto
  • Redirección: HTTP 302 (temporal) para enlaces activos
  • Performance: Endpoint de redirección optimizado para baja latencia

🧪 Testing

Ejecutar tests:

npm test

📧 Soporte

Para soporte técnico o consultas, contactar a: dey.gordillo@simpledatacorp.com


📄 Licencia

UNLICENSED - Uso corporativo interno