{
 "subtemas": [],
 "tarjetas": [
  {
   "sub": "Plataforma y despliegue",
   "q": "Estructura de un repo de microservicio (Java/Spring) en 2025",
   "a": "src/main/java (api: controllers/DTOs, domain: entidades+lógica, app: services/casos de uso, infra: repos/config/clients), src/test (unit + integration).\nRoot: Dockerfile (multi-stage), cloudbuild.yaml/.github workflows, openapi.yaml o generado, README + runbook, chart/Terraform, ADRs en docs/.\nConvención > configuración: mismo layout en todos los servicios = onboarding instantáneo.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Pipeline CI/CD de un microservicio: etapas y puertas",
   "a": "PR: compile + unit + lint + contract tests del consumer + build imagen (no deploy) + security scan.\nMerge a main: integration tests (Testcontainers) + push imagen tag SHA + deploy dev automático + smoke + contract verify si soy provider.\nRelease: tag → deploy stage → canary prod con análisis de métricas → 100%.\nTodo falla rápido y es visible en el PR.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Secrets y config por entorno sin duplicar YAML",
   "a": "Base común: application.yml del jar (defaults seguros).\nPor entorno: ConfigMap/Config Server con overrides (solo lo que cambia).\nSecrets: NUNCA en el YAML de entorno — Secret Manager montado/inyectado por el runtime.\nConvención de nombres: SPRING_DATASOURCE_URL etc. — relaxed binding une YAML y env vars.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Versionado de imágenes y trazabilidad de deploy",
   "a": "Tag SIEMPRE con: git SHA (app:9f3c2ab) + semántico opcional (app:2.4.1). Never 'latest' en prod.\nDeployment anotado con SHA, build URL, quién aprobó.\nRollback = redeploy del SHA anterior (imagen inmutable en registry con retention).\nLa pregunta '¿qué versión corre en prod AHORA?' se responde en 5 segundos.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Consumidores de colas: despliegue y compatibilidad",
   "a": "El esquema del mensaje es un contrato: consumer DEBE tolerar campos extra (ignorar desconocidos) y validar lo esencial.\nDeploy de consumer antes que del producer (backward compatible primero).\nDurante un deploy hay 2 versiones consumiendo: una transacción atómica por mensaje + offset/persistencia de posición.\nBlue/green de consumers: nueva versión a grupo separado hasta validar.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Seguridad",
   "q": "Pentest-ready: los checks de seguridad de un microservicio nuevo",
   "a": "Auth en TODOS los endpoints (test que falla sin token), autorización por recurso (user A no lee de user B — IDOR), input validation estricta, rate limits, TLS only, secrets fuera del repo (gitleaks en CI), headers de seguridad en responses, dependencias sin CVEs críticos, logs sin PII.\nChecklist en el template — el auditor lo pedirá igual.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Seguridad",
   "q": "JWT en la práctica: los 5 errores que ves en producción",
   "a": "1) Validar solo firma sin exp/aud/iss. 2) Aceptar alg 'none' o negociado. 3) Secret compartido en N servicios (HS256) sin rotación. 4) Guardar datos sensibles EN el payload (es Base64 legible). 5) Tokens de vida larga sin refresh ni revocación (logout que no desloguea).\nFixes: librería que valide todo, JWKS+RS256, vidas cortas (15-60min) + refresh.",
   "nivel": "intermedio",
   "clave": true
  },
  {
   "sub": "Seguridad",
   "q": "Threat modeling de un flujo de pago en microservicios",
   "a": "Diagrama: app → gateway → pedidos → pagos → banco. Por confianza: ¿puede un usuario repetir un cobro? (idempotency) ¿ver pagos de otro? (authz por recurso) ¿token reusado? (jti/nonce) ¿MITM interno? (mTLS) ¿secret leak? (vault) ¿reply attack del webhook? (firma+timestamp).\nSTRIDE por elemento: spoofing, tampering, repudiation, info disclosure, DoS, elevation.\nSalida: riesgos rankeados + mitigaciones asignadas.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Operación y organización",
   "q": "Cortar un servicio de otro equipo: la transición",
   "a": "1) Catálogo actualiza ownership; 2) transferencia de conocimiento (sesiones + docs), no solo git; 3) nuevo equipo empieza on-call acompañado (shadow 2 semanas); 4) SLOs/runbooks revisados; 5) accesos (IAM, dashboards, repos) migrados; 6) período de hypercare 30 días.\nServicio sin dueño claro en la transición = incidente sin respondiente.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Operación y organización",
   "q": "El costo real de los microservicios (para defender la decisión)",
   "a": "Costos: infra distribuida (más VMs/pods), observabilidad (logging/tracing mensual), plataforma (equipo que la mantiene), latencia de red, complejidad de datos (sagas/CQRS).\nBeneficios: despliegue independiente (time-to-market), escalado selectivo, equipos desacoplados, fallos acotados.\nDecisión honesta: solo si los beneficios pesan para TU escala — 5 devs raramente justifica 30 servicios.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "«¿Un microservicio puede llamar a otro directamente?» — la respuesta completa",
   "a": "Sí, con condiciones: relación cliente-proveedor estable (contract tests), timeouts+breakers (no cascadas), deadline propagado, y control de la cadena (A→B→C→D de más de 2 saltos = smell — usar eventos o agregación).\nProhibido: llamadas circulares (A llama B que llama A).\nAlternativa siempre presente: async por eventos si el llamador no necesita respuesta inmediata.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario: «cada despliegue de X rompe Y» — diagnóstico arquitectónico",
   "a": "Síntoma de acoplamiento: contrato compartido implícito (schema de BD o payload SIN versionar), o dependencia síncrona dura.\nRemedios: contrato explícito + versionado, consumidor tolerante (ignora campos nuevos), migrar la dependencia dura a eventos, y contract testing que ROMPA el CI antes que producción.\nSi persiste: los dos 'servicios' son uno — unificar o cortar bien.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario: «el P99 explotó tras mover a microservicios» — causas top",
   "a": "1) N llamadas encadenadas que antes eran 1 (in-process → network): arreglar con agregación/eventos/caché. 2) Serialización JSON duplicada: protobuf/caché. 3) Timeouts mal puestos que esperan el peor caso. 4) Falta de paralelismo en scatter-gather. 5) Cold calls sin connection pooling.\nMedir con tracing el waterfall — el número indica el tramo culpable, no se adivina.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario: «necesitamos un reporte que cruza 6 servicios» — opciones",
   "a": "Malo: API composition en vivo (lento y frágil para analítica).\nBueno: read model analítico — eventos de los 6 servicios → warehouse (BigQuery) → reporte/dashboards con datos de minutos de antigüedad.\nOperativo-urgente: materialized view alimentada por CDC.\nLa regla: analítica NO cruza servicios en vivo; se replica con propósito.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario: «dos equipos editan el mismo servicio» — soluciones",
   "a": "Corto plazo: separar módulos claros + CODEOWNERS + checks de fronteras (ArchUnit).\nMediano: extraer lo que el segundo equipo necesita a SU servicio (el motivo de roce indica frontera mal puesta).\nAlternativa: módulos internos deployables (modulith) con releases independientes.\nEl roce recurrente entre equipos es LA señal clásica para dividir.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario: «migrar 200 endpoints del monolito» — priorización",
   "a": "Por valor/riesgo: 1) primero casos de uso AUTOCONTENIDOS y de alto cambio (más beneficio, menos riesgo). 2) Frontend en momentos de pico (escala distinta). 3) Rutas write-heavy con necesidades de escala. 4) Lo último: núcleo transaccional entrelazado.\nNunca empezar por lo más difícil para 'demostrar valor' — empieza por lo que libera velocidad al negocio.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Escenario: «el consumidor necesita datos de 3 eventos para actuar» — patrón",
   "a": "Problema: eventos llegan desordenados/parciales.\nOpciones: 1) event-carried state (cada evento trae snapshot completo del agregado — consumidor siempre tiene lo último). 2) consumidor mantiene estado incremental y actúa cuando la clave está completa. 3) orquestador que consulta APIs al trigger.\nPreferir 1: elimina dependencia de orden entre eventos distintos.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Escenario: «la cola crece sin parar en Black Friday» — playbook",
   "a": "1) Confirmar: es lag del consumidor o throughput del productor legítimo.\n2) Escalar horizontal consumidores (KEDA por lag).\n3) Bajar trabajo por mensaje (batching), subir paralelismo por partición.\n4) Shedding: degradar trabajo no crítico (deferir emails).\n5) Si los datos lo toleran: ralentizar productores (429) — el usuario entiende 'lento' mejor que 'perdido'.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Escenario: «el gateway es un SPOF» — diseños alternativos",
   "a": "Múltiples instancias del gateway detrás de un LB anycast ( nunca 1 pod).\nDos gateways con rutas distintas (uno para APIs públicas, otro interno) — blast radius.\nDNS failover entre regiones con gateway regional + LB global.\nCliente con reintentos + caché de descubrimiento si el gateway cae.\nEl gateway puede degradar, no puede desaparecer: capacidad N+1 siempre.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Escenario: «la BD del catálogo se cae 30s cada hora» — diseño defensivo",
   "a": "Buscar causa raíz paralela (failover? OOM? migraciones?). Mientras tanto, aislar: caché de catálogo con serve-stale (TTL largo), breaker + fallback a catálogo embebido/mínimo, retry con backoff en lecturas.\nLa app NO debe caerse por una BD de LECTURA: degradar el módulo, no el servicio.\nPost-mortem: la degradación es permanente hasta arreglar la causa.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Escenario: «un cliente abuse 10x su cuota» — protección progresiva",
   "a": "Capa 1: rate limit por API key (429 rápido y barato).\nCapa 2: detección de patrón (abuse score) → degradación (menor prioridad de procesamiento, no bloqueo).\nCapa 3: política comercial (contactar, cobrar tier superior).\nLogs de abuso como evidencia. NUNCA bloqueos manuales 'a mano' — reglas versionadas y auditadas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Escenario: «usuarios reportan errores que nuestras métricas no ven» — dónde mirar",
   "a": "1) El path roto puede no estar instrumentado (endpoint nuevo sin métricas).\n2) Falla en el cliente/borde (CDN, DNS, certificado) antes de llegar.\n3) Sample del tracing esconde el caso (tail sampling sin regla de ese endpoint).\n4) Errores de negocio (HTTP 200 con lógica fallida — metrics de códigos no captan).\nFix: RUM + synthetic del flujo reportado + log con código de negocio.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Escenario: «regulatorio exige saber dónde vive cada dato» — mapa de datos",
   "a": "Inventario por servicio: qué datos personales procesa, en qué almacenes (SQL, Redis, logs, colas, backups), regiones.\nHerramientas: DLP scan sobre almacenes + catálogo con clasificación por servicio.\nControles: residency por región, retención automática, borrado trazable (right to erfection como job auditable).\nSe demuestra con evidencia, no con promesas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Testing y calidad",
   "q": "Escenario: «la suite de integración tarda 40 minutos» — plan de reducción",
   "a": "1) Medir: qué tests son lentos y por qué (startup de contexto, BD, sleeps).\n2) Slices sobre @SpringBootTest (WebMvcTest/DataJpaTest) donde no se necesita todo.\n3) Contenedores singleton + reutilización, datos mínimos por test.\n4) Parallelización con fuentes de datos aisladas.\n5) Sleeps → Awaitility; contextos duplicados → unificar configuración de test (cache de contexto).",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Testing y calidad",
   "q": "Escenario: «no podemos probar el flujo completo antes de producción»",
   "a": "Realidad de microservicios: el 'ambiente completo' es una ilusión costosa.\nSustitutos: contract tests por par (cada dependencia verificada localmente), staging con stubs de terceros + servicios reales clave, canary/shadow en prod como validación final con reversión automática.\nEl entorno de integración compartido eterno se sustituye por confianza CONTRACTUAL verificada por máquinas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Escenario: «deploy requiere 15 pasos manuales» — automatización mínima viable",
   "a": "Semana 1: script único (deploy.sh) con los pasos — ya elimina error humano.\nSemana 2: mismo script en CI con parámetros entorno/versión.\nLuego: gates (tests, aprobación) en el pipeline, rollback automático en fallo de smoke.\nLa automatización incremental vale más que esperar la plataforma perfecta.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Plataforma y despliegue",
   "q": "Escenario: «el mismo config en 5 servicios se desincroniza» — arquitectura de config compartida",
   "a": "Propiedad compartida → biblioteca común de config (starter propio con defaults) o config central con herencia (defaults org + override por servicio).\nCambios auditados en un solo repo; versiones de la librería pinneadas.\nConfig runtime compartida (timeouts de plataforma) via config server/ConfigMap común referenciado.\nAnti-patrón: copiar-pegar la misma propiedad en 5 YAMLs.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Operación y organización",
   "q": "Escenario: «presupuesto de observabilidad disparado» — optimización",
   "a": "Logging: exclusion sinks de ruido, sampling de successes, retención escalonada (hot 7d, archivo GCS).\nTracing: bajar head sampling, tail solo errores/lentos.\nMétricas: matar series de alta cardinalidad (top offender report).\nCada optimización con validación: '¿siguió detectándose el incidente X?' — la observabilidad no se recorta a ciego.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Escenario final: «convence al CTO (en contra) de microservicios»",
   "a": "Presenta AMBOS lados: costo real (plataforma, on-call, latencia, complejidad de datos) vs beneficio (velocity de equipos, escala, resiliencia).\nPropón el camino intermedio: monolito modular ahora, fronteras por DDD, extracción por señales concretas (escala/equipos).\nMuestra métricas: DORA actuales y objetivo.\nEl arquitecto senior no vende microservicios: vende el diseño que RESUELVE el problema de la organización.",
   "nivel": "intermedio",
   "clave": false
  }
 ]
}