JM Sanchez
Líder de Producto Técnico, Arquitecto de Soluciones y Head of Systems & Data EngineeringQuito el riesgo de plataforma del escritorio del CEO. Llevo más de veinte años trabajando con datos y sistemas, y los últimos doce dirigiendo equipos de inteligencia de negocios e ingeniería cuyo trabajo abarca cinco países. Construyo sistemas pensados para seguir funcionando, pasar una auditoría y costar una fracción de lo que cuesta la versión en la nube gestionada.
La versión corta
- Qué hago
- Soy responsable de toda la línea técnica (edge, cómputo, datos, aplicaciones cliente y cumplimiento) y lidero al equipo que la construye. Me mantengo lo bastante cerca del código para revisarlo bien, y eso es lo que me permite liderar especialistas en lugar de solo administrarlos.
- Dónde
- Doce años dirigiendo BI, analítica e ingeniería de sistemas para operaciones en Estados Unidos, Kenia, Sudáfrica, Filipinas y República Dominicana, reportando a VP y a nivel C. También he entregado trabajo de datos para proyectos del Programa de las Naciones Unidas para el Desarrollo.
- Resultados
- Un asistente de voz que empieza a hablar en menos de 500 ms. Infraestructura que funciona por unos $1,900 al mes donde el equivalente gestionado cuesta $38,000 según precios de lista. Ningún dato personal guardado en texto plano.
- Cómo trabajo
- Los errores nunca se ignoran, las pruebas corren contra una base de datos real, cada dependencia está fijada a una versión exacta y las herramientas asistidas por IA forman parte del flujo de todo el equipo.
- Contratación
- A través de una entidad B2B en Estados Unidos (Delaware), sin costos de employer of record de tu lado.
Dos resultados
Los dos vienen de sistemas que están en producción. Cada uno se abre para mostrar cómo se logró.
Tiempo hasta el primer byte audible
Mismo modelo, mismo hardware, mismo centro de datos.
Costo mensual de la misma carga
Un asistente de voz que empieza a hablar en menos de 500 ms. El pipeline habitual tarda de 3 a 6 segundos con el mismo modelo y el mismo hardware.
Un asistente de voz encadena cuatro servicios: detección de voz, voz a texto, un modelo de lenguaje y texto a voz. Si se ejecutan uno tras otro, el usuario no oye nada durante tres a seis segundos. Cuatro cambios bajaron el tiempo hasta el primer byte audible por debajo de 500 ms.
Cambio Efecto Una sola conexión HTTP/2 para todo Los fragmentos de audio y las señales de control comparten un único flujo bidireccional sobre Connect RPC. No hay máquina de estados de WebSocket ni un viaje de ida y vuelta por cada fragmento. Detección de voz en el dispositivo El silencio se filtra en el cliente y nunca se envía, así que nunca se transcribe ni se factura. La voz empieza con la primera oración La síntesis arranca con la primera oración completa y se reenvía por io.Pipesin búfer. El usuario oye la respuesta mientras el modelo sigue escribiendo.Las interrupciones detienen el trabajo Cuando el usuario habla encima del asistente, la cancelación viaja por context.Done()y detiene la generación y la facturación en ese momento.Tiempo hasta el primer byte audible Pipeline secuencial, cada etapa espera a la anterior 3,000–6,000 ms Pipeline en streaming descrito arriba < 500 ms Infraestructura que cuesta unos $1,900 al mes. La versión en nube gestionada de la misma carga cuesta $38,000 según precios de lista, una diferencia de unos $433,000 al año.
La misma carga de trabajo, costeada de dos maneras. La columna gestionada usa precios de lista publicados para cada capa y sirve como comparación de orden de magnitud.
Versión en nube gestionada, al mes Clúster de base de datos gestionado (Aurora Multi-AZ) $9,600 Kubernetes gestionado y cómputo de aplicación $8,800 Caché y streaming de eventos gestionados $5,400 Entorno de staging espejo $5,200 Plataforma de observabilidad y servicios de seguridad $4,800 Balanceadores, NAT y transferencia de datos $4,200 Total $38,000 Lo que corre en producción, al mes Clúster de cómputo sin estado, producción y staging $1,100 CDN empresarial, WAF, DNS y TLS $400 Almacenamiento en bloque persistente, todos los nodos $260 Almacenamiento de objetos y archivado WAL, multirregión $140 Capa de base de datos gestionada eliminada Capa de balanceador y NAT eliminada Total $1,900 La versión de producción es un clúster de cómputo sin estado con volúmenes persistentes separados, un edge de CDN y archivado WAL continuo. Producción y staging se construyen igual, así que no hay diferencias de configuración entre ellos.
Quitar la capa de base de datos gestionada también quita una frontera de seguridad, así que la reemplacé por una más fuerte: cada campo de datos personales se cifra con una clave emitida por KMS antes de llegar al disco. Una copia robada de la base de datos no contiene nada legible. El razonamiento está en la decisión D-03.
Cuatro plataformas
Sistemas que diseñé, construí o lideré, y de los que sigo siendo responsable. Los nombres de clientes y productos se reservan por confidencialidad; puedo explicar cualquiera a fondo en una llamada.
Plataforma de IA de voz en tiempo real. Un asistente conversacional que responde en menos de 500 ms.
Lo difícil
Cuatro servicios en red (detección de voz, voz a texto, un agente con modelo de lenguaje y texto a voz) encadenados de forma ingenua producen de tres a seis segundos de silencio, una factura que crece con cada sílaba y ninguna forma de interrumpir a la máquina cuando empieza a hablar.
Qué construí
- Streaming bidireccional HTTP/2 sobre Connect RPC, con audio y señales de control en una sola conexión.
- Interrupción mediante
context.Done(), que detiene la síntesis a mitad de oración y con ella la facturación. - Reenvío por
io.Pipesin búfer y síntesis oración por oración. - Dos bases de datos: los datos personales y de facturación en una bóveda gestionada a la que se llega por un túnel mTLS, y la analítica en un PostgreSQL local dentro de una red privada.
- Tokens de sesión opacos en Valkey, con control de cuotas en la frontera del protocolo para que una solicitud por encima de su límite falle antes de costar algo.
Resultados
- Menos de 500 ms hasta el primer byte audible.
- Cerca de un 70% menos de costo de síntesis de voz, cambiando la forma de las respuestas del modelo.
- Ninguna credencial humana expuesta: el túnel hacia la bóveda es solo de salida y de máquina a máquina.
Go 1.26, Connect RPC, HTTP/2 (h2c), Protobuf, PostgreSQL con pgx v5, Valkey, Whisper para voz a texto, texto a voz en streaming, detección de voz WebRTC, Caddy, Flutter.
Plataforma federada de datos cívicos. Funciona sin conexión en el terreno, cifra los datos personales antes de que toquen un disco y modela tres autoridades legales que no coinciden entre sí.
Lo difícil
Operadores de campo en todo un país, muchas veces sin señal, capturan datos personales regulados. Eso exige escrituras locales que se reproduzcan siempre igual, prueba de quién escribió qué, autorización a nivel nacional, regional y local que se resuelva en tiempo constante, y un presupuesto sin fines de lucro que descarta una arquitectura gestionada de varias capas.
Qué construí
- Una cola de comandos sin conexión: los cambios se escriben localmente, se firman con ED25519 y se reproducen en el servidor registro por registro, así que un registro malo nunca aborta un lote.
- Cifrado de envoltura AES-256-GCM con una clave de datos de KMS y un IV aleatorio de 12 bytes por campo. El texto plano y la clave se borran de la memoria justo después de usarse.
- Control de acceso por territorio en lugar de roles planos, con árboles de UUID codificados por prefijo para que comprobar si un registro está dentro de mi región tome tiempo constante.
- Tres registros geográficos separados (el estándar internacional, la ley nacional y la autoridad catastral), cada uno congelado y versionado, conectados por tablas de equivalencia en lugar de forzarlos a una sola jerarquía.
- Triggers de base de datos que hacen imposible editar las ediciones de referencia publicadas, y pruebas de datos semilla que fallan el build si se rompe la procedencia.
- Un solo código Flutter para iOS, Android, escritorio y web, con SQLCipher y el almacén de claves del hardware en dispositivos nativos, y una bóveda WebCrypto no extraíble en el navegador.
Go 1.26, Connect RPC, PostgreSQL 18, Valkey, AWS KMS, Flutter y Dart, SQLCipher, WebCrypto, OpenTofu, Hetzner Cloud, Caddy, WAL-G, Buf, Devbox.
Plataforma de BI multinacional. Un solo conjunto de números acordado por operaciones, finanzas y la dirección en cinco países, a cargo del equipo de 5 personas que dirijo.
Lo difícil
Un BPO grande con operaciones en Estados Unidos, Kenia, Sudáfrica, Filipinas y República Dominicana tenía sus reportes repartidos entre servidores, hojas de cálculo y departamentos. Cada revisión ejecutiva empezaba discutiendo qué números eran los correctos, y la nómina, la facturación y los incentivos dependían de esos números.
Qué construimos mi equipo y yo
- Una implantación de Apache Superset que se convirtió en la única fuente de reportes para la dirección ejecutiva y la gobernanza operativa.
- ETL automatizado entre servidores con SSIS, Python y Power Query hacia un SQL Server central, que redujo en un 40% el tiempo de procesamiento de reportes.
- Marcos de KPI e incentivos ponderados para agentes, supervisores, gerentes, directores y VP, con las mismas definiciones que usan los reportes.
- Reportes de P&L y modelos de pronóstico para el nivel C, y nómina y facturación verificadas contra ingresos, horas facturables y términos contractuales.
- Sistemas web internos construidos desde el diseño hasta su adopción, incluida una aplicación MVC para registrar y auditar horas de trabajo manuales, hecha bajo PCI-DSS y estándares de call center, y una aplicación de monitoreo de calidad para toda la empresa.
Apache Superset, SQL Server, SSIS y SSRS, Python, Power BI, T-SQL, C# y .NET MVC.
Red edge sin dirección IPv4 pública permanente. Toma una durante unos segundos para descargar imágenes y luego la libera.
Lo difícil
Un host solo IPv6 no puede descargar imágenes de contenedor privadas de un registro que no publica registros IPv6 (AAAA). La solución fácil es una IPv4 pública permanente, que también es un blanco permanente para los escáneres. Mantuve el host solo IPv6 y resolví el problema de la descarga.
Qué construí
- Una dirección IPv4 temporal que se asigna solo durante la descarga y se retira cuando se dispara un hook de éxito. Una versión anterior basada en temporizador quitaba rutas a mitad de la descarga; la versión basada en eventos no puede.
- Un certificado de origen del CDN aprovisionado desde código, que resolvió un ciclo del desafío ACME detrás de un proxy que siempre fuerza HTTPS, sin pasos manuales en la consola.
- Ciclos de vida separados: los cambios de configuración de arranque ya no reconstruyen servidores, los volúmenes de base de datos y las claves de KMS están protegidos contra borrado, y las direcciones IP ya no cambian cuando cambian los servidores.
- Credenciales de registro de corta duración en lugar de tokens de acceso personales, así que no hay un secreto de larga duración que guardar o filtrar.
- Despliegues que esperan a que el servicio esté listo, cortan los bucles de caídas, prueban la conectividad de salida desde dentro de la red y revierten solos si la verificación falla.
Resultados: ninguna dirección IPv4 pública permanente, ningún secreto de registro de larga duración y varios minutos menos en cada arranque en frío.
OpenTofu, Hetzner Cloud, Cloudflare (WAF, DNS, Origin CA), cloud-init, Docker Compose, GitHub Actions, Caddy, SOPS con age, Trivy.
Otros trabajos. Proyectos de datos del Programa de las Naciones Unidas para el Desarrollo, una plataforma de datos electorales en vivo y documentación de cumplimiento en salud.
- Programa de las Naciones Unidas para el Desarrollo. Trabajo de datos y analítica en dos proyectos, convirtiendo los datos de los programas en reportes útiles para sus equipos.
- Plataforma de datos electorales. Pipelines de conteo de votos en vivo conectados a los datos de la autoridad electoral nacional, además de un sistema y una app de registro de miembros. Dirigí a un equipo de un analista y tres desarrolladores como gerente de proyecto y de producto, y me encargué personalmente de la ingeniería de datos en vivo.
- Cumplimiento en salud. Documentos auditados de políticas, procedimientos y licencias para una empresa de cumplimiento en salud con sede en Texas, bajo HIPAA, HITECH y la Stark Law. Cada documento lo aprueba un especialista certificado en cumplimiento.
Registro de decisiones
Estas son las decisiones que defendería en una revisión de arquitectura: qué elegí, qué descarté y qué costó. Guardo registros como estos en los propios repositorios, junto al código al que afectan.
D-01Síntesis de voz oración por oración en lugar de
esperar la respuesta completa del modelo- Contexto
- Un pipeline de voz secuencial deja al usuario en silencio de tres a seis segundos.
- Decisión
- Hacer streaming sobre una sola conexión HTTP/2 multiplexada y empezar la síntesis con la primera oración completa.
- Consecuencias
- Menos de 500 ms hasta el primer byte audible. La cancelación tiene que llegar a cada etapa, así que todas corren bajo un contexto compartido.
D-02Tokens opacos guardados en Valkey en lugar de
sesiones JWT- Contexto
- Un JWT no se puede revocar sin una lista de revocación, y una lista de revocación es un almacén de sesiones con otro nombre.
- Decisión
- Usar un almacén de sesiones de verdad y mantener los tokens opacos.
- Consecuencias
- Revocación inmediata, solicitudes más pequeñas y conteo de cuotas en tiempo constante. Un servicio con estado más que operar.
D-03Cifrado por campo en la aplicación en lugar de
una capa de datos separada y segregada- Contexto
- El presupuesto no alcanzaba para una capa de datos segregada.
- Decisión
- Cifrar cada campo de datos personales con AES-256-GCM usando una clave de datos emitida por KMS antes de que llegue al disco, y borrar la clave de la memoria después de usarla.
- Consecuencias
- La base de datos nunca contiene datos personales legibles, aunque alguien la copie. KMS solo se llama cuando un lote contiene datos personales, así que su latencia no frena el tráfico normal.
D-04Un clúster HA propio, con staging igual a producción en lugar de
una nube gestionada de varias capas- Contexto
- La versión gestionada de la carga cuesta $38,000 al mes según precios de lista.
- Decisión
- Nodos de cómputo sin estado, volúmenes persistentes separados, archivado continuo con WAL-G y un CDN empresarial, con staging idéntico a producción.
- Consecuencias
- Unos $1,900 al mes, ninguna diferencia de configuración y escalado horizontal agregando nodos. El equipo opera la infraestructura, así que los simulacros de restauración están automatizados en lugar de solo documentados.
D-05Una IPv4 temporal durante la descarga de imágenes en lugar de
una IPv4 pública permanente- Contexto
- Un host solo IPv6 necesitaba imágenes de un registro sin registros IPv6. Una dirección permanente sería escaneada de forma permanente.
- Decisión
- Asignar una dirección solo para la descarga y liberarla desde un hook de éxito basado en eventos.
- Consecuencias
- Ninguna exposición IPv4 permanente. La complejidad de tiempos que esto añadió se eliminó después al pasar el desmontaje de un temporizador al hook.
D-06Protobuf sobre HTTP/2 en todas las APIs en lugar de
JSON sobre REST- Contexto
- Servidor y cliente se desalinean cuando cada lado escribe sus propios tipos de solicitud y respuesta.
- Decisión
- Generar ambos lados desde el mismo archivo de contrato y no permitir JSON en el cable.
- Consecuencias
- Desaparece toda una clase de errores de integración, las versiones cambian de forma segura mediante la numeración de campos y los mensajes pesan menos en conexiones móviles lentas. Depurar requiere herramientas que lean el formato binario.
D-07SQL escrito a mano a través de un pool de conexiones en lugar de
un ORM- Contexto
- Los reportes sobre series de tiempo particionadas tienen que seguir siendo predecibles bajo carga.
- Decisión
- Escribir el SQL, generar código tipado a partir de él con sqlc y ejecutarlo con pgx.
- Consecuencias
- Planes de consulta que cualquiera puede leer e índices sobre los que cualquiera puede razonar. Más SQL que escribir y revisar.
D-08Pruebas contra una base de datos real en lugar de
repositorios simulados con mocks- Contexto
- Un mock confirma que el código coincide con mis supuestos. Solo una base de datos real confirma que mis supuestos coinciden con la base de datos.
- Decisión
- Las pruebas de integración corren contra un PostgreSQL real, y la integración continua falla si se omite alguna prueba.
- Consecuencias
- Pruebas más lentas, y ningún pipeline en verde que no haya probado nada.
D-09Cada dependencia fijada a una versión exacta en lugar de
etiquetas flotantes como:latesty@main- Contexto
- Cuando hay un incidente, el build que importa puede tener seis meses.
- Decisión
- Versiones semánticas o digests SHA-256 para contenedores, GitHub Actions, módulos de Go y proveedores de infraestructura.
- Consecuencias
- Cualquier build pasado se reproduce byte por byte. Las actualizaciones se hacen a propósito, mediante un cambio revisado.
Por qué Go
Go compila a un solo binario estático, maneja decenas de miles de conexiones concurrentes en un solo nodo y trata cada error como un valor que hay que atender. Los resultados de latencia y costo de arriba dependen de las tres cosas.
La función de cifrado por campo de la plataforma de datos cívicos, con notas sobre lo que muestra.
internal/vault/seal.gopackage vault import ( "context" "crypto/aes" "crypto/cipher" crand "crypto/rand" "encoding/binary" "errors" "fmt" "io" "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" ) // A version byte prefix lets keys or algorithms rotate later with no data migration. const ( envelopeV1 = 0x01 nonceSize = 12 // 96-bit GCM nonce ) // Sentinel errors — internal KMS/network detail never leaks to the caller. var ( ErrSeal = errors.New("vault: seal failed") ErrContext = errors.New("vault: context invalid or canceled") ErrEntropy = errors.New("vault: entropy source failure") ) // Seal encrypts one PII field with a per-record data key from KMS and returns a // self-describing envelope. The plaintext data key never outlives this call. func (v *Vault) Seal(ctx context.Context, plaintext []byte) (_ []byte, err error) { if len(plaintext) == 0 { return nil, fmt.Errorf("%w: empty payload", ErrSeal) } // One span per seal; success/error recorded on the way out. ctx, span := v.tracer.Start(ctx, "Vault.Seal", trace.WithAttributes( attribute.String("kms.key_id", v.keyID), attribute.Int("payload.bytes", len(plaintext)), )) defer func() { if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) v.metrics.SealErrors.Inc() } span.End() }() // Bound the call only if the caller gave us no deadline of its own. if _, ok := ctx.Deadline(); !ok && v.kmsTimeout > 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, v.kmsTimeout) defer cancel() } if err = ctx.Err(); err != nil { return nil, fmt.Errorf("%w: %w", ErrContext, err) } // KMS data key, with latency recorded for the SLO. start := time.Now() dek, err := v.kms.GenerateDataKey(ctx, v.keyID) v.metrics.KMSLatency.Observe(time.Since(start).Seconds()) if err != nil { return nil, fmt.Errorf("%w: generate data key", ErrSeal) } defer wipe(dek.Plaintext) // zeroed on every path, including panic block, err := aes.NewCipher(dek.Plaintext) if err != nil { return nil, fmt.Errorf("%w: new cipher", ErrSeal) } gcm, err := cipher.NewGCM(block) if err != nil { return nil, fmt.Errorf("%w: new gcm", ErrSeal) } // One allocation for the whole envelope. size := 1 + 2 + len(v.keyID) + 2 + len(dek.Ciphertext) + nonceSize + len(plaintext) + gcm.Overhead() out := make([]byte, 0, size) out = append(out, envelopeV1) out = binary.BigEndian.AppendUint16(out, uint16(len(v.keyID))) out = append(out, v.keyID...) out = binary.BigEndian.AppendUint16(out, uint16(len(dek.Ciphertext))) out = append(out, dek.Ciphertext...) // Reserve the nonce and fill it from the OS CSPRNG. ivStart := len(out) out = out[:ivStart+nonceSize] if _, err = io.ReadFull(crand.Reader, out[ivStart:]); err != nil { return nil, fmt.Errorf("%w: %w", ErrEntropy, err) } // Seal in place: ciphertext+tag land in the same backing array. out = gcm.Seal(out, out[ivStart:], plaintext, nil) return out, nil }- Un solo binario. Se distribuye en un contenedor distroless sin root, sin runtime que instalar o parchear, y arranca en milisegundos. Cada nodo del clúster necesita una pequeña fracción de la memoria que pediría un runtime gestionado.
- Concurrencia barata. Una goroutine arranca con unos pocos kilobytes de pila, mientras que un runtime de un hilo por solicitud arranca con cerca de un megabyte. Por eso el audio en vivo y los procesos de sincronización en segundo plano pueden compartir hardware modesto.
- Errores que no se pueden ignorar por accidente. Con
errcheckcomo control de merge, un error sin manejar detiene el pipeline, y los incidentes en producción llegan con una causa legible.
Seguridad y cumplimiento
He trabajado bajo HIPAA, HITECH, la Stark Law, PCI-DSS y GDPR, y construyo la criptografía además de los documentos de políticas. El diseño de cumplimiento está autoevaluado contra estándares publicados y no está certificado por un tercero. Cuando se requiere una certificación, preparo la evidencia que necesita el auditor y trabajo junto al evaluador.
Cómo se manejan los datos personales, la identidad, el borrado y la recuperación.
Cifrado de envoltura
KMS emite una clave de datos, el campo se cifra en memoria con AES-256-GCM y un IV aleatorio de 12 bytes, y la base de datos guarda juntos la clave cifrada, el IV y el texto cifrado. El texto plano y la clave se borran de inmediato.
Identidad
Un handshake ligado al dispositivo devuelve en una sola respuesta el token de sesión, los permisos, el alcance territorial y una clave de base de datos local derivada por el servidor. Los cambios hechos sin conexión llevan firmas ED25519 que se verifican antes de reproducirlos. El acceso a la bóveda usa certificados (mTLS), así que no existe una contraseña que filtrar.
Artículos 9 y 17 del GDPR
Los datos de categoría especial nunca se guardan en texto plano. El borrado está integrado en el modelo de datos: los registros usan UUID como clave y tienen borrados en cascada, así que borrar a una persona es una sola operación con un alcance conocido.
Trabajo regulado
Una aplicación de nómina y horas manuales construida y auditada bajo PCI-DSS y estándares de call center. Trabajo continuo de documentación bajo HIPAA, HITECH y la Stark Law para consultorios médicos de Estados Unidos.
Cadena de suministro
Versiones fijadas en todas partes, secretos cifrados en reposo con SOPS y age, y Trivy, govulncheck, osv-scanner y go-licenses en el pipeline, incluida una comprobación de que no entre ninguna licencia copyleft.
Recuperación ante desastres
Archivado continuo con WAL-G en almacenamiento compatible con S3 y simulacros de restauración automatizados. Protección contra borrado en volúmenes persistentes y claves de KMS, y selección explícita de recursos para que una reconstrucción solo pueda tocar la capa de cómputo.
Cómo se publican los cambios
Cada cambio va de una rama de funcionalidad, a través de controles automáticos, a un despliegue verificado. Si falla cualquier control, el despliegue se revierte solo y las sondas de diagnóstico se quedan en su sitio.
Los cinco controles, el ciclo de incidentes y la regla de “terminado”.
Etapa Qué pasa Bloquea el cambio si Rama El trabajo se hace en una rama de funcionalidad, nunca en main.falla el hook de pre-push Análisis estático Corren golangci-lint,go vetystaticcheck.queda algún error sin manejar Pruebas Las pruebas de integración corren contra un PostgreSQL real. una prueba falla o se omite Imagen Se construye una imagen distroless sin root, fijada por digest y escaneada con Trivy y govulncheck. una etiqueta flota o un escaneo falla Publicación Un despliegue gradual espera a que el servicio esté listo y prueba la conectividad de salida antes de recibir tráfico. la verificación no pasa Después de publicar
- Instrumentar primero. La telemetría corre fuera del proceso mediante APIs del plano de control, sin agentes dentro del proceso.
- Detectar pronto. Los timeouts y las sondas de salud convierten una lentitud en una señal en lugar de un bloqueo silencioso.
- Diagnosticar en el sitio, agregando instrumentación en lugar de relajar la seguridad.
- Corregir y luego verificar con comprobaciones en vivo desde fuera del edge del CDN.
- Conservar en el repositorio las sondas que encontraron el problema, para la próxima vez.
Cuándo un cambio está terminado
Cada error tiene contexto y un timeout acotado; las pruebas contra la base de datos real pasan sin ninguna omitida; y una comprobación en vivo más allá del edge (sonda TLS, llamada RPC autenticada, preflight de CORS) resulta bien. Entonces pasa de la rama de funcionalidad a develop y a main, con la reversión preparada.
Cómo lidero
Desde Santo Domingo dirijo un equipo de inteligencia de negocios e ingeniería cuyo trabajo llega a operaciones en cinco países. Buena parte de mi semana transcurre entre operaciones, finanzas, la dirección ejecutiva e ingeniería, convirtiendo objetivos que cada grupo define de forma distinta en un plan que todos firman. También diseñé los marcos de KPI e incentivos ponderados que se usan desde agente hasta VP, para que el desempeño se mida igual que como la empresa lo paga.
Me importan las personas que entregan el trabajo tanto como la arquitectura. Un sistema que el equipo no puede hacer suyo no dura, por bien que se vea en papel.
Mis equipos trabajan con seis reglas, y el pipeline las hace cumplir:
- Ningún fallo silencioso. Cada error se envuelve con contexto. Ningún bloque catch vacío y ninguna excepción tragada.
- Un timeout en cada llamada de red, medido en segundos, con cancelación compartida en toda la solicitud.
- Verificado antes de darlo por terminado: sondas TLS más allá del CDN, llamadas RPC autenticadas, comprobaciones de preflight de CORS.
- La deuda técnica escrita en el repositorio, donde la va a encontrar el siguiente ingeniero.
- De funcionalidad a develop y a main, nunca directo a producción, lo pida quien lo pida.
- Instrumentar antes de escalar. Cuando algo se rompe agregamos instrumentación, no excepciones al modelo de seguridad.
“Un sistema que funciona en hardware modesto le gana a una arquitectura correcta que nadie puede pagar.”
Herramientas
Todas las herramientas, agrupadas según cuánto depende de cada una.
De estas depende producción
- Runtime y protocolo
- Go 1.26, Connect RPC, Protocol Buffers, HTTP/2 (h2c), gRPC, Buf, protovalidate, sqlc
- Datos
- PostgreSQL 18, pgx v5, series de tiempo particionadas, PL/pgSQL, Valkey y Redis, SQL Server, Oracle, MySQL, SQLite y SQLCipher, WAL-G
- Seguridad
- AWS KMS, cifrado de envoltura AES-256-GCM, ED25519, mTLS, tokens opacos, SOPS con age, aislamiento de red zero-trust
- Cliente
- Flutter y Dart para iOS, Android, escritorio y web, sincronización sin conexión, Isar, WebCrypto, Svelte 5, Astro 5, TypeScript
- Infraestructura
- OpenTofu y Terraform, AWS, Cloudflare, Hetzner Cloud, Azure, Google Cloud, Docker, Caddy, GitHub Actions, Linux
Cómo entrega el equipo
- Trabajo asistido por IA
- Claude Code, Aider, OpenCode, Codex, Gemini AI Studio, ciclos automáticos de pruebas y lint
- Calidad
- Devbox, golangci-lint, go vet, staticcheck, revive, govulncheck, osv-scanner, Trivy, go-licenses, ast-grep, Vitest
- Datos y BI
- Apache Superset, SSIS y SSRS, Power BI y Power Platform, Python, Apache ECharts, MapLibre GL
- Red y operaciones
- Tailscale, WireGuard, Prometheus y Alertmanager, cloud-init, redes solo IPv6, Jira, Linear, ClickUp
Patrones que sirven en cualquier stack
- Arquitectura
- Replicación sin conexión, un modelo de comandos CQRS ligero, monolitos modulares, cómputo sin estado con almacenamiento persistente separado, infraestructura desechable definida en código
- Corrección
- Reproducción idempotente, entrega al menos una vez con deduplicación, bloqueo optimista, inmutabilidad garantizada por la base de datos, timeouts acotados, cancelación en cascada
- Práctica
- Ingeniería de fiabilidad de sitios, Scrum, desarrollo guiado por pruebas, registros de decisiones de arquitectura, deuda técnica documentada, desarrollo guiado por especificaciones, análisis de negocio
Experiencia
| Años | Rol | Organización |
|---|---|---|
| actual | Product Manager, líder de IA y desarrollador principal en un equipo de 3 ingenieros | Producto confidencial (bajo NDA) |
| 2022–hoy | Gerente de Inteligencia de Negocios, Estadística y Reportes | ERC Global CX, remoto y multinacional |
| 2025–hoy | Especialista en contenido de cumplimiento en salud, a tiempo parcial | Empresa de cumplimiento en salud, Texas (remoto) |
| 6 meses | Gerente General, Product Manager y Scrum Master (contrato) | Proyectos empresariales farmacéuticos, República Dominicana |
| 2014–2022 | Gerente de Estadística y Reportes | ERC Global / Working Bees |
| 2012–2014 | Analista Senior, luego Gerente del Equipo de Reportes | Laurus International, Santo Domingo |
| 2003–2010 | Analista Líder de Estadística y Jefe de Departamento | Amov International Teleservices (Claro / América Móvil), Santo Domingo |
Qué implicó cada rol.
Producto confidencial, actual
Desarrollador principal en un equipo de tres personas, a cargo de la dirección del producto y de la arquitectura de IA. El cliente no me corresponde nombrarlo.
ERC Global CX, 2022 a hoy
- Dirijo un equipo de BI y analítica de 5 personas en Santo Domingo y Estados Unidos, y convertí los reportes estáticos en una práctica completa de inteligencia de negocios.
- Soy responsable de los datos de facturación, nómina y KPI de desempeño, consolidando datos de producción de Estados Unidos, Kenia, Sudáfrica, Filipinas y República Dominicana.
- Principal contacto técnico de operaciones, finanzas y la dirección ejecutiva; los marcos de KPI, los modelos de incentivos y los reportes de P&L van directo a VP y al nivel C.
- Llevando el stack a herramientas de código abierto preparadas para IA, para procesar datos más rápido.
Cumplimiento en salud, 2025 a hoy
Investigo y redacto documentos de políticas, procedimientos y licencias para consultorios médicos de Estados Unidos bajo HIPAA, HITECH y la Stark Law, cada uno aprobado por un especialista certificado en cumplimiento.
Proyectos farmacéuticos, contrato de seis meses
Dirigí un equipo de 6 personas, entre analistas y desarrolladores junior y senior, en tres productos a la vez: BI geolocalizado, una solución en Microsoft Power Apps y una plataforma SaaS con funciones de call center. Llevé la relación con el cliente y diseñé la arquitectura en AWS (balanceo de carga, EC2, red).
ERC Global / Working Bees, 2014 a 2022
Construí la función de reportes, desde los tableros de desempeño hasta el P&L ejecutivo. Diseñé las bases de datos, los procedimientos almacenados y los paquetes SSIS para ETL automatizado y transferencias entre servidores, y fui responsable de los cálculos de ingresos, horas facturables y nómina detrás de los pronósticos y presupuestos.
Laurus International, 2012 a 2014
Dirigí a tres analistas como Analista Senior y luego gestioné el Equipo de Reportes. Construí ETL en SQL Server para facturación, nómina y KPI de operaciones, y reduje en un 40% el tiempo de procesamiento manual con reportes automatizados.
Amov International Teleservices, 2003 a 2010
Dirigí un departamento de estadística de tres personas, a cargo de las estadísticas operativas y los reportes para cuentas internacionales de telecomunicaciones. Construí bases de datos, servidores de archivos, macros y controles de captura de datos en tiempo real para equipos distribuidos.
Educación, idiomas y certificaciones.
- Educación
- Licenciatura en Ingeniería de Software, Universidad del Caribe (UNICARIBE), en curso. Técnico profesional en Informática, Politécnico Fabio A. Mota.
- Idiomas
- Español (nativo), inglés (profesional completo, C2), italiano (conversacional).
- Ingeniería
- Site Reliability Engineering y Developing a Google SRE Culture (Google); Spec-Driven Development (Kiro / AWS); Clean Code with Go (CodeSignal); Mastering Design Patterns with Go.
- Negocio y liderazgo
- Especialización de preparación para el examen CBAP® (Coursera); Business Analysis: Key Definitions and Strategy Analysis (Starweaver); Effective Leadership Principles y Adaptive Leadership Principles (CodeSignal).
Preguntas
¿A qué se dedica JM Sanchez?
Es Líder de Producto Técnico, Arquitecto de Soluciones y Head of Systems & Data Engineering. Es responsable de toda la línea técnica (edge, cómputo, datos, aplicaciones cliente y cumplimiento) y lidera al equipo que la construye, con doce años de trabajo en inteligencia de negocios, arquitectura de plataformas y fiabilidad de sitios en cinco países.
¿Cómo se logra IA de voz en tiempo real en menos de 500 ms?
Un pipeline secuencial (detectar, transcribir, pensar, hablar) hace esperar al usuario de tres a seis segundos. Hacer streaming por una sola conexión HTTP/2 multiplexada y pronunciar cada oración en cuanto está lista, en lugar de esperar la respuesta completa del modelo de lenguaje, baja el tiempo hasta el primer byte audible por debajo de 500 ms con el mismo modelo, hardware y centro de datos.
¿Cuánto más barata es la infraestructura propia que la nube gestionada?
Unas 20 veces más barata: cerca de $1,900 al mes con infraestructura propia frente a $38,000 al mes en el equivalente gestionado, con el mismo clúster HA, respaldos con WAL-G, CDN y WAF empresariales y observabilidad completa. Son unos $433,000 ahorrados al año.
¿Cómo se protegen los datos personales?
Con cifrado de envoltura en la aplicación. Cada campo de datos personales se cifra con una clave emitida por KMS antes de llegar al disco, así que ningún dato personal se guarda en texto plano y quien copie la base de datos no obtiene nada legible.
¿JM trabaja solo o lidera equipos?
Lidera equipos. Dirige un equipo de inteligencia de negocios e ingeniería cuyo trabajo abarca cinco países, y lleva doce años gestionando y haciendo crecer personas. Se mantiene lo bastante cerca de cada capa del stack para liderar especialistas en lugar de solo administrarlos.
¿Qué roles busca JM?
Roles de Head of Engineering, Technical Lead y arquitecto fundador.
¿Cómo puedo contactarlo?
Con el formulario de contacto de esta página o con un mensaje por LinkedIn. Cada mensaje recibe una respuesta personal, normalmente en un día.
Contacto
Cuéntame en qué estás trabajando: el objetivo de latencia, el requisito de cumplimiento, el sistema que nadie quiere tocar o la factura de infraestructura. Leo cada mensaje y respondo personalmente, normalmente en un día. También puedes escribirme por LinkedIn.
Este sitio no publica correo ni teléfono. El formulario me envía tu mensaje directamente por una conexión cifrada.