{
 "subtemas": [
  "Fundamentos y decisiones",
  "Comunicación",
  "Datos y consistencia",
  "Resiliencia",
  "Observabilidad",
  "APIs y edge",
  "Seguridad",
  "Plataforma y despliegue",
  "Testing y calidad",
  "Operación y organización"
 ],
 "sub_old": {
  "M01": "Fundamentos y decisiones",
  "M02": "Fundamentos y decisiones",
  "M03": "Comunicación",
  "M04": "Comunicación",
  "M05": "APIs y edge",
  "M06": "Comunicación",
  "M07": "Resiliencia",
  "M08": "Datos y consistencia",
  "M09": "Datos y consistencia",
  "M10": "Datos y consistencia",
  "M11": "Datos y consistencia",
  "M12": "Datos y consistencia",
  "M13": "Datos y consistencia",
  "M14": "Plataforma y despliegue",
  "M15": "Observabilidad",
  "M16": "Observabilidad",
  "M17": "Plataforma y despliegue",
  "M18": "Plataforma y despliegue",
  "M19": "Fundamentos y decisiones",
  "M20": "APIs y edge"
 },
 "tarjetas": [
  {
   "sub": "Fundamentos y decisiones",
   "q": "¿Qué NO es un microservicio? (desmontando mitos)",
   "a": "NO es: un endpoint suelto (eso es una función), un CRUD con su propia BD compartida, un módulo desplegado aparte que necesita despliegues sincronizados, 'código más chico' por defecto.\nES: un servicio con negocio encapsulado, datos propios y despliegue independiente.\nEl tamaño correcto = cabe en un equipo y cambia por razones propias.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Señales de que NO deberías usar microservicios",
   "a": "Equipo pequeño (1-5 devs), dominio sin explorar (no sabes los bounded contexts), startup buscando product-market fit, operaciones sin madurez (sin CI/CD, monitoreo, on-call).\nAlternativa: MONOLITO MODULAR (módulos con fronteras claras, un despliegue) — migrar a micros después es más fácil que deshacer micros mal cortados.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Monolito modular: el paso intermedio que casi nadie hace",
   "a": "Un deployable, pero módulos con fronteras ENFORZADAS: paquetes cerrados, ArchUnit/Module checks, interfaces internas, BD con esquemas por módulo (sin joins cruzados).\nBeneficio: la simplicidad del monolito + la disciplina de fronteras → extraer micros después es mecánico.\nEs la recomendación default de Martin Fowler ('MonolithFirst').",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Ley de Conway aplicada: tu arquitectura imita tu organización",
   "a": "Los sistemas reflejan los canales de comunicación de los equipos que los construyen.\nQuieres microservicios por dominio? Organiza equipos por dominio (Team Topologies: stream-aligned teams con su servicio end-to-end).\nSi 5 equipos tocan el mismo servicio, no importa cómo lo dividas: será un monolito distribuido.\nConway's Law inversa: organiza como quieres que sea la arquitectura.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Event Storming: qué es y qué produce",
   "a": "Taller de discovery (Big Picture): pegas eventos de dominio en naranja en una pared (PedidoCreado, PagoConfirmado), luego actores, comandos, políticas, bounded contexts emergen visualmente.\nProduce: modelo del dominio compartido, candidatos a microservicios (contextos), lenguaje común.\nBarato y rápido comparado con descubrir el dominio en producción.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Agregados DDD: la unidad de consistencia",
   "a": "Un agregado agrupa entidades bajo una raíz que protege INVARIANTES (Pedido con sus Items: total = suma de items).\nReglas: referencia otros agregados por ID (no por objeto), una transacción modifica UN agregado, eventos publicados al cambiar.\nMicroservicio ≠ agregado, pero los agregados guían qué va junto y qué se comunica por eventos.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Context Mapping: relaciones entre bounded contexts",
   "a": "Shared Kernel (código común), Customer/Supplier (aguas arriba atiende al downstream), Conformist (aceptas el modelo del otro), Anticorruption Layer (traduces su modelo al tuyo — para sistemas legados/externos), Open Host Service + Published Language (tu API es el estándar).\nDecide por relación de poder y estabilidad del otro contexto.",
   "nivel": "avanzado",
   "clave": true
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Strangler Fig: migrar el monolito sin big bang",
   "a": "El gateway enruta: nuevas capacidades van a servicios NUEVOS; el monolito sigue sirviendo lo demás; cada ruta migrada se 'estrangula' del monolito hasta que muere.\nPasos: 1) gateway delante, 2) extraer funcionalidad + datos (CDC para sincronizar), 3) mover ruta, 4) repetir.\nNunca freeze del monolito: sigue evolucionando durante la migración.",
   "nivel": "intermedio",
   "clave": true
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Distributed monolith: los síntomas del fracaso",
   "a": "Desplegar un servicio requiere desplegar 5 (release trains), cambios que cruzan varios repos, servicios sin datos propios (todos contra la misma BD), latencias encadenadas para una operación simple, un fallo tira todo.\nCausa raíz: cortaste por CAPAS TÉCNICAS (frontend-service-dao) o por conveniencia, no por dominio.\nRemedio: re-cortar contextos, o retroceder a monolito modular.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Hexagonal/Ports & Adapters dentro de un microservicio",
   "a": "Dominio en el centro (entidades, reglas) SIN dependencias de Spring/JPA/HTTP.\nPuertos: interfaces que el dominio define (RepositoryPort, NotificationPort).\nAdapters: implementaciones de infraestructura (JpaAdapter, KafkaAdapter, RestController).\nBeneficio: dominio testeable sin levantar nada, swap de infraestructura, y la prueba de que tu lógica no está en los adapters.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "ADR: Architecture Decision Records",
   "a": "Documento corto por decisión: contexto, opciones consideradas, decisión, consecuencias (positivas y negativas), fecha y estado.\nVersionado en el repo del servicio.\nValor: 6 meses después, '¿por qué usamos Saga orquestada y no coreografiada?' tiene respuesta escrita, no arqueología de Slack.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Service ownership: qué significa end-to-end",
   "a": "El equipo que construye el servicio lo OPERA: on-call, SLOs, costos, deprecación — 'you build it, you run it'.\nHerramientas: catálogo de servicios (Backstage), runbooks, dashboards por servicio.\nAnti-patrón: equipo de 'deploy' separado que recibe tickets de otros equipos para publicar.\nMétricas DORA para medir la salud de la entrega.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Métricas DORA: las 4 que miden entrega de software",
   "a": "Deployment frequency (cada cuánto despliegas), Lead time for changes (commit→prod), Change failure rate (% de deploys que causan incidente), MTTR (tiempo para recuperar).\nElite: deploy diario+, lead time <1 día, CFR <15%, MTTR <1 hora.\nLos microservicios bien hechos mueven estas 4; mal hechos las empeoran (medir antes/después).",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "¿Cuántos microservicios son demasiados?",
   "a": "Señales de exceso: nanoservicios CRUD que solo reenvían llamadas, servicios que SIEMPRE se despliegan juntos, equipos dedicados a 'concatenar' otros servicios, latencia por saltos que domina el P99.\nRegla empírica: 1 equipo (5-9 personas) = 1-3 servicios que posee end-to-end.\nConsolidar es una decisión arquitectónica tan legítima como dividir.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "C4 model: documentar arquitectura en 4 niveles",
   "a": "Context (tu sistema + usuarios + sistemas externos), Containers (apps/servicios y sus tecnologías), Components (módulos dentro de un container), Code (clases — opcional).\nDiagramas como código (PlantUML/Structurizr) versionados con ADRs.\nEvita el diagrama PowerPoint de hace 2 años: C4 + CI mantiene docs vivas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "API-first: qué significa de verdad",
   "a": "El CONTRATO (OpenAPI/Proto) se diseña, revisa y aprueba ANTES del código — consumidores (frontend, otros equipos) empiezan en paralelo con mocks.\nValidación: spec lint (Spectral), mock server, contract tests.\nBeneficio: cambios caros se discuten en diseño, no en integración.\nHerramientas: OpenAPI Generator, Prism, Spectral rules.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Domain services vs application services",
   "a": "Domain service: lógica de negocio que no pertenece a un solo agregado (calcularTarifa(remate, destino)).\nApplication service: orquesta CASO DE USO — carga agregados, llama dominio, persiste, publica eventos, maneja tx (el 'service' de Spring suele ser esto).\nConfundirlos = lógica de negocio fugándose a capas técnicas (anemia).",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Anticorruption Layer: cuándo y cómo",
   "a": "Cuando consumiste un sistema EXTERNO con modelo ajeno/feo (ERP legado, API de tercero): capa que traduce su modelo al tuyo en la FRONTERA (adapter + translator).\nSin ACL: el modelo del ERP (campos raros, estados en mayúsculas) se contagia a todo tu dominio.\nCosto: más código; valor: tu dominio queda limpio y el swap del externo es local.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "¿Qué es un 'golden path' / platform engineering?",
   "a": "Plataforma interna que da a los equipos el camino pavimentado: template de servicio (CI/CD, observabilidad, seguridad incluidos), catálogo, infraestructura self-service.\nEl equipo de producto codifica negocio, no YAML.\nMedida del éxito: tiempo de 'idea a producción' de un nuevo servicio en días, no semanas.\nAntipatrón: plataforma obligatoria sin feedback de los equipos.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Cuándo EXTRAER un servicio del monolito: señales concretas",
   "a": "1) Un módulo escala de forma diferente (picos aislados).\n2) Ritmos de release chocan (equipo X frena a Y).\n3) Tecnología distinta necesaria (ML en Python, streaming).\n4) Compliance aísla datos.\nNO extraer por: 'está feo el código' (refactor), moda, o porque el dominio no está claro.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Fundamentos y decisiones",
   "q": "Product over project: el cambio de mentalidad",
   "a": "Proyecto: equipo se arma, entrega, se desarma → el servicio queda huérfano.\nProducto: equipo estable posee el servicio y su roadmap continuo.\nEn microservicios es crítico: cada servicio necesita dueño permanente (on-call, SLOs, evolución).\nSi tu organización solo sabe hacer proyectos, microservicios producirán servicios abandonados.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Event notification vs event-carried state transfer",
   "a": "Notification: 'pasó X, id=42' — el consumidor debe llamar de vuelta para datos (acoplamiento a tu API, riesgo de N+1 remoto).\nEvent-carried state: el evento TRAE los datos necesarios (PedidoCreado con items y cliente) — consumidor construye su vista sin llamarte (desacoplado, datos posiblemente viejos).\nRegla: notificación mínima + API para detalles, o state transfer si el consumidor es estable.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Request-reply sobre mensajería: cómo y cuándo",
   "a": "Necesitas respuesta async: publicas comando con reply_to + correlation_id; el responder publica la respuesta al topic de reply; el cliente correlaciona por id.\nCasos: backend-for-backend async donde sync acoplaría.\nComplejidad: timeouts, polling de respuesta, dos colas.\nSi puedes, REST/gRPC directo es más simple — async-reply solo con justificación.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Deadlines y presupuesto de latencia en cascadas de servicios",
   "a": "Cada servicio tiene un presupuesto del tiempo total: A(50ms) llama B(200ms) que llama C(150ms)...\nPropagar deadline: si a A le quedan 80ms y B necesita 200, B ni intenta (fail fast) — header de deadline (gRPC lo trae nativo).\nSin deadlines, los reintentos amplifican la latencia (retry storm) y el P99 explota.\nMedir por tramo con tracing.",
   "nivel": "intermedio",
   "clave": true
  },
  {
   "sub": "Comunicación",
   "q": "Schema evolution: compatibilidad forward y backward",
   "a": "Backward: schema NUEVO lee datos VIEJOS (añadir campo con default — seguro). Forward: schema viejo lee datos nuevos (no romper al añadir).\nFull compatibility: ambos.\nReglas prácticas: no renombrar (añadir + deprecar), no cambiar tipos, campos nuevos OPCIONALES.\nProtobuf/Avro + schema registry validan en CI.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "JSON vs Avro vs Protobuf para mensajería",
   "a": "JSON: legible, universal, verbose, sin schema fuerte (JSON Schema opcional).\nProtobuf: binario compacto, tipado, código generado, requiere .proto compartido — el estándar gRPC.\nAvro: binario + schema en registry, evolución sofisticada — estándar Kafka.\nDecisión: ecosistema (gRPC→protobuf), herramientas y habilidad del equipo pesan más que benchmarks.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Consumer groups y particiones (Kafka): cómo escala un topic",
   "a": "Topic dividido en N particiones (orden SOLO dentro de partición, por key).\nConsumer group: cada partición se asigna a UN consumidor del grupo → paralelismo máx = #particiones.\nRebalanceo cuando entran/salen consumidores (pausa breve).\nOffsets: posición por consumidor, commiteada — replay posible re-seateando.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Idempotent producer y transacciones en Kafka",
   "a": "Idempotent producer: enable.idempotence=true → broker deduplica reintentos por (PID, secuencia) — exactamente-once POR PARTIÓN en escritura.\nTransacciones: escribir a varias particiones + offset commit atómicamente (consume-transform-produce) — exactly-once end-to-end del pipeline.\nCosto: throughput algo menor, complejidad de aislamiento (read_committed).",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Backpressure en sistemas de mensajería: quién frena",
   "a": "Productor más rápido que consumidor = colas creciendo sin fin (latencia + OOM).\nEstrategias: colas con límite (reject/persist en DLQ), consumer escala horizontal (KEDA por lag), batching del consumidor, y si el origen puede frenarse: HTTP 429 backpressure real.\nMonitoreo clave: consumer lag — el indicador de salud #1 de un pipeline async.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Retry amplification: cómo los reintentos escalan una caída",
   "a": "A reintenta a B 3 veces; B reintenta a C 3 veces → un clic del usuario = 27 llamadas a C. Servicio caído recibe 27x carga = nunca se recupera.\nDefensas: retry budget global (máx % de tráfico como retry), solo reintentar en el borde, circuit breakers que cortan reintentos, deadlines que acaban cadenas.\nRegla: reintentar en UNA capa, no en todas.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Fan-out y scatter-gather: patrones de agregación",
   "a": "Fan-out simple: publicar a topic, N suscriptores actúan independientes.\nScatter-gather: llamar a N servicios en PARALELO y combinar respuestas (búsqueda que consulta inventario+precios+envío) — con timeout por rama y degradación parcial (mostrar lo que respondió).\nHerramientas: CompletableFuture.allOf, orquestadores (Workflows), GraphQL.\nRiesgo: latencia del más lento → bulkheads por rama.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Comunicación",
   "q": "Correlation ID vs message ID vs causation ID",
   "a": "Message ID: identidad ÚNICA del mensaje (dedup).\nCorrelation ID: agrupa toda una petición de negocio end-to-end (tracing).\nCausation ID: qué mensaje PRECISO provocó este (cadena de eventos: PedidoCreado causa EmailEnviado).\nEn headers/wrapper CloudEvents: id, correlationid, causationid — logs y trazas se vuelven navegables.",
   "nivel": "intermedio",
   "clave": false
  }
 ]
}