Respuesta A: Anthropic Claude Opus 4.7
# Plan de Diseño del Sistema Escalable de Reservas de Entradas para Conciertos ## 1. Supuestos - Región única en la nube (p. ej., AWS us-east-1) con 3 Zonas de Disponibilidad (AZ); se prefieren servicios administrados. - El catálogo (eventos, recintos, mapas de asientos) es de lectura intensiva y cambia con poca frecuencia. - Las reservas son la ruta crítica; los pagos se realizan fuera de la ruta crítica a través de devoluciones de llamada asíncronas. - "Nunca vender de más" es un invariante estricto; se prefiere una indisponibilidad breve a la doble venta. - Un proveedor de pagos externo (p. ej., Stripe/Adyen)...
Mostrar respuesta completa ▼
# Plan de Diseño del Sistema Escalable de Reservas de Entradas para Conciertos ## 1. Supuestos - Región única en la nube (p. ej., AWS us-east-1) con 3 Zonas de Disponibilidad (AZ); se prefieren servicios administrados. - El catálogo (eventos, recintos, mapas de asientos) es de lectura intensiva y cambia con poca frecuencia. - Las reservas son la ruta crítica; los pagos se realizan fuera de la ruta crítica a través de devoluciones de llamada asíncronas. - "Nunca vender de más" es un invariante estricto; se prefiere una indisponibilidad breve a la doble venta. - Un proveedor de pagos externo (p. ej., Stripe/Adyen) maneja el alcance PCI; solo almacenamos tokens. - Tamaño promedio de evento 30k asientos; el pico dura minutos a ~1 hora. ## 2. Arquitectura de Alto Nivel Clientes (web/móvil) → CDN (CloudFront) → API Gateway / Balanceador de Carga L7 → Autenticación de borde (JWT) → Microservicios sin estado en Kubernetes (EKS) a través de 3 AZs. Servicios principales: - **Servicio de Identidad**: registro, inicio de sesión, emisión de JWT, MFA. - **Servicio de Catálogo**: metadatos de eventos, recintos, mapas de asientos; optimizado para lectura. - **Servicio de Inventario/Asientos**: estado de asientos autoritativo, retenciones, reservas; el ancla de consistencia. - **Servicio de Reservas**: orquesta la retención → pago → intención de pago. - **Servicio de Pagos**: se integra con el proveedor, procesa devoluciones de llamada de webhook de forma idempotente. - **Servicio de Entradas**: emite entradas digitales firmadas (JWT/QR) tras el éxito del pago. - **Servicio de Notificaciones**: correo electrónico/push (SES/SNS). - **Servicio de Sala de Espera / Cola Virtual**: limita la entrada durante los picos de venta. - **Worker de Expiración**: libera retenciones no pagadas después de 10 minutos. - **Servicio de Administración/Venta**: configuración de eventos, carga de mapas de asientos, programación de ventas. Transversales: Kafka (MSK) para eventos, Redis (ElastiCache, modo clúster) para estado en caliente y bloqueos, PostgreSQL (Aurora Multi-AZ) para datos transaccionales, DynamoDB para claves de idempotencia y almacenamiento de entradas, S3 para JSON/imágenes de mapas de asientos, OpenSearch para búsqueda de eventos. ## 3. Almacenes de Datos - **Aurora PostgreSQL (Multi-AZ, 1 escritor + 2 lectores)**: eventos, usuarios, reservas, pagos, entradas (sistema de registro). Copia de seguridad continua; PITR. - **Clúster Redis (Multi-AZ, con réplicas)**: estado de retención por asiento, caché de mapa de bits de asientos por evento, límites de tasa, tokens de sala de espera. Se utiliza para CAS rápido en retenciones. - **DynamoDB**: claves de idempotencia de pago, deduplicación de webhooks, búsqueda de entradas emitidas (baja latencia, multi-AZ por defecto). - **Kafka (MSK)**: eventos de dominio (`SeatHeld`, `ReservationCreated`, `PaymentSucceeded`, `PaymentFailed`, `ReservationExpired`, `TicketIssued`). Factor de replicación 3 entre AZs. - **S3**: artefactos estáticos de mapas de asientos, PDFs de entradas. - **CDN**: almacena en caché listados de eventos, esqueleto de mapa de asientos (no disponibilidad en vivo). - **OpenSearch**: búsqueda/filtrado de eventos. ## 4. Modelo de Datos Principal **eventos**(event_id PK, venue_id, name, onsale_at, status, version). **asientos**(seat_id PK, event_id, section, row, number, price_tier, status ENUM[available, held, reserved, sold], hold_id NULL, version BIGINT). Índice compuesto (event_id, status). Versionado a nivel de fila para bloqueo optimista. **reservas**(reservation_id PK, user_id, event_id, seat_ids[], state ENUM[pending_payment, confirmed, expired, cancelled], created_at, expires_at, payment_intent_id, idempotency_key UNIQUE). **pagos**(payment_id PK, reservation_id, provider_ref UNIQUE, status, amount, currency, received_at). Restricción única en provider_ref para deduplicación al menos una vez. **entradas**(ticket_id PK, reservation_id, seat_id, qr_payload, issued_at, signature). **outbox**(id, aggregate, payload, published_at) para patrón outbox transaccional → Kafka. Claves de Redis: - `event:{id}:seat:{seat_id}` → estado + propietario de la retención + TTL 600s. - `event:{id}:availability` → bitmap/HLL para recuentos rápidos. - `hold:{reservation_id}` → lista de asientos, TTL 600s. ## 5. APIs Principales (REST + encabezados de idempotencia) - `GET /events?filters` → lista paginada (en caché por CDN, TTL de 30s). - `GET /events/{id}` → detalles del evento. - `GET /events/{id}/seatmap` → diseño estático (caché larga). - `GET /events/{id}/availability` → disponibilidad general (secciones); caché de 1–5s. - `GET /events/{id}/seats?section=A` → estado detallado de asientos (caché corta o en vivo). - `POST /reservations` (Idempotency-Key) → `{event_id, seat_ids[]}` → crea retención de 10 minutos. - `GET /reservations/{id}` → estado, expires_at. - `DELETE /reservations/{id}` → el usuario cancela, libera asientos. - `POST /reservations/{id}/checkout` → crea intención de pago en el proveedor, devuelve clave secreta del cliente. - `POST /webhooks/payments` → devolución de llamada del proveedor (firmada, idempotente). - `GET /tickets/{id}` → entrada digital firmada. - Administración: `POST /events`, `POST /events/{id}/seats:bulk`, `POST /events/{id}/onsale`. ## 6. Flujos de Solicitud ### Navegación Cliente → CDN (acierto para catálogo/mapa de asientos) → en caso de fallo, API → Servicio de Catálogo → Lector de Aurora / OpenSearch. Los recuentos de disponibilidad se sirven desde Redis con 1–5s de desactualización; los estados de asientos individuales se extraen en vivo para la sección que el usuario está viendo. ### Reserva (retención) 1. El cliente envía `POST /reservations` con Idempotency-Key y asientos objetivo. 2. API Gateway verifica el token de la sala de espera; limita la tasa por usuario/IP. 3. El Servicio de Reservas valida el estado del evento y los IDs de los asientos. 4. **Adquirir retenciones atómicamente** a través del script Lua de Redis: para cada clave de asiento, `SETNX` con hold_id y TTL 600s; si algún asiento falla, revierte los exitosos y devuelve 409 con los asientos en conflicto. 5. Persistir la fila de reserva en Aurora en estado `pending_payment` (transacción única con evento outbox). Utilizar bloqueo optimista en los asientos: `UPDATE seats SET status='held', hold_id=?, version=version+1 WHERE seat_id=? AND status='available'`. Aurora es la verdad duradera; Redis es el guardián rápido. Ambos deben estar de acuerdo. 6. Devolver la reserva con `expires_at`. p95 < 800 ms. ### Pago 1. El cliente llama a `POST /reservations/{id}/checkout`; el Servicio de Pagos crea un PaymentIntent en el proveedor, almacena `provider_ref` indexado por reservation_id (idempotente). 2. El cliente completa el pago a través del SDK del proveedor directamente (nos mantenemos fuera del alcance PCI). 3. El proveedor envía webhook → `POST /webhooks/payments`. 4. Manejador de Webhook: verificar firma → insertar/actualizar en `pagos` usando `provider_ref` UNIQUE (deduplicación). Usar escritura condicional de DynamoDB en event_id para idempotencia adicional. 5. En `succeeded`: actualización transaccional — reserva→`confirmed`, asientos→`sold`, escribir `tickets`, añadir evento outbox `TicketIssued`. Seguridad contra desorden: el manejador compara las marcas de tiempo de los eventos e ignora las transiciones obsoletas (máquina de estados: pending → confirmed/failed/expired, los estados terminales absorben duplicados tardíos). 6. El Servicio de Entradas consume `TicketIssued`, genera QR/PDF firmado, almacena en S3 + DynamoDB; el Servicio de Notificaciones envía correo electrónico al usuario. ### Expiración - Principal: el TTL de Redis expira la clave `hold:*` → la notificación de keyspace activa el worker de expiración; el worker ejecuta la transacción de Aurora liberando asientos solo si la reserva sigue `pending_payment` (CAS en el estado). - Respaldo: trabajo programado cada 30s escanea `reservas WHERE state='pending_payment' AND expires_at < now() - 30s` y libera. Devolución de llamada tardía que llega después de la expiración: si el asiento ya se revendió, marcar el pago como `refund_required` y activar el reembolso automático; si el asiento sigue libre, opcionalmente reconfirmar — pero la política predeterminada es el reembolso, porque no podemos volver a retener un asiento posiblemente revendido. El retraso de 5 minutos del proveedor de pagos está dentro de la ventana de retención de 10 minutos, por lo que el caso normal no tiene conflicto. ## 7. Prevención de Venta Excesiva (Consistencia) - El asiento es un recurso único y poseído: cada transición de estado utiliza **concurrencia optimista** en Aurora (`WHERE status=expected_status AND version=expected_version`). - Redis SETNX proporciona rechazo rápido de primera línea a 8k RPS sin sobrecargar la base de datos; la actualización de fila de Aurora es la segunda línea y la verdad legal. - Todas las escrituras del lado del pago son idempotentes a través de la unicidad de `provider_ref` + tabla de deduplicación de DynamoDB. - El patrón Outbox garantiza que los eventos de dominio se publiquen exactamente una vez en Kafka en relación con los commits de la base de datos. - Fuerte consistencia dentro de una sola fila de asiento; la consistencia eventual es aceptable solo para los recuentos de disponibilidad agregados que se muestran en las vistas de navegación. ## 8. Estrategia de Escalado para Picos - **Sala de espera virtual**: cuando `concurrent_users > threshold`, los nuevos usuarios obtienen un token de cola; solo se admiten N tokens/segundo a los puntos finales de reserva. Mantiene el sistema a una capacidad conocida (p. ej., admitir 10k/segundo para absorber 8k intentos de reserva/segundo). - **Escalado automático horizontal** (HPA en EKS) en métricas de CPU y RPS personalizadas; precalentar pods 15 minutos antes de las ventas anunciadas. - **Particionamiento de eventos calientes**: particionar claves de Redis por `event_id` para que un mega-evento único aterrice en un shard dedicado; se pueden preaprovisionar shards para ventas conocidas. - **Escalado de lectura**: réplicas de lectura de Aurora + Redis para disponibilidad + CDN para datos estáticos del mapa de asientos. - **Contrapresión**: cuotas de solicitud de API Gateway por usuario; 429 con Retry-After. - **Abanico asíncrono**: Kafka desacopla la generación de entradas, el correo electrónico y la analítica de la ruta crítica. - **Agrupación de conexiones**: RDS Proxy / PgBouncer para evitar tormentas de conexiones de Aurora. - **Defensa contra bots**: WAF, CAPTCHA en `POST /reservations` durante las ventas, huella digital del dispositivo. ## 9. Fiabilidad y Recuperación ante Desastres - Multi-AZ para cada componente con estado (Aurora, Redis con réplicas + conmutación por error automática, MSK RF=3, DynamoDB). - Aurora: copia de seguridad continua a S3, PITR a cualquier segundo dentro de la retención → RPO ≤ 1 min cumplido; conmutación por error ~30–60s → RTO ≤ 15 min cumplido. - Redis: Multi-AZ con conmutación por error automática; los datos se pueden reconstruir desde Aurora (las retenciones se pueden reconstruir en un inicio en frío desde `reservas WHERE state='pending_payment'`). - Kafka: almacenamiento por niveles, RF=3, min ISR=2. - Ejecución de DR: réplica de base de datos global de Aurora entre regiones (RPO ~ segundos) para recuperación ante fallos en toda la región; procedimiento de promoción documentado. - Simulacros de caos: apagón de AZ, eliminación del primario de Redis, simulación de interrupción del proveedor de pagos trimestralmente. - Comprobaciones de estado a nivel de ALB; disyuntores (similares a Resilience4j) entre servicios y hacia el proveedor de pagos. - Degradación elegante: si Redis no está disponible, recurrir a la ruta solo de base de datos con límite de tasa más estricto; si el proveedor de pagos está caído, poner en cola los pagos y notificar al usuario. ## 10. Monitorización y Alertas - **Métricas (Prometheus + CloudWatch)**: RPS, latencia p50/p95/p99 por punto final, tasa de éxito de reservas, tasa de conflicto de adquisición de retenciones, retraso del webhook de pago, retraso del worker de expiración, retraso de la réplica de Aurora, CPU/memoria/evicciones de Redis, retraso del consumidor de Kafka. - **SLOs**: disponibilidad del 99.95% en la ventana de venta; navegación p95 < 300 ms; reserva p95 < 800 ms; alertas de quema de presupuesto de error. - **Trazado**: OpenTelemetry de extremo a extremo (cliente → API → servicio → DB). - **Registros**: JSON estructurado a CloudWatch/Elastic; IDs de correlación. - **Paneles de control de negocio**: retenciones/seg, conversión (retención→pago), contador de venta excesiva (debe ser 0 — alerta ante cualquier valor no cero). - **Alertas**: violación de venta excesiva=0 (P0), cola de webhooks > 1 min, reserva p95 > 800 ms durante 5 min, conmutación por error de Aurora, conmutación por error de Redis, caída de la tasa de éxito de pagos > 2σ. ## 11. Compromisos y Alternativas Clave - **Redis como autoridad de retención vs. solo base de datos**: el enfoque de base de datos puro es más simple y más fuerte, pero no pudo mantener 8k RPS en puntos calientes de fila única; Redis en el front absorbe el pico, la actualización de fila de Aurora garantiza la corrección. - **Bloqueos pesimistas (SELECT FOR UPDATE)**: considerado; rechazado porque la contención de bloqueos en secciones populares reduciría drásticamente el rendimiento. El bloqueo optimista con reintentos escala mejor. - **Asientos reservados vs. contador de admisión general**: el diseño anterior es por asiento. Para admisión general, se utiliza un contador único que decrementa (`DECR` en Redis con un mínimo de 0, reflejado en la base de datos) en su lugar. - **Región única vs. región activa-activa**: la restricción dice una región. Activa-activa complicaría "nunca vender de más" (se necesita consenso entre regiones). Usamos réplica de lectura entre regiones solo para DR. - **Kafka vs. SQS**: Kafka elegido por su registro de eventos ordenado y reproducible (ayuda con el procesamiento de pagos desordenados y la reconstrucción del estado). - **Pago síncrono vs. solo webhook**: se eligió solo webhook para mantener la ligereza PCI y tolerar la latencia del proveedor; los retrasos de webhook de hasta 5 minutos aún caben dentro de la retención de 10 minutos. - **Sala de espera vs. escalado automático puro**: el escalado automático por sí solo no puede proteger los almacenes con estado posteriores; la cola proporciona una forma de carga determinista y una mejor experiencia de usuario que los 503 masivos. - **Emisión de entradas síncrona vs. asíncrona**: asíncrona a través de Kafka mantiene el manejador de devolución de llamada de pago rápido y resiliente; el usuario ve la entrada en segundos a través de push/actualización. Este diseño cumple con los SLOs declarados, previene la venta excesiva a través de concurrencia optimista en capas, absorbe los picos de venta a través de la cola virtual + retenciones con front de Redis, y satisface los objetivos de RPO/RTO a través de tiendas administradas Multi-AZ con PITR y conmutación por error ensayada.
Resultado
Votos ganadores
3 / 3
Puntuacion media
Puntuacion total
Comentario general
La respuesta A presenta un diseño concreto de extremo a extremo que aborda directamente las restricciones de venta flash, los requisitos de corrección y los objetivos operativos de la indicación. Sus aspectos más sólidos son la estrategia de capas anti-sobreventa, los flujos de solicitud explícitos, el enfoque de sala de espera/modelado de carga, el manejo idempotente de devoluciones de llamada de pago y las secciones detalladas de confiabilidad/monitoreo. También analiza el comportamiento de recuperación y las compensaciones con una especificidad razonable. Las debilidades menores son una complejidad añadida en la ruta de retención de escritura dual Redis-plus-Aurora y algunas opciones de implementación que requerirían una ingeniería cuidadosa para evitar desviaciones, pero en general es una respuesta de diseño de sistema de alta calidad.
Ver detalle de evaluacion ▼
Calidad de la arquitectura
Peso 30%Arquitectura sólida con componentes bien elegidos y una clara separación entre catálogo, inventario, reserva, pago, emisión de boletos, sala de espera y trabajadores de caducidad. El diseño une de manera coherente las rutas de lectura, las rutas de escritura, la gestión de eventos y el almacenamiento duradero, e identifica explícitamente el servicio de inventario como el ancla de consistencia. El enfoque de retención en capas de Redis más Aurora es sofisticado y adecuado para el problema, aunque introduce complejidad de coordinación.
Integridad
Peso 20%Cubre suposiciones, servicios, almacenes de datos, API, modelo de datos, flujos detallados de navegación/reserva/pago/caducidad, consistencia anti-sobreventa, manejo de picos, DR, monitoreo y compensaciones. También aborda devoluciones de llamada desordenadas y retrasadas, escaneos de caducidad de respaldo, degradación elegante y defensa contra bots. Muy pocas áreas de la indicación quedan sin tratar.
Analisis de compromisos
Peso 20%Proporciona varias compensaciones significativas: Redis primero frente a solo base de datos, bloqueo optimista frente a pesimista, Kafka frente a SQS, pago solo por webhook, sala de espera frente a escalado automático, y región única frente a activo-activo. El razonamiento es específico de las restricciones de la indicación y explica por qué la corrección y el modelado de carga dominan las elecciones de diseño.
Escalabilidad y fiabilidad
Peso 20%Sólido tanto en escala como en resiliencia: sala de espera explícita, limitación de velocidad, precalentamiento, estrategia de Redis consciente de fragmentos para eventos importantes, capas de CDN y caché para lecturas, desacoplamiento asíncrono con Kafka, agrupación de conexiones, implementación multizona, PITR, expectativas de conmutación por error, reconstrucción de respaldo desde Aurora y alertas detalladas. Aborda directamente los requisitos de venta flash y DR declarados.
Claridad
Peso 10%Bien estructurado y fácil de seguir, con secciones distintas y flujos paso a paso. La respuesta es densa pero aún legible. Algunas partes son ligeramente complejas debido a la estrategia de consistencia en capas, sin embargo, la organización la mantiene comprensible.
Puntuacion total
Comentario general
La Respuesta A es un plan de diseño integral y profundamente técnico que aborda directamente todas las restricciones del prompt. Proporciona un modelo de consistencia en capas (Redis SETNX + bloqueo optimista de Aurora), una estrategia concreta de sala de espera virtual para el tráfico de rebajas, un flujo de expiración detallado con una ruta principal de TTL de Redis y una copia de seguridad de escaneo de base de datos, manejo idempotente de pagos con el patrón outbox y alertas específicas vinculadas a SLO. El modelo de datos es preciso, los flujos de solicitud son paso a paso y mecánicamente sólidos, y las compensaciones se argumentan con razonamiento concreto en lugar de declaraciones genéricas. Debilidades menores: algunas secciones son densas y podrían beneficiarse de diagramas, y la sección de DR entre regiones es breve, pero en general, esta es una respuesta de calidad de referencia.
Ver detalle de evaluacion ▼
Calidad de la arquitectura
Peso 30%La Respuesta A presenta una arquitectura bien en capas con una clara separación de responsabilidades, un modelo de consistencia preciso de dos fases (Redis SETNX + bloqueo optimista de Aurora), outbox transaccional para la publicación confiable de Kafka, manejo idempotente de pagos a través de la unicidad de provider_ref y deduplicación de DynamoDB, y una sala de espera virtual. Cada elección de componente está justificada y vinculada a una restricción específica. El modelo de datos es detallado y correcto, incluyendo columnas de versión, hold_id y tabla outbox.
Integridad
Peso 20%La Respuesta A cubre todas las secciones requeridas: servicios, almacenes de datos, API, modelo de datos, los cuatro flujos de solicitud (navegar, reservar, pagar, expirar), estrategia de escalabilidad, confiabilidad/DR con análisis RPO/RTO, garantías de consistencia, monitoreo con alertas específicas vinculadas a SLO y compensaciones. También aborda la defensa contra bots, el pooling de conexiones, el precalentamiento y el manejo de webhooks tardíos después de la expiración.
Analisis de compromisos
Peso 20%La Respuesta A proporciona compensaciones concretas y bien argumentadas: Redis primero vs. solo base de datos (con justificación de RPS), bloqueo pesimista vs. optimista (con razonamiento de contención), región única vs. activa-activa multiregión (con explicación del riesgo de sobreventa), Kafka vs. SQS, sala de espera vs. autoscaling puro, y emisión de tickets asíncrona vs. síncrona. Cada compensación está vinculada a una restricción específica o a un modo de falla.
Escalabilidad y fiabilidad
Peso 20%La Respuesta A aborda el pico de 150k usuarios concurrentes / 8k RPS con una sala de espera virtual (admitiendo N tokens/segundo), precalentamiento de pods 15 minutos antes de las ventas, Redis fragmentado por eventos, RDS Proxy para pooling de conexiones, WAF/CAPTCHA para defensa contra bots y fan-out asíncrono de Kafka. La confiabilidad cubre multi-AZ para todas las tiendas, PITR de Aurora cumpliendo RPO < 1 minuto, failover cumpliendo RTO < 15 minutos, reconstrucción de Redis desde la base de datos, simulacros de caos y disyuntores. Se menciona la base de datos global entre regiones para DR a nivel de región.
Claridad
Peso 10%La Respuesta A está bien organizada con secciones numeradas, encabezados claros y flujos paso a paso. Se especifican explícitamente el esquema de claves de Redis y el modelo de datos. La redacción es precisa y técnica sin ser verbosa. Problema menor: la densidad de algunas secciones (especialmente consistencia y escalabilidad) podría beneficiarse de un diagrama resumen, pero la prosa es clara en general.
Puntuacion total
Comentario general
La respuesta A proporciona un diseño de sistema excepcional y muy detallado. Su principal fortaleza radica en el mecanismo específico y robusto para manejar el problema de reserva de asientos de alta concurrencia, utilizando una combinación de un script Lua de Redis para una verificación rápida y atómica, y bloqueo optimista en la base de datos para garantizar la corrección. La estrategia de escalado es integral y proactiva, incluyendo detalles prácticos como una sala de espera virtual, precalentamiento de instancias y fragmentación de eventos 'hot' en la caché. El diseño es completo, bien razonado y demuestra una profunda comprensión de las compensaciones involucradas en la construcción de un sistema de este tipo.
Ver detalle de evaluacion ▼
Calidad de la arquitectura
Peso 30%La arquitectura es excelente. La elección de usar Redis con una operación atómica (SETNX/Lua) como guardián rápido delante de una base de datos con bloqueo optimista es un patrón superior para este problema de alta contención. Maneja eficazmente la carga de 8k RPS sin sobrecargar la base de datos. La integración de una sala de espera virtual es también una fortaleza clave.
Integridad
Peso 20%La respuesta es excepcionalmente completa, abordando cada punto del prompt con un detalle significativo. Incluye detalles de implementación específicos como el patrón 'transactional outbox', el uso de DynamoDB para la idempotencia y estrategias de defensa contra bots, que van más allá de los requisitos básicos.
Analisis de compromisos
Peso 20%El razonamiento de las compensaciones es excelente y demuestra una profunda experiencia. La discusión sobre Redis vs. solo base de datos, bloqueo pesimista vs. optimista, y la elección de Kafka sobre SQS son todas directamente relevantes y bien justificadas en el contexto de las restricciones específicas del sistema.
Escalabilidad y fiabilidad
Peso 20%Esta es una sección destacada. La estrategia de escalado es integral y proactiva, mencionando técnicas específicas como el precalentamiento de pods, la fragmentación de Redis por ID de evento para eventos 'hot' y el uso de RDS Proxy. El plan de fiabilidad también es de primer nivel, incluyendo multi-AZ para todos los componentes, un plan de recuperación ante desastres entre regiones y un compromiso con simulacros de caos.
Claridad
Peso 10%La respuesta es excepcionalmente clara, bien estructurada y fácil de seguir. El uso de secciones numeradas, subencabezados y texto en negrita guía eficazmente al lector a través del complejo diseño.