Arquitectura Objetivo

Lenguaje: Go (principal)

Por qué Go

Go es la elección principal para la plataforma por:

  • Rendimiento nativo: compilación a binario, sin runtime pesado. Latencia predecible.
  • Concurrencia nativa: goroutines y channels para manejo de miles de conexiones simultáneas (WebSocket, ARI events, webhooks).
  • Ecosistema de red: stdlib completa para HTTP, gRPC, WebSocket. Sin frameworks pesados.
  • Simplicidad: lenguaje deliberadamente simple. Facilita onboard de desarrolladores y reduce defectos.
  • Deployment: un solo binario estático. Sin dependencias de runtime. Ideal para containers y orquestación.
  • Herramientas: go fmt, go vet, race detector, profiling integrado.
  • Madurez: amplio uso en infraestructura de producción (Kubernetes, Docker, Terraform, Cloudflare).

Cuándo usar Python

Python se utiliza únicamente cuando existe una ventaja concreta y demostrable:

  • Bibliotecas maduras sin equivalente en Go: procesamiento de audio/speech-to-text, ML pipelines, herramientas científicas.
  • Procesamiento especializado: análisis de NLP, modelos de clasificación, herramientas de datos.
  • Tooling: scripts de migración, generadores, herramientas internas.
  • No para prototipado más rápido: esta justificación es inválida. Go es igual de productivo para prototipos y el resultado es producción-ready desde el inicio.

Regla: si Python se usa, es como servicio externo o worker aislado, nunca integrado en el binario principal.


Principios de Arquitectura

Clean Code, Clean Architecture

La arquitectura sigue los principios de Robert C. Martin:

  • Independencia de frameworks: la lógica de negocio no depende de frameworks externos.
  • Testabilidad: la lógica de negocio se puede testear sin UI, base de datos, o servicios externos.
  • Independencia de UI: la UI (API REST, CLI, web) es un plugin que adapta la lógica de negocio.
  • Independencia de infraestructura: la base de datos, mensajería, y servicios externos son plugins intercambiables.

Hexagonal (Puertos y Adaptadores)

                    ┌──────────────────────────┐
                    │     Lógica de Negocio     │
                    │                          │
         ┌─────────┤   Puertos de Entrada      │
         │         │   (Use Cases)             │
         │         │                          │
         │         │   Puertos de Salida       │
         │         │   (Interfaces)            │
         │         └──────────┬───────────────┘
         │                    │
    ┌────┴────┐          ┌────┴────┐
    │ Adapt.  │          │ Adapt.  │
    │ Entrada │          │ Salida  │
    ├─────────┤          ├─────────┤
    │ REST API│          │PostgreSQL│
    │ gRPC    │          │Redis    │
    │ WebSocket│         │ARI Client│
    │ CLI     │          │S3       │
    └─────────┘          └─────────┘

Los puertos definen interfaces. Los adaptadores implementan interfaces concretas.

Pensamiento library-first

Cada componente se diseña como si pudiera ser una biblioteca:

  • API pública clara y documentada.
  • Dependencias mínimas.
  • Reutilización entre bounded contexts.
  • Testing independiente.

Lógica event-first

Los eventos de dominio son el centro de la arquitectura:

  • Los eventos se producen después de cada acción significativa.
  • Las proyecciones se derivan de eventos.
  • Los procesos asíncronos reaccionan a eventos.
  • El estado se reconstruye desde eventos.

Contratos explícitos

  • Interfaces Go para contratos internos.
  • Protocol Buffers para contratos gRPC.
  • OpenAPI para contratos REST.
  • Versionado explícito de contratos.

Límites de dominio claros

  • Cada bounded context tiene su propio paquete.
  • La comunicación entre contextos es vía eventos o interfaces explícitas.
  • No hay dependencias directas entre bounded contexts en la misma capa.

Observabilidad desde el diseño

  • Tracing: OpenTelemetry integrado desde el inicio.
  • Logging: estructurado (JSON), con correlation IDs.
  • Metrics: Prometheus, contadores y histogramas por operación.
  • Health checks: endpoints de salud y readiness.

APIs internas tipadas

  • Interfaces Go para contratos internos.
  • Type-safe en compile time.
  • Sin interface{} o any en contratos de negocio.

gRPC para límites de procesamiento reales

Cuando dos componentes corren en procesos separados:

  • gRPC como protocolo de comunicación (no REST para inter-service).
  • Protocol Buffers para serialización (eficiente y tipada).
  • HTTP/2 como transporte (multiplexing, compresión).
  • Streaming para eventos en tiempo real entre servicios.

Monolito Modular Primero

Filosofía

Empezar como monolito modular y solo separar cuando exista una razón técnica u operativa concreta:

  1. Identificar bounded contexts en el dominio.
  2. Implementar como paquetes Go separados dentro de un solo binario.
  3. Interfaces claras entre paquetes.
  4. Separar en servicios solo cuando:
    • Requieren escalado independiente (ej: telefónica con Asterisk).
    • Tienen requisitos de deployment diferentes (ej: workers asíncronos).
    • Necesitan aislamiento de fallas fuerte.
    • La latencia inter-service es aceptable.

Objetivo: <10 servicios principales

No crear microservicios por crear. Un monolito modular bien diseñado supera a una arquitectura de microservicios mal diseñada.


Bounded Contexts Propuestos

1. Core Application

Responsabilidades:

  • Identidad y autenticación (OAuth2, SAML, 2FA).
  • Gestión de tenants (multi-tenancy).
  • Usuarios y roles (RBAC).
  • Configuración del sistema.
  • Permisos y políticas de acceso.

Dominio: quién puede hacer qué.

2. Messaging Gateway

Responsabilidades:

  • Adapters para cada canal de comunicación.
  • Routing de mensajes entrantes al contexto correcto.
  • Enrutamiento de mensajes salientes al canal correcto.
  • Normalización de mensajes entre canales.
  • Gestión de templates por canal.

Dominio: comunicación con el exterior.

3. Conversation Management

Responsabilidades:

  • Inbox de conversaciones.
  • Asignación de conversaciones a agentes.
  • Ciclo de vida de conversaciones (apertura, asignación, cierre, transferencia).
  • Reglas de auto-asignación.
  • SLA y escalamiento.
  • Estado de conversaciones en tiempo real.

Dominio: gestión de la interacción cliente-agente.

4. Contact & CRM

Responsabilidades:

  • Gestión de contactos (personas).
  • Gestión de empresas (organizaciones).
  • Atributos personalizados (schema flexible con JSONB).
  • Historial de interacciones por contacto.
  • Deduplicación y merge de contactos.
  • Búsqueda y segmentación.

Dominio: conocimiento del cliente.

5. Campaign Engine

Responsabilidades:

  • Gestión de campañas outbound.
  • Pacing (velocidad de discado).
  • Programación y calending.
  • Gestión de leads y hopper.
  • DNC (Do Not Call) management.
  • Throttling por canal.

Dominio: comunicación proactiva.

6. Telephony

Responsabilidades:

  • Integración con Asterisk vía ARI.
  • Gestión de canales SIP.
  • IVR dinámico.
  • WebRTC signaling.
  • Grabación de llamadas.
  • Gestión de troncales y DID.

Dominio: telecomunicaciones.

7. Dialer

Responsabilidades:

  • Discador predictivo.
  • Discador progresivo.
  • Discador preview.
  • Algoritmos de pacing adaptivo.
  • Detección de tonos de contestación.
  • Throttling y rate limiting.

Dominio: discado automatizado.

8. Reporting & Analytics

Responsabilidades:

  • Dashboards en tiempo real.
  • Reportes históricos.
  • Exportación (CSV, PDF).
  • Métricas de agentes.
  • Métricas de campañas.
  • SLA reporting.

Dominio: datos y métricas.

9. Async Workers

Responsabilidades:

  • Jobs en background (procesamiento de email, webhooks, notificaciones).
  • Delivery de webhooks outbound.
  • Procesamiento de archivos (grabaciones, exports).
  • Tareas programadas (cron jobs).
  • Retry logic y dead letter queues.

Dominio: trabajo asíncrono.

10. AI Services & Resident Agents

Responsabilidades:

  • Integración con LLMs (OpenAI, Anthropic, Google, BYOK).
  • Abstracción sobre proveedores de AI (puerto + adaptadores).
  • Capacidades de IA para agentes humanos:
    • Clasificación de mensajes.
    • Sentiment analysis.
    • Summarización de conversaciones.
    • Sugerencia de respuestas.
    • Detección de intención.
    • Traducción en tiempo real.
  • Agentes residentes autónomos:
    • KPI Guardian: monitoreo de métricas y optimización automática.
    • Security Sentinel: detección de abuso, fraude y spam.
    • Policy Engine: gestión y optimización de políticas.
    • Health Monitor: salud técnica de la plataforma.
  • Sistema de skills para definir personalidad y restricciones de agentes.
  • Motor de reglas para acciones autónomas dentro de políticas.

Dominio: inteligencia artificial aplicada y automatización autónoma.

11. MCP Server (Model Context Protocol)

Responsabilidades:

  • Servidor MCP para integración externa con herramientas de IA.
  • Chatbot integrado en la plataforma (lenguaje natural).
  • Herramientas (tools) de consulta, gestión y acciones.
  • Autenticación y autorización de conexiones MCP.
  • Aislamiento por tenant en todas las operaciones.
  • Rate limiting y auditoría de acciones MCP.
  • Traducción de lenguaje natural a operaciones de dominio.

Dominio: interfaz de inteligencia artificial para el exterior y chatbot interno.


Decisión: Módulo vs Servicio

Módulos (mismo binario)

ContextoJustificación
Core ApplicationFundacional, todas las demás dependen de él
Conversation ManagementLógica central de negocio, alta cohesión con Assignment
Contact & CRMCore domain, acceso frecuente desde otros contextos
Campaign EngineLógica de negocio, requiere transaccionalidad
Reporting & AnalyticsQueries contra la misma base de datos
AI ServicesAbstraction layer, llamadas a APIs externas, agentes residentes
MCP ServerServidor HTTP/WebSocket dedicado, seguridad aislada

Servicios (proceso separado)

ContextoJustificación
Messaging GatewayRequiere async processing, manejo de conexiones persistentes (WebSocket), escalado independiente por canal
TelephonyProceso separado por Asterisk, necesita ARI client dedicado, escalado independiente
DialerEscalado independiente, puede ser CPU-intensive en discado predictivo
Async WorkersBackground processing, escalado horizontal independiente, no bloquea el request cycle
MCP ServerServidor HTTP/WebSocket, necesita escalado independiente, seguridad aislada
AI Agents (Residentes)Workers de background que consumen eventos, escalado independiente, procesamiento intensivo

Comunicación entre servicios

  • Módulos: llamadas de función directas a través de interfaces Go.
  • Servicios: gRPC para comunicación síncrona, eventos para asíncrona.
  • Entre módulos y servicios: los servicios exponen gRPC, los módulos los consumen.

Base de datos

PostgreSQL como primario

PostgreSQL es la elección por:

  • JSONB: soporte nativo para schema flexible (atributos personalizados).
  • Row-Level Security (RLS): aislamiento a nivel de base de datos para multi-tenancy.
  • Partitioning: particionamiento por tenant o por tiempo.
  • Full-text search: capacidades de búsqueda integradas.
  • Extensions: pgvector para embeddings, pg_trgm para búsqueda fuzzy.
  • Madurez: probado en miles de implementaciones de producción.

Estrategia multi-tenant en base de datos

Opción A: Schema per tenant.

  • Cada tenant tiene su propio schema en la misma base de datos.
  • Pros: aislamiento fuerte, fácil de entender.
  • Contras: overhead de migraciones, límite práctico de tenants.

Opción B: Row-Level Security (RLS).

  • Una sola schema, tenant_id en cada tabla.
  • RLS policy que filtra automáticamente por tenant.
  • Pros: más simple, mejor escalabilidad, migraciones centralizadas.
  • Contras: requiere configuración cuidadosa de RLS.

Recomendación: RLS para la mayoría de las tablas. Schema per tenant solo si un tenant tiene requisitos de aislamiento especial (enterprise, compliance).

Redis

Redis complementa PostgreSQL:

  • Caching: sesiones, configuración de tenants, datos calientes.
  • Pub/Sub: distribución de eventos en tiempo real entre procesos.
  • Rate limiting: control de tasa por tenant, canal, o endpoint.
  • Queues: colas de trabajo para async workers.
  • Distributed locks: locks distribuidos para operaciones críticas.
  • Sessions: almacenamiento de sesiones de agentes.

Diseño de API

REST para clientes externos

  • Endpoints RESTful: recursos nombrados correctamente, métodos HTTP semánticos.
  • JSON como formato: request y response en JSON.
  • Autenticación: OAuth2 bearer tokens.
  • Rate limiting: headers de rate limit (X-RateLimit-*).
  • Paginación: cursor-based o offset-based.
  • Filtros: query parameters para filtrado.
  • Sorting: query parameters para ordenamiento.

gRPC para límites internos

  • Protocol Buffers: serialización eficiente y tipada.
  • HTTP/2: multiplexing y compresión.
  • Streaming: server streaming, client streaming, bidirectional.
  • Interceptors: logging, tracing, auth, rate limiting.
  • Health checking: gRPC health checking protocol.
  • Load balancing: client-side o proxy-based.

Documentación

  • OpenAPI/Swagger: especificación para REST APIs.
  • Protobuf: especificación nativa para gRPC.
  • Code generation: generación automática de clientes y servidores.
  • Versioning: versionado explícito en URLs (/api/v1/) o headers.

Versioning

  • URL path versioning: /api/v1/contacts, /api/v2/contacts.
  • Backward compatibility: versiones antiguas se mantienen por periodo definido.
  • Deprecation headers: Deprecation, Sunset headers para comunicación de deprecación.
  • Migration guides: documentación para migrar entre versiones.