Grafo Salir
⚙️ service draft high 👤 ❓ Pendiente de asignar 📅 Tue Feb 17 2026 21:00:00 GMT-0300 (Chile Summer Time)
Framework
Express.js 4.19.2
Runtime
Node.js 20
Deploy
kubernetes
Entorno
prod

SVC-turn-o-matic-queue-reservations

Descripción General

API REST de solo lectura consumida exclusivamente por SVC-web-module. Devuelve las reservas activas del día que están disponibles para ser llamadas desde un módulo de atención. SVC-web-module invoca este servicio periódicamente (polling) para obtener la lista actualizada.

Propósito

  • Problema que resuelve: SVC-web-module necesita obtener periódicamente las reservas del día que están disponibles para llamar en un módulo de atención específico, filtradas por las líneas asignadas a ese módulo y excluyendo las ya llamadas, canceladas, saltadas o derivadas.
  • Usuarios/consumidores principales: SVC-web-module (único consumidor).
  • Alternativa si no existiera: SVC-web-module tendría que consultar directamente INFRA-MongoDB y INFRA-Redis para armar la lista de reservas disponibles.

Resumen de Arquitectura

graph LR
    WEB[SVC-web-module] -->|GET polling| QR

    subgraph QR [SVC-queue-reservations - Express :3000]
        API[REST API<br/>solo lectura]
    end

    subgraph Infraestructura
        REDIS[(INFRA-Redis<br/>Cache reservas · Estado · Permisos)]
        MONGO[(INFRA-MongoDB<br/>Reservas del día)]
        PG[(INFRA-PostgreSQL<br/>Oficinas · Líneas · Permisos)]
    end

    QR -->|lectura + cache TTL 5s| REDIS
    QR -->|fallback si no hay cache| MONGO
    QR -->|lectura + cache TTL 180s| PG
  • Tipo: service
  • Lenguaje/Framework: TypeScript / Express.js 4.19.2
  • Runtime: Node.js 20 (Alpine)
  • Destino de despliegue: Kubernetes (Helm — zeroqchart v1.4.1)
  • Puerto: 3000 (configurable vía EXPRESS_PORT)
  • Protocolo: REST (solo lectura — 3 endpoints GET)
  • Réplicas en prod: ❓ Pendiente de verificar (definido en chart externo zeroqchart)

Dependencias

Upstream (servicios que llaman a este)

ServicioMétodoEndpoint
SVC-web-moduleGET (polling)/offices/:office_id/modulos/:modulo_id/reservations
SVC-web-moduleGET (polling)/offices/:office_id/modulos/:modulo_id/reservations/skipped
SVC-web-moduleGET (polling)/offices/:office_id/modulos/:modulo_id/reservations/derivated

Downstream (servicios que este llama)

ServicioMétodoPropósito
Ninguno detectadoEste servicio no realiza llamadas HTTP a otros servicios

Infraestructura

ComponenteUsoCrítico
INFRA-MongoDBLectura de reservas del día (colección reserves) — fallback cuando no hay datos en Redis
INFRA-PostgreSQLLectura de líneas asignadas a módulos y permisos de usuario por oficina
INFRA-RedisCache de reservas por oficina (TTL 5s), cache de datos PG (TTL 180s), lectura de estado de reservas canceladas/saltadas/derivadas/llamadas

Flujo de Datos

Descripción del flujo principal (GET /offices/:office_id/modulos/:modulo_id/reservations):

  1. SVC-web-module hace polling con token JWT al endpoint del módulo/oficina
  2. Se valida el token JWT y se verifican permisos del usuario sobre la oficina consultando INFRA-PostgreSQL (cacheado en INFRA-Redis con TTL 180s)
  3. Se obtienen las líneas asignadas al módulo desde INFRA-PostgreSQL (cacheado en INFRA-Redis con TTL 180s)
  4. Se buscan las reservas del día: primero en INFRA-Redis (key turn-o-matic.state.offices.{id}.reservations.queue, TTL 5s); si no hay cache, se consulta INFRA-MongoDB (colección reserves, rango del día en timezone de la oficina) y se cachea el resultado
  5. Por cada reserva de MongoDB, se sincroniza al cache de Redis en keys de estado (entity, queued, cancelled)
  6. Se filtran las reservas excluyendo las ya llamadas, canceladas, saltadas y derivadas (consultando sets y hashes en INFRA-Redis); se retornan solo las de hoy
  7. Se ordenan cronológicamente por hora de inicio y se devuelven las primeras 20

Datos sensibles manejados

Este servicio no persiste datos — solo lee y retorna información existente. Los datos PII presentes en las reservas consultadas incluyen:

DatoClasificaciónOrigenRetención
email (usuario)PIILeído de MongoDB/RedisNo almacena — solo transita
phone (usuario)PIILeído de MongoDB/RedisNo almacena — solo transita
rut (usuario)PIILeído de MongoDB/RedisNo almacena — solo transita
JWT tokenInternoHeader de requestSesión

Modos de Falla

EscenarioImpactoMitigaciónSeveridad
INFRA-MongoDB no disponibleNo se pueden consultar reservas (si Redis cache expiró)Cache en Redis (TTL 5s) mitiga brevementeAlta
INFRA-PostgreSQL no disponibleNo se pueden validar oficinas/líneasCache en Redis (TTL 180s)Alta
INFRA-Redis no disponibleSin cache, sin estado de reservasRetry strategy con backoff exponencial (max 2s, 3 reintentos)Crítica
JWT secret inválidoTodas las peticiones rechazadasNinguna detectadaCrítica

Política de Reintentos / Circuit Breaker

  • Intentos de reintento: Redis: 3 reintentos con backoff exponencial (max delay 2000ms), max 10 reconexiones
  • Estrategia de backoff: Exponencial para Redis (retryStrategy en ioredis)
  • Umbral de circuit breaker: No implementado
  • Comportamiento de fallback: No implementado

Monitoreo

Health Check

  • Endpoint: GET /online{ready: true}
  • Intervalo: ❓ Pendiente de verificar (configurado en chart externo)
  • Timeout: ❓ Pendiente de verificar (configurado en chart externo)

Métricas clave

MétricaUmbral de alertaDashboard
Latencia de request p99
Tasa de errores
Uso de CPU
Uso de memoria

Logs

  • Formato: JSON estructurado (Winston)
  • Nivel por defecto: info (producción), debug (desarrollo)
  • Destino: Console (stdout) + archivos (./logs/app.log, ./logs/error.log)
  • Retención: ❓ Pendiente de verificar
  • HTTP request logging: Morgan (formato combined), excluye /online, /metrics, /version
  • Debug dinámico: POST /logger/debug/:active permite activar/desactivar debug en runtime

Consideraciones de Seguridad

  • Autenticación requerida (JWT vía header Authorization)
  • Autorización por roles — validación de permisos por oficina (validaOfficePermissions)
  • Rate limiting configurado
  • Validación de entrada implementada (Celebrate/Joi + middleware anti-inyección SQL/XSS)
  • Datos sensibles encriptados en reposo
  • Datos sensibles encriptados en tránsito (TLS en ingress)
  • Logging de auditoría habilitado (solo HTTP request logs, sin audit trail estructurado)
  • No expone datos internos en errores (stack traces solo en entornos no-productivos)

Estrategia de Escalamiento

  • Tipo: Horizontal (inferido)
  • Auto-scaling: ❓ Pendiente de verificar (no visible en codebase, posiblemente en chart externo)
  • Réplicas mínimas: ❓ Pendiente de verificar
  • Réplicas máximas: ❓ Pendiente de verificar
  • Trigger de escalamiento: ❓ Pendiente de verificar
  • Limitaciones conocidas: No se detectaron resource limits/requests en los values de Helm; graceful shutdown no implementado (sin handlers para SIGTERM/SIGINT)

Consideraciones de DRP

  • RTO: ❓ (Objetivo de Tiempo de Recuperación)
  • RPO: ❓ (Objetivo de Punto de Recuperación)
  • Estrategia de respaldo: ❓ Pendiente de verificar
  • Failover automático: ❓ Pendiente de verificar
  • Runbook: PROC-DRP-turn-o-matic-queue-reservations

Servicios Relacionados

Dataview LIST
LIST
FROM "01-Architecture/Services"
WHERE contains(related_services, this.file.link)

Esta query se ejecuta dinámicamente en Obsidian.

Preguntas Abiertas

  • Owner del servicio: Pendiente de asignar
  • Réplicas en producción: Definido en chart externo zeroqchart, no visible en el repositorio
  • Auto-scaling (HPA): No visible en el repositorio, posiblemente configurado en el chart externo
  • Resource limits/requests: No definidos en los values de Helm del repositorio
  • Retención de logs: No configurada explícitamente
  • docs-config.json desactualizado: El archivo OpenAPI (src/entrypoints/http/docs-config.json) contiene endpoints de otro servicio (creación de reservas, templates, excepciones, bloques) que no existen en este codebase — debería eliminarse o actualizarse
  • Log engañoso en index.ts: Línea 17 registra connected to RabbitMQ pero no existe conexión a RabbitMQ en el servicio
  • Métricas y tracing: Endpoint /metrics referenciado pero no implementado — sin instrumentación de Prometheus, OpenTelemetry ni APM
  • Graceful shutdown: No implementado — sin handlers para SIGTERM/SIGINT, riesgo de pérdida de requests en vuelo durante redeploys
  • Circuit breaker: No implementado para ninguna dependencia
  • Rate limiting: No configurado, la API está expuesta sin throttling
  • RTO/RPO: Sin definir
  • Estrategia de respaldo y failover: Sin definir
  • Compliance: Sin features de GDPR u otra regulación de protección de datos