Módulo 1: Por qué no reescribir
Mini-proyecto: arma la defensa contra el rewrite de Mercado
Descripción
Este es el capstone del módulo. Durante siete lecciones instalaste el "por qué" completo: los cuatro modos de falla del big rewrite (el negocio que no se detiene, la paridad móvil, el segundo sistema, el conocimiento tácito), el caso a favor de lo incremental (valor temprano, riesgo acotado), la metáfora del strangler fig, y el criterio medido de cuándo cada camino es correcto. Ahora lo aplicas de punta a punta a un caso real: el equipo de Mercado está a punto de decidir entre reescribir el monolito desde cero o modernizarlo por rebanadas, y te toca armar la defensa contra el rewrite —con números, no con opiniones—.
El trabajo del proyecto es el trabajo real de un arquitecto antes de tocar una sola línea de código: convertir la convicción del módulo en un entregable que un equipo pueda usar para decidir. Tiene tres piezas. Primero, clasificar los módulos del monolito de Mercado por valor y riesgo para elegir cuál sería la primera rebanada a modernizar —porque si se va por el camino incremental, hay que empezar por algún lado, y no da lo mismo cuál—. Segundo, modelar el costo/valor de big-rewrite vs incremental para poner sobre la mesa la ventaja medida. Tercero, escribir una recomendación de migración que junte todo: qué estrategia, cuál primera rebanada, por qué no el rewrite (con las cifras), y a dónde sigue el proceso. Fíjate en la frontera, que es deliberada: este proyecto no ejecuta la migración (eso es toda la guía), ni escribe la mecánica del strangler (módulo 3), ni la decisión formal con su ADR (esa es la guía de decisiones). Produce lo que va antes: la defensa razonada y medida de por qué incremental le gana al rewrite en Mercado, y por dónde empezar.
Conexión con el módulo. Es la integración de las siete lecciones en un solo entregable ejecutado. La clasificación de módulos usa el criterio de valor/riesgo de las lecciones 5 y 7; el modelo de costo/valor usa los valor-periodos de la lección 5 y la ventana de silencio de la lección 1; la recomendación usa el conocimiento tácito de la lección 4 (lo que "no sabemos") y apunta a la mecánica de los módulos que siguen. Al terminarlo, tendrás el artefacto que abre el trabajo de toda la guía: una recomendación defendible de modernizar Mercado por rebanadas, empezando por el catálogo. El siguiente paso —tender la red y estrangular— es literalmente el módulo 2 en adelante.
La solución de referencia, ejecutada
Vamos a construir la solución en un solo programa que hace los tres pasos: clasifica los módulos y elige la primera rebanada, modela el costo/valor de las dos estrategias, y emite la recomendación. Todo con datos fijos, reproducible.
Parte 1 — Los datos: los módulos del monolito de Mercado
Recibimos los seis módulos del monolito, cada uno puntuado en tres ejes de 1 a 5: value (cuánto se gana modernizándolo), risk (qué tan peligroso es tocarlo) y coupling (qué tan enredado está con el resto; 1 = fácil de pelar). La buena primera rebanada, siguiendo a Sam Newman, es la de alto valor y bajo acoplamiento: valiosa para que valga la pena, y fácil de desprender para aprender la mecánica con poco riesgo.
# value = cuanto se gana modernizandolo (dolor actual + upside) (1-5)
# risk = que tan peligroso es tocarlo (criticidad, escrituras) (1-5)
# coupling = que tan enredado esta con el resto (1 = facil de pelar) (1-5)
MODULES = [
# (name, value, risk, coupling)
("catalog", 5, 2, 2),
("orders", 4, 5, 5),
("payments", 3, 5, 4),
("shipping", 3, 3, 3),
("search", 4, 2, 2),
("auth", 2, 5, 5),
]
Parte 2 — El programa completo
Los tres pasos, encadenados. Clasificar y elegir la primera rebanada (lecciones 5 y 7), modelar el costo/valor de las dos estrategias (lecciones 1 y 5), y emitir la recomendación (lección 4 para la honestidad sobre lo que no se sabe):
def first_slice_score(value, coupling):
# Buena primera rebanada (Newman): ALTO valor y BAJO acoplamiento -> se pela
# facil, entrega valor y sirve para aprender la mecanica con poco riesgo.
return value - coupling
ranked = sorted(MODULES, key=lambda m: first_slice_score(m[1], m[3]), reverse=True)
print("=== Parte 1: worklist de rebanadas (que modernizar primero) ===")
print(f"{'module':<10}{'value':>7}{'risk':>6}{'coupling':>10}{'slice_score':>13}")
print("-" * 46)
for name, value, risk, coupling in ranked:
print(f"{name:<10}{value:>7}{risk:>6}{coupling:>10}"
f"{first_slice_score(value, coupling):>13}")
first = ranked[0]
print(f"\nPrimera rebanada: {first[0]} "
f"(valor {first[1]}, acoplamiento {first[3]}: valiosa y facil de pelar)")
# --- Parte 2: big-rewrite vs incremental, medido -------------------------------
SLICES = len(MODULES) # 6 modulos = 6 rebanadas
HORIZON = 9 # periodos observados
FEATURES_PER_PERIOD = 4 # lo que el negocio sigue pidiendo, no se detiene
inc_value = rw_value = rw_slip_value = 0
rw_backlog = 0
for t in range(1, HORIZON + 1):
inc_value += min(t, SLICES) # una rebanada entregada por periodo
rw_value += SLICES if t >= 6 else 0 # corte optimista en el periodo 6
rw_slip_value += SLICES if t >= HORIZON else 0 # corte que se corre al final
rw_backlog += FEATURES_PER_PERIOD # features congeladas en el rewrite
print("\n=== Parte 2: valor-periodos entregados en 9 periodos ===")
print(f" incremental : {inc_value:>3} valor-periodos, backlog 0")
print(f" big-rewrite (corte 6): {rw_value:>3} valor-periodos, backlog {rw_backlog}")
print(f" big-rewrite (slip 9) : {rw_slip_value:>3} valor-periodos, backlog {rw_backlog}")
print(f" ventaja incremental vs rewrite optimista: "
f"{inc_value / rw_value:.1f}x mas valor entregado")
# --- Parte 3: la recomendacion (NO es un ADR; el ADR es architecture-decisions) --
print("\n=== Parte 3: recomendacion de migracion ===")
print(f"Estrategia: incremental (strangler fig), NO big rewrite.")
print(f"Primera: {first[0]} (alto valor, bajo acoplamiento, pocas escrituras).")
print(f"Por que no rewrite: entrega {rw_value} valor-periodos vs {inc_value} del")
print(f" incremental, congela {rw_backlog} features y arriesga el 100%")
print(f" del sistema en un solo corte.")
print(f"Sabemos: catalog es read-heavy y de frontera limpia; se pela con bajo riesgo.")
print(f"No sabemos: su comportamiento exacto en los bordes (reglas tacitas sin doc).")
print(f"Siguiente: ponerlo bajo characterization tests (M2), luego strangler (M3),")
print(f" extraer el servicio (M5), migrar datos (M6) y medir avance (M7).")
Qué esperar. Al correr el archivo completo, la salida es exactamente esta:
=== Parte 1: worklist de rebanadas (que modernizar primero) ===
module value risk coupling slice_score
----------------------------------------------
catalog 5 2 2 3
search 4 2 2 2
shipping 3 3 3 0
orders 4 5 5 -1
payments 3 5 4 -1
auth 2 5 5 -3
Primera rebanada: catalog (valor 5, acoplamiento 2: valiosa y facil de pelar)
=== Parte 2: valor-periodos entregados en 9 periodos ===
incremental : 39 valor-periodos, backlog 0
big-rewrite (corte 6): 24 valor-periodos, backlog 36
big-rewrite (slip 9) : 6 valor-periodos, backlog 36
ventaja incremental vs rewrite optimista: 1.6x mas valor entregado
=== Parte 3: recomendacion de migracion ===
Estrategia: incremental (strangler fig), NO big rewrite.
Primera: catalog (alto valor, bajo acoplamiento, pocas escrituras).
Por que no rewrite: entrega 24 valor-periodos vs 39 del
incremental, congela 36 features y arriesga el 100%
del sistema en un solo corte.
Sabemos: catalog es read-heavy y de frontera limpia; se pela con bajo riesgo.
No sabemos: su comportamiento exacto en los bordes (reglas tacitas sin doc).
Siguiente: ponerlo bajo characterization tests (M2), luego strangler (M3),
extraer el servicio (M5), migrar datos (M6) y medir avance (M7).
Parte 3 — La justificación, leída desde la propia corrida
La Parte 1 ordenó los seis módulos por slice_score (valor menos acoplamiento) y el ganador es claro: catalog, con score 3. No está arriba porque "suene importante", sino porque combina las dos cosas que se buscan en una primera rebanada: valor alto (5, porque es read-heavy y una modernización con cache le daría un salto de rendimiento grande) y acoplamiento bajo (2, porque el catálogo es sobre todo lecturas con una frontera relativamente limpia, fácil de desprender del resto). Le sigue search (score 2, también valioso y poco acoplado), y luego caen los módulos pesados: orders, payments y auth tienen scores negativos, no porque no valgan, sino porque su acoplamiento alto (5, 4, 5) los hace difíciles y peligrosos de pelar como primera rebanada. Ojo con la lectura: un score negativo no significa "no modernizar nunca"; significa "no empezar por aquí". Se empieza por donde se aprende la mecánica con poco riesgo —el catálogo—, y se dejan los módulos acoplados y críticos para cuando el equipo ya domina el patrón.
Fíjate en la distinción entre value, risk y coupling. El risk no entra en el slice_score —el orden lo deciden valor y acoplamiento—, pero es información que la recomendación usa: el catálogo tiene risk 2 (pocas escrituras, sobre todo lecturas), lo que refuerza que es una primera rebanada segura. orders y payments, con risk 5, son justo los módulos donde un error cuesta caro (dinero, pedidos), así que tocarlos primero, sin experiencia con el patrón, sería temerario. La primera rebanada ideal es valiosa, poco acoplada y de bajo riesgo: el catálogo cumple las tres.
La Parte 2 pone la ventaja del incremental en números, reuniendo la lección 1 y la lección 5. En 9 periodos, el incremental entrega 39 valor-periodos (una rebanada por periodo, acumulando valor desde el primero) contra 24 del rewrite optimista (que entrega las 6 de golpe en el periodo 6) y apenas 6 del rewrite atrasado (que entrega todo en el último periodo). La ventaja del incremental sobre el rewrite optimista es de 1.6x, y sobre el atrasado —el escenario realista— de 6.5x. Y no olvides la columna del backlog: el rewrite congela 36 features que el negocio pidió y no recibió durante los 9 periodos, mientras que el incremental las entregó todas (backlog 0). El mismo esfuerzo, pero uno entrega valor y features en el camino y el otro pide silencio.
La Parte 3 es la pieza que integra todo: la recomendación de migración. Fíjate en su estructura, que hereda el brief de decisión de la guía hermana pero adaptado a la migración: Estrategia (incremental/strangler, no rewrite), Primera (catalog, con su justificación de valor/acoplamiento/riesgo), Por qué no rewrite (las cifras: 24 vs 39 valor-periodos, 36 features congeladas, el 100% del sistema en riesgo en un corte), Sabemos (lo que la evidencia dice: catalog es read-heavy y de frontera limpia), No sabemos (la niebla honesta de la lección 4: las reglas tácitas del catálogo que ninguna doc captura), y Siguiente (a dónde va: M2 caracterizar → M3 strangler → M5 extraer → M6 datos → M7 medir). Esa recomendación no ejecuta la migración —no escribe el router ni los tests—; hace algo más valioso en esta etapa: deja explícito, con números, por qué incremental le gana al rewrite en Mercado, por dónde empezar, qué se ignora, y cuál es el camino. Un equipo que arranca desde esta recomendación no empieza de cero: empieza con la defensa hecha.
Este proyecto es el paso 0 de un recorrido que el resto de la guía completa:
flowchart LR
P["Proyecto M1<br/>recomendación + primera rebanada<br/>(paso 0: por qué y por dónde)"] --> M2["M2<br/>characterization tests<br/>(tender la red)"]
M2 --> M3["M3<br/>strangler fig<br/>(desviar tráfico)"]
M3 --> M5["M5<br/>extraer el servicio"]
M5 --> M6["M6<br/>migrar los datos"]
M6 --> M7["M7<br/>medir el progreso"]
Léelo así: aquí decides por qué incremental y por dónde empezar; de ahí en adelante, la guía lleva el catálogo de "elegido como primera rebanada" a "modernizado, con sus datos migrados y la vieja ruta apagada".
Tu entrega
Reproduce y adapta la solución de referencia. Tu entrega tiene tres piezas:
- El worklist de rebanadas ejecutado: los módulos de Mercado puntuados en valor/riesgo/acoplamiento y ordenados por
slice_score, con la salida literal de tu programa. Puedes usar los módulos del ejemplo o —mejor— agregar uno o dos módulos propios de Mercado (por ejemplo,reviewsonotifications) y puntuarlos tú, justificando cada eje. - El modelo de costo/valor: los valor-periodos de incremental vs rewrite (a tiempo y atrasado) y el backlog congelado, con el factor de ventaja del incremental. Si cambiaste el número de módulos, ajusta
SLICESy observa cómo se mueven las cifras. - La recomendación de migración: la estructura de seis líneas —Estrategia / Primera / Por qué no rewrite / Sabemos / No sabemos / Siguiente—, honesta sobre lo que no se sabe (el conocimiento tácito de la lección 4). No ejecutes la migración; justifica por qué incremental gana y por dónde empezar.
Errores comunes
Elegir la primera rebanada por su importancia en vez de por su idoneidad. Qué pasa: el proyecto elige empezar por payments u orders "porque son los más importantes / los que más duelen". Por qué pasa: parece lógico atacar primero lo más crítico. Cómo detectarlo: si tu primera rebanada es un módulo de acoplamiento y riesgo altos (score negativo en el worklist), estás empezando por el lugar equivocado. Cómo corregirlo: la primera rebanada no se elige por importancia sino por idoneidad para aprender el patrón con poco riesgo —alto valor, bajo acoplamiento, bajo riesgo—. El catálogo es la elección correcta justamente porque es valioso y fácil de pelar y de bajo riesgo: te deja dominar la mecánica del strangler antes de tocar los módulos peligrosos. Empezar por payments es aprender a caminar en la cuerda floja más alta sin haber practicado en el suelo. Los módulos críticos se modernizan después, con el patrón ya dominado. (La importancia sí importa —pero para el orden general, no para la primera rebanada—.)
Escribir una recomendación que finge certeza total. Qué pasa: la línea "No sabemos" queda vacía o dice algo cosmético, y la recomendación suena a que ya se conoce todo el comportamiento del catálogo. Por qué pasa: admitir lo que no sabes se siente como debilidad, cuando es lo contrario —es la honestidad que la lección 4 volvió imprescindible—. Cómo detectarlo: si tu recomendación no nombra ninguna incertidumbre real sobre el conocimiento tácito del módulo, no es una recomendación de migración honesta; es una declaración de fe. Cómo corregirlo: nombra la niebla concreta (aquí, "las reglas tácitas del catálogo que ninguna doc captura", como las reglas ocultas de la lección 4) y aun así recomienda avanzar, porque el primer paso —tender la red con characterization tests— es precisamente lo que convierte esa niebla en comportamiento capturado. Una buena recomendación dice las dos cosas: "esto no lo sabemos" y "por eso el paso 1 es caracterizarlo, no reescribirlo a ciegas".
Deslizarse de "recomendar" a "ejecutar la migración". Qué pasa: el proyecto se desvía a diseñar el router del strangler, o a escribir los characterization tests del catálogo, o a decidir el stack del nuevo servicio. Por qué pasa: es la parte "de manos a la obra" y es donde muchos quieren saltar. Cómo detectarlo: si tu entrega empieza a contener código de la migración (el strangler_router, los tests, el esquema de datos nuevo), te saliste del alcance. Cómo corregirlo: recuerda la frontera. Este proyecto produce la defensa y la priorización, no la ejecución. Tender la red es el módulo 2; el router es el módulo 3; extraer el servicio es el módulo 5. Aquí solo decides por qué incremental y por dónde empezar, con los números que lo justifican —la recomendación termina en "Siguiente: M2, M3...", no en un router funcionando—.
Ejercicios
Ejercicio 1 — Agrega un módulo y re-prioriza. Mercado tiene también un módulo reviews (reseñas de productos): valor 3 (mejora la conversión, pero no es central), risk 2 (sobre todo lecturas y escrituras simples, poco crítico) y coupling 2 (bastante independiente, ligado solo al catálogo). Calcula su slice_score, di en qué posición del worklist caería, y argumenta si sería una buena segunda rebanada después del catálogo.
Ver solución
slice_score = value - coupling = 3 - 2 = 1. En el worklist del ejemplo, un score de 1 caería entre shipping (0) y search (2) —cuarta posición aproximadamente, por debajo de catalog (3) y search (2), y por encima de shipping (0) y los módulos pesados con score negativo—.
¿Buena segunda rebanada después del catálogo? Sí, y por una razón que va más allá del score: reviews está acoplado justamente al catálogo (coupling 2, ligado a él). Una vez que el catálogo ya está modernizado y extraído (la primera rebanada), reviews se vuelve una continuación natural —consume el catálogo nuevo, comparte su frontera, y el equipo ya aprendió la mecánica del strangler con el catálogo—. Su riesgo es bajo (2) y su valor decente (3). No es la más urgente, pero es una segunda rebanada de bajo riesgo que aprovecha el trabajo ya hecho y consolida el patrón antes de atacar los módulos pesados (orders, payments). La lección de método: después de la primera rebanada, conviene seguir por lo adyacente y de bajo riesgo, no saltar directo a lo más crítico. (El orden fino de las rebanadas intermedias es tema del módulo 7, medir el progreso; aquí basta con ubicarla.)
Ejercicio 2 — Defiende la elección del catálogo. Un compañero mira el worklist y objeta: "catalog tiene valor 5 y orders valor 4, casi igual; pero orders es el corazón del negocio. Empecemos por orders, que es lo que de verdad importa". Da un argumento, usando los conceptos del módulo, de por qué empezar por el catálogo es la mejor jugada a pesar de que orders sea más central.
Ver solución
El compañero tiene un punto válido —orders es más central para el negocio— pero confunde "más importante" con "mejor primera rebanada", y no son lo mismo. La importancia de un módulo te dice que hay que modernizarlo eventualmente; la idoneidad como primera rebanada la deciden otros factores: el acoplamiento y el riesgo.
Y ahí catalog gana claramente:
- Acoplamiento.
catalogtiene coupling 2 (frontera limpia, sobre todo lecturas), mientras queorderstiene coupling 5 (enredado con pagos, envíos, inventario). Pelarordersprimero significa desenredar simultáneamente sus conexiones con medio sistema —justo la operación más difícil— sin haber practicado el patrón antes. Pelarcatalogprimero es desprender una pieza casi independiente: la mecánica del strangler se aprende con un caso manejable. - Riesgo.
orderstiene risk 5 (maneja pedidos y dinero; un error cuesta caro y es difícil de revertir), contra risk 2 decatalog(sobre todo lecturas; un error es tolerable y reversible). Estrenar el patrón de migración en el módulo donde un fallo cuesta más caro es exactamente la jugada que la lección 5 (riesgo en juego) desaconseja.
La regla: se empieza por donde se aprende el patrón con poco riesgo, no por lo más importante en abstracto. Modernizar orders con calma y a fondo después, con el equipo ya experto en strangler tras haber hecho el catálogo (y quizá search y reviews), es mucho más seguro que estrenar la técnica en el módulo más crítico y acoplado. Empezar por el catálogo no pospone orders por miedo; lo prepara para hacerse bien. Idoneidad manda la primera rebanada; importancia manda que ninguno se quede sin modernizar. Son dos perillas distintas.
Ejercicio 3 — Cierra el arco: de la recomendación a lo que viene. La recomendación termina en "Siguiente: characterization tests (M2), luego strangler (M3), extraer el servicio (M5), migrar datos (M6) y medir avance (M7)". Enumera, en orden, los pasos que le seguirían a esta recomendación para llevar el catálogo de "elegido como primera rebanada" a "modernizado y con la vieja ruta apagada", nombrando qué módulo de la guía cubre cada uno.
Ver solución
El recorrido completo, desde donde este proyecto lo deja:
- Tender la red: characterization tests (módulo 2). Antes de tocar el catálogo, capturar su comportamiento actual —rarezas incluidas, como las reglas ocultas de la lección 4— con tests que fijen lo que hoy hace. Encontrar el seam donde insertar la prueba. Esto convierte la niebla del "No sabemos" en comportamiento capturado, y es el requisito previo de cualquier cambio seguro (la palanca de la cobertura, lección 7).
- Poner el facade y desviar tráfico: strangler fig (módulo 3). Montar el
strangler_routerdelante del catálogo, construir el servicio nuevo al lado, y desviar tráfico incrementalmente (por porcentaje o feature flag) con la vieja ruta como fallback —la mecánica de la metáfora de la lección 6—. - Extraer el servicio: anti-corruption layer (módulo 5). Separar el catálogo del monolito como servicio propio, con un anti-corruption layer que traduzca entre el modelo viejo y el nuevo, y definir la propiedad de sus datos.
- Migrar los datos sin downtime (módulo 6). Mover los datos del catálogo con expand-contract: dual-write (escribir a ambos), backfill (llenar lo histórico), parallel-run (leer de ambos y comparar antes de confiar) y el read-switch final. La comparación del parallel-run atrapa las regresiones del conocimiento tácito antes del switch.
- Medir el progreso (módulo 7). Con métricas de avance —% de tráfico en la ruta nueva, burn-down de llamadas al legacy— saber si la migración avanza y cuándo terminó, y apagar la vieja ruta del catálogo solo cuando el 100% pasó de forma estable. Evitar la migración eterna que nunca apaga lo viejo.
Este proyecto (módulo 1) es el paso 0: la defensa que dice por qué incremental y por dónde empezar. Todo lo demás —tender la red, estrangular, extraer, migrar, medir— es el resto de la guía, y el módulo 8 recorre todo ese arco con el catálogo de punta a punta.
Resumen y siguiente paso
Cerraste el módulo aplicando su método completo a un caso real. Tomaste el monolito de Mercado y produjiste el artefacto que abre el trabajo de un arquitecto de migración: un worklist de rebanadas que clasifica los seis módulos por valor y acoplamiento y elige el catálogo como primera rebanada (valioso, poco acoplado, de bajo riesgo); un modelo de costo/valor que muestra la ventaja del incremental en números (39 valor-periodos contra 24 o 6 del rewrite, con 36 features congeladas del lado del rewrite); y una recomendación de migración honesta que junta la estrategia, la primera rebanada, el porqué no reescribir, lo que se sabe, lo que no, y a dónde sigue. No ejecutaste la migración ni escribiste el router: hiciste el paso 0 que le dice al equipo por qué incremental gana y por dónde empezar.
Con esto termina el módulo 1. Ya tienes el "por qué" completo: sabes por qué el big rewrite fracasa (los cuatro modos de falla), por qué el incremental gana (valor temprano, riesgo acotado), qué es el strangler fig, y cuándo cada camino es correcto. Lo que sigue en la guía es el "cómo". El módulo 2 ataca lo primero e imprescindible: caracterizar y fijar el legacy —trabajar con código que da miedo y no tiene tests, poner el characterization test que captura el comportamiento actual (bugs incluidos) antes de tocar nada, y encontrar el seam donde insertar el cambio—. Es la red de seguridad que la lección 7 identificó como la palanca clave, y el requisito previo de todo lo demás. La recomendación que acabas de escribir termina justo ahí: "Siguiente: caracterizar el catálogo". El módulo 2 lo hace.
Recursos
- Sam Newman, Monolith to Microservices (O'Reilly, 2019), cap. 3, "Splitting the Monolith" — cómo elegir la primera rebanada por acoplamiento y valor, y el orden de extracción de un monolito. El marco directo de la Parte 1 de este proyecto. En inglés.
- Michael Feathers, Working Effectively with Legacy Code (Prentice Hall, 2004) — el destino inmediato de la recomendación: caracterizar el catálogo con tests antes de tocarlo. El módulo 2 de esta guía. En inglés.
- Martin Fowler, "StranglerFigApplication" (2004) — martinfowler.com/bliki/StranglerFigApplication.html. Hacia dónde va la primera rebanada una vez elegida: el patrón que la desvía de a poco. El módulo 3. En inglés.
- Joel Spolsky, "Things You Should Never Do, Part I" (2000) — joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i. La defensa contra el rewrite que este proyecto formaliza con números, contada con el caso real de Netscape. En inglés.
- microservices.io, "Refactoring a Monolith to Microservices" — microservices.io/refactoring/index.html. Catálogo de patrones para migrar un monolito por partes, referencia para los módulos 3 al 7. En inglés.