{
 "subtemas": [],
 "tarjetas": [
  {
   "sub": "Comunicación",
   "q": "CloudEvents: el sobre estándar de eventos",
   "a": "Spec de CNCF: id, source, type (com.empresa.pedido.creado.v1), specversion, time, datacontenttype + extensiones (traceparent, tenantid).\nBeneficio: herramientas neutrales (routers, validators, sinks) entienden TODOS tus eventos; el type versionado evita magic strings.\nAdoptar en el wrapper del outbox desde el día 1 — migrar después duele.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Event granularity: fino, grueso y la regla práctica",
   "a": "Muy fino (CampoActualizado por cada campo): tormenta de eventos, consumidores engordando.\nMuy grueso (NegocioCambiado con todo): consumidores filtrando y parseando de más.\nRegla: un evento por HECHO DE NEGOCIO significativo (PedidoCreado, PagoRechazado), payload con las entidades afectadas + id + versión.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Versionado de eventos: compatibilidad en la práctica",
   "a": "type con versión (pedido.creado.v2). V2 añade campos OPCIONALES (consumidores viejos ignoran).\nCambios incompatibles: nuevo type v2 CONVIVE con v1 (publicas ambos durante transición), migras consumidores, matas v1 con fecha.\nNunca: cambiar semántica del mismo type en silencio — los consumidores viejos seguirán funcionando MAL sin error.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Long polling, streaming y gRPC bidi: para datos en vivo",
   "a": "gRPC bidirectional streaming: canal persistente tipo-duplex con backpressure nativo — el más eficiente entre servicios de tu dominio.\nSSE/WebSocket en el edge para clientes.\nLong polling: fallback universal, simple pero desperdicia conexiones.\nCriterio: frecuencia de datos y tamaño de payload — eventos espaciados → SSE; continuo/binario → gRPC bidi.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Datos y consistencia",
   "q": "Saga log: persistir el estado de la saga y reanudar",
   "a": "La saga misma es un agregado: tabla saga_log(saga_id, step, status, payload) — cada paso registra antes de ejecutar.\nCrash recovery: al arrancar el orquestador, reanuda sagas en estados intermedios (reintenta paso pendiente, idempotente).\nTimeout por paso → compensación automática.\nSin persistencia de saga, un restart pierde la mitad de las operaciones en curso.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Datos y consistencia",
   "q": "Dual write: el bug silencioso más común",
   "a": "Código: guardar en BD + publicar a cola, sin transacción entre ambos.\nFallas: crashea entre ambos (dato sin evento o evento sin dato), o tx rollback pero mensaje ya enviado.\nSíntomas: datos que 'a veces' no aparecen downstream, imposible de reproducir.\nÚnica solución seria: outbox (mismo tx) o broker transaccional en la misma BD.",
   "nivel": "avanzado",
   "clave": true
  },
  {
   "sub": "Datos y consistencia",
   "q": "Proyecciones CQRS: rebuild y testing",
   "a": "Proyección = función determinista (estado + evento → nuevo estado) con posición guardada (offset/version por proyección).\nRebuild: borrar read store y reprocesar desde evento 0 — corre como deploy (verificando conteos antes de cutover).\nTesting: fixture de eventos → assert de estado final; test de idempotencia (mismo evento 2 veces = mismo estado).\nVersiona la proyección junto al evento.",
   "nivel": "basico",
   "clave": false
  },
  {
   "sub": "Datos y consistencia",
   "q": "Snapshot y purge en event store: rendimiento a largo plazo",
   "a": "Streams de millones de eventos → reconstruir estado tarda segundos.\nSnapshot cada N eventos (ej. 100): estado serializado + versión → cargar snapshot + eventos posteriores.\nPurge: eventos viejos archivados a almacenamiento frío (el snapshot conserva el estado legalmente necesario).\nMonitorear: tiempo medio de reconstrucción por agregado.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Datos y consistencia",
   "q": "Consistencia en UI: patrones de UX para eventual",
   "a": "Optimistic UI: mostrar el estado esperado inmediatamente ('Tu pedido está en proceso'), sincronizar al confirmar.\nPendiente explícito: estados visibles PENDING/PROCESANDO con refresh automático (polling/websocket).\nRead-your-writes: tras escribir, las consultas del usuario van al write model o a réplica actualizada.\nNEVER: pantalla de error por lag eventual que el usuario percibe como fallo.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Rate limiting por niveles de servicio (gold/platinum)",
   "a": "Clasificar clientes (plan, prioridad) → presupuesto por clase: gold sin límite práctico, free con N rps.\nEn gateway: atributo del token (claim plan) → política correspondiente.\nBajo presión extrema: shedding empieza por free (proteger revenue-critical).\nComunicado claro al cliente: límites documentados + métrica de cuota consumida.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Self-healing automático: qué permite K8s y qué no",
   "a": "K8s sana automáticamente: pod muerto → restart, nodo caído → reschedule, health check fallido → reinicio.\nNO sana: dependencias externas caídas (necesitas breakers/fallbacks), bugs (necesitas rollback), saturación sostenida (necesitas autoscaling + shedding).\nEl equipo diseña PARA el restart: idempotencia, arranque rápido, estado externo.\nGame days validan el self-healing real.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "El patrón request hedging: duplicar llamadas para ganar P99",
   "a": "Lanzar la misma llamada a 2 réplicas tras un pequeño delay (ej. 50ms) y tomar la primera respuesta — reduce tail latency dramáticamente en servicios con colas variadas.\nCosto: 2x tráfico en los casos lentos; SOLO para operaciones read-only/idempotentes.\nNo aplicar globalmente: en dependencias con costos por llamada (APIs pagas) es tirar dinero.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Timeout defaults sensatos por tipo de llamada",
   "a": "DB queries: 1-5s (OLTP). Cache: 50-100ms. API interna crítica: 500ms-2s. API interna batch: 10-30s. API externa pagos: 5-10s. Email/webhook: async (nunca en el request path).\nConnect timeout SEPARADO del read timeout (2-3x menor).\nDocumentar el presupuesto heredado: tu timeout ≤ presupuesto del llamador.",
   "nivel": "intermedio",
   "clave": true
  },
  {
   "sub": "Resiliencia",
   "q": "Graceful shutdown en microservicios: checklist",
   "a": "1) Recibir SIGTERM → dejar de aceptar nuevos (readiness false). 2) Terminar requests en curso (timeout). 3) Parar consumidores (ack/nack pendientes). 4) Flush de métricas/logs/buffers. 5) Cerrar pools. 6) exit 0.\nEn K8s: terminationGracePeriodSeconds > suma de todo lo anterior.\nSin esto: cada deploy pierde requests y mensajes.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Dashboards por servicio: el layout mínimo viable",
   "a": "Fila 1: salud (SLO compliance, error rate, p95/p99). Fila 2: tráfico (req/s por endpoint top, throughput de colas). Fila 3: dependencias (latencia/errores por servicio externo). Fila 4: infra (CPU/mem/replicas/cola profundidad).\nAnnotate deploys (líneas verticales) — el 80% de incidentes arranca 10 min después de un deploy.\nUn dashboard por servicio, linkeado desde el catálogo y las alertas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Oncall: qué debe poder hacer un respondiente SIN conocimiento del código",
   "a": "Ver salud (dashboard), leer qué falló (alerta → runbook), ejecutar runbook (rollback, drain, flag off, escalar cola), ver quién es dueño de dependencias (catálogo), escalar.\nSi requiere 'entrar al código y debuggear en vivo' para mitigar, el servicio no está listo para on-call → más flags de kill, más runbooks, más automatización.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Synthetic monitoring: detectar el problema antes que el usuario",
   "a": "Transacciones sintéticas: script que ejecuta el flujo crítico (login→agregar→checkout) cada 1-5 min desde las regiones de usuarios.\nDetecta: certificados vencidos, DNS roto, degradación regional, flujos que nadie probó tras el deploy.\nAlerta si falla 2 de 3 corridas (evita flapping).\nBarato comparado con un solo SEV1 no detectado.",
   "nivel": "intermedio",
   "clave": false
  }
 ]
}