CV-as-Code: el currículum como artefacto generado (post vivo)


9 de junio de 2026

Este es un post vivo: lo escribo como plan antes de tocar código y lo voy completando a medida que el trabajo avanza. La idea es pensar en voz alta, que se vea el diseño, y decidir por dónde tirar antes de picar.

El problema

Actualizar un currículum es un suplicio recurrente: abres una plataforma online que no recuerdas cuál era, peleas con su editor, exportas un PDF, y seis meses después el PDF está desactualizado y desligado de cualquier fuente de verdad. El último que tengo es de octubre y se quedó congelado en un trabajo que dejé hace años: le falta todo lo reciente.

Mientras tanto, el portfolio (la web personal) está al día: tiene la experiencia, los proyectos, los highlights. Pero vive como atributos data'[…]'= incrustados dentro de componentes web, y el PDF va por otro lado. Dos fuentes, ninguna conectada.

El objetivo es reducir "actualizar el CV" a tres pasos:

  1. Editar un fichero de datos con la nueva chicha.
  2. Pulsar "Descargar CV (PDF)".
  3. PDF profesional, paginado, listo para enviar.

El insight: el PDF lo genera el cliente, no el servidor

La primera versión del plan proponía que el servidor lanzara un Chromium headless para imprimir el PDF. Mala idea: meter un navegador entero en un servidor pequeño de producción, para generar un documento que cambia una vez cada varios meses, es complejidad que no paga su precio.

La versión buena es mucho más simple: el navegador del visitante ya trae el mejor motor de impresión que existe. No hace falta generar nada en el servidor. Se sirve una página HTML diseñada para imprimirse en A4, y el botón "Descargar" no hace más que abrirla y disparar la impresión. El navegador produce el PDF.

Cero infraestructura nueva. Cero dependencias pesadas. El "botón mágico" es una página bien hecha y una línea de JavaScript.

La arquitectura

cv-data/*.json   ──►   /cv (HTML A4 print)   ──►   window.print()   ──►   PDF
 (fuente única)        (diseño imprimible)        (motor del navegador)

Tres piezas:

1. Datos separados: cv-data/*.json

La fuente de verdad pasa a ser un puñado de ficheros de datos:

La buena noticia: la experiencia ya está escrita y actualizada dentro del portfolio. Es mover datos que ya existen a un sitio con nombre propio, no inventarlos. Lo único que falta rescatar del CV viejo es formación e idiomas.

2. La vista /cv: una página pensada para el papel

Aquí está el 80% del valor. Una ruta nueva que sirve una página distinta del portfolio:

Esta vista, por sí sola, ya sirve para imprimir un CV decente con el atajo de impresión del navegador, aunque el botón llegue después.

3. El botón "Descargar CV (PDF)"

En el portfolio, un botón que abre /cv y llama a la impresión del navegador. Sin endpoint que genere PDFs, sin caché, sin proceso aparte. La única pega menor: el navegador añade sus propias cabeceras (fecha, URL) en el diálogo de impresión, pero se quitan con un clic y además se controlan bastante desde CSS.

Decisiones tomadas

No-objetivos

Plan por fases

  1. Extraer los datos a cv-data/*.json (sin romper el portfolio actual).
  2. Construir la vista /cv imprimible (el corazón).
  3. Añadir el botón "Descargar CV" en el portfolio.

Por dónde tirar

Mi propuesta es empezar por la fase 2 reducida: montar /cv leyendo los datos ya existentes, ver cómo queda impreso en A4 con la experiencia actual, y ajustar el diseño hasta que se sostenga cuando la experiencia crezca. Con eso ya hay CV imprimible. Las fases 1 y 3 (datos limpios y botón) caen solas después.

Implementación (hecho)

Las tres fases están en producción. El CV imprimible vive en pascualmg.dev/cv y el portfolio tiene un botón "Descargar mi CV (PDF)" bajo los enlaces sociales.

Lo bonito del resultado: actualizar el currículum es ahora editar un fichero de datos y publicar. El documento deja de ser un artefacto muerto que se desincroniza; pasa a ser una vista de unos datos versionados.

Y un guiño meta: este post se publicó en el mismo blog que sirve el CV, a través de un endpoint que se volvió idempotente hace unos días. Publicar el plan y desplegar la solución fueron, literalmente, el mismo sistema.

Cómo se actualiza

La gracia del invento: actualizar el currículum no es "abrir un editor de CVs", es editar datos. Hay tres ficheros JSON:

El flujo es: editar el JSON, validarlo, publicar el cambio y desplegar. La página /cv lee los datos en cada carga, así que el CV refleja el cambio al instante, sin tocar una línea de HTML ni de CSS. El PDF se genera imprimiendo desde el navegador (márgenes "Ninguno", sin cabeceras).

El documento dejó de ser un artefacto que se pudre en una carpeta de Descargas: ahora es el reflejo, siempre al día, de unos datos versionados. Quien quiera el detalle exacto (formato de cada campo, dónde viven los ficheros, cómo desplegar) lo tiene en la documentación del proyecto.

Lo siguiente (que no es ahora)

Una vez que generas uno, la pregunta cae sola: ¿y un generador para muchos? La vista ya es genérica —lee un JSON y pinta—, así que el salto natural sería un endpoint que reciba el JSON completo de cualquiera (foto incluida por URL), lo guarde con su propio identificador y sirva un CV compartible por persona. Un "generador de currículums" en lugar de un currículum.

Pero eso será otro día, si llega. El objetivo de hoy era tener mi CV resuelto para siempre, y ese ya vale. La mejor manera de no caer en el sobre-diseño es justo esta: parar cuando el problema que tenías delante está resuelto, y dejar la idea grande apuntada para cuando de verdad la necesites.

Comparte este post:

Es tu post

Estas seguro? Esto no se puede deshacer.

Comentarios (0)

Sin comentarios todavia. Se el primero!

Deja un comentario