yesid.dev: explicar cómo se conectan las partes
Mi sitio profesional en tres idiomas, con contenido editable, historias de proyectos y una guía interactiva para entender las partes de un software.
Mi sitio profesional en español, francés e inglés. Un lugar para explicar mi trabajo, mostrar los proyectos que lo respaldan y empezar una conversación.
Empezar por las preguntas de las personas#
Alguien que busca ayuda con una página web o con sus reportes no tiene por qué llegar con una lista de programas. Puede saber que está registrando la misma información dos veces, que preparar un reporte toma demasiado trabajo o que su sitio ya no representa lo que hace. La elección de herramientas viene después de entender esa situación.
yesid.dev reúne esas preguntas y mi trabajo como desarrollador freelance de soluciones digitales en Montreal. Incluye servicios, proyectos, artículos, una página para entender las herramientas y varias formas de contactarme. Construirlo también implicó decidir cómo mantener al día esas explicaciones.
Es mi propio sitio profesional. Soy responsable de las decisiones sobre lo que dice, cómo se conectan sus partes y qué estoy dispuesto a publicar con mi nombre.
Distintas formas de acercarse al trabajo#
Los servicios están organizados en bases de datos y SQL, pipelines y automatización, tableros y analítica, y sitios web y comercio electrónico. Cada grupo ofrece un punto de partida. No hace falta saber en cuál encaja un problema antes de escribirme.
Los proyectos muestran algo más concreto: qué se construyó, qué partes se usaron y qué se puede enseñar. El blog permite detenerse en el razonamiento detrás de una decisión. Separar esos formatos ayuda a que la historia de un proyecto mantenga un hilo claro y a que un artículo tenga espacio para profundizar.
La página de herramientas cumple otra función. Explica las partes de un programa en términos cotidianos: la interfaz que usamos, la lógica que hay detrás, la información que conserva y la infraestructura donde funciona. Sus diagramas interactivos permiten escoger un tipo de proyecto y ver una posible combinación de esas partes.
Son ejemplos para explorar. Un diagrama sirve para abrir la conversación, pero una recomendación concreta sigue dependiendo de los requisitos.
Qué construí y qué se necesita para mantenerlo al día#
La decisión central fue separar la escritura de la distribución de las páginas. Las historias de proyectos, las descripciones de servicios y las traducciones tienen su lugar en Directus, el editor de contenido. La web en SvelteKit convierte ese material estructurado en las páginas que la gente consulta. Puedo corregir una explicación sin rehacer su presentación a mano, mientras las mismas reglas visuales conectan las páginas.
El sitio funciona en español, francés e inglés. Eso incluye detalles prácticos como las etiquetas y los errores del formulario, no solo tres versiones de un título. El formulario también registra lo que alguien escribió para poder trasladar esos valores durante un cambio de idioma. Es una función prevista para esa transición, no un almacenamiento permanente de mensajes sin terminar.
El diseño inspirado en el transporte público le da al sitio un lenguaje reconocible, pero la interfaz sigue teniendo tareas comunes. Un texto largo necesita navegación. Una tarjeta desplegable debe permitir seleccionar una frase sin cerrarse. Un formulario debe distinguir un campo vacío, una solicitud en curso y un envío fallido. Ahí la idea visual se encuentra con la persona que usa el sitio.
Publicar tiene un paso deliberado. Guardar una corrección en el editor no cambia inmediatamente la web pública: hay que exportar el contenido, construir una nueva versión y ponerla en línea. Esto corresponde al ritmo editorial de un sitio profesional. También me hace responsable de saber qué versión se está mostrando cuando una corrección todavía no aparece.
Las herramientas de IA ayudaron en la implementación y la revisión. Yo dirigía la arquitectura y examinaba los resultados, incluso cuando una página se veía bien pero usaba texto guardado en el lugar equivocado. Hacerse cargo de este proyecto exige seguir esas conexiones, en vez de tomar la pantalla como única prueba de que el trabajo está terminado.
Ese es el proyecto completo: un lugar para explicar mi trabajo, respaldado por un proceso de edición y publicación que debo mantener. Las siguientes secciones examinan decisiones específicas. Cada una se puede leer por separado, según el interés en contenido, idiomas, comportamiento de la interfaz u operaciones.
El sitio se presenta como un solo producto, pero el trabajo está dividido en cuatro áreas: la web pública, el sistema de edición, el código que mueve y revisa el contenido, y los recursos de diseño compartidos. Saber a cuál le corresponde un cambio me ayuda a no corregir un problema en el lugar equivocado.
La aplicación web, construida con SvelteKit, se encarga de la experiencia del visitante. Organiza la página de un proyecto, elige el idioma, presenta el contenido, conecta la navegación y maneja interacciones como abrir una sección. Directus es el sistema de edición, conectado a una base de datos PostgreSQL en Neon y alojado en Railway. Allí se organizan proyectos, servicios, artículos, traducciones y contenido compartido.
Entre ambos hay herramientas escritas para este proyecto. Unas funciones leen los registros del CMS; otras los transforman a la estructura que espera el sitio. Los validadores revisan los datos y el exportador genera los módulos de contenido que usará la aplicación. Una relación útil para editar no tiene que convertirse en un objeto complejo que cada página deba interpretar.
Un paquete compartido contiene los tipos de datos, los esquemas de validación y las funciones de transformación que usan ambos lados. Por ejemplo, el exportador y la web pueden coincidir en lo que contiene una sección de proyecto sin mantener dos interpretaciones distintas de esa estructura.
La cuarta área viene de yesid.dev-design. El sitio consume copias versionadas de paquetes de diseño para componentes básicos, valores visuales, movimiento, rutas por idioma, analítica y metadatos para buscadores. Este proyecto aplica esos recursos a sus propios contenidos y pantallas. No es, por sí solo, todo el sistema de diseño.
Tres cambios pequeños ayudan a verlo. Corregir la descripción de un servicio corresponde al CMS. Cambiar el comportamiento de una tarjeta corresponde a la aplicación web. Modificar una regla de movimiento compartida corresponde a los recursos de diseño y después requiere adoptar esa versión en el sitio. Mantener esas rutas separadas permite seguir el origen de cada cambio.
La descripción de un servicio cambia. Un proyecto necesita una explicación más precisa. Una traducción requiere una corrección. Quería que esos cambios tuvieran un lugar en el editor sin perder una presentación consistente.
Un proyecto tiene una identidad, un título, una frase corta, una introducción, secciones ordenadas, servicios relacionados, tecnologías, etiquetas, enlaces y un estado de presentación. En Directus, varios de esos elementos son registros relacionados. La exportación los convierte en un objeto más sencillo para la web. El orden de las secciones viene de los valores de orden guardados; las tecnologías y etiquetas se resuelven a partir de sus relaciones.
El esquema compartido de una sección es corto:
export const ProjectSectionSchema = z.object({
title: LocalizedStringSchema,
content: LocalizedBlockEditorDocSchema,
});Indica que una sección contiene un título traducido y un documento de contenido enriquecido traducido. No exige un borde naranja, una distribución en dos columnas ni una animación. Esas decisiones corresponden a la interfaz.
La separación sirve cuando un proyecto necesita una presentación breve para quien recorre el portafolio y una explicación detallada para quien evalúa el trabajo. La frase corta va en la tarjeta. La introducción plantea el problema. Las secciones pueden explicar un modelo de datos, una decisión de interfaz o una condición de operación sin hacer que todo eso quepa en la tarjeta.
El modelo también distingue el estado de presentación del proyecto de la visibilidad del repositorio. Un registro que se muestra como proyecto público no cambia los permisos de su código fuente. La indicación de repositorio privado y el enlace a un sitio disponible son datos distintos.
Imaginemos una corrección concreta: cambiar una frase en la introducción francesa de un proyecto. El cambio esperado está en ese documento en francés. La identidad del proyecto, su versión en español, los servicios asociados y el componente de la página no necesitan cambiar por esa sola frase. Ese es el valor práctico de la estructura: una modificación editorial pequeña tiene un lugar preciso.
El cuerpo de una sección usa BlockEditorDoc, el documento JSON que produce el editor de bloques del CMS. Contiene una marca de tiempo, una versión y una lista ordenada llamada blocks. Cada bloque tiene una identidad, un tipo y los datos correspondientes a ese tipo.
Los tipos admitidos incluyen títulos, párrafos, listas anidadas, código, citas, imágenes y separadores. Un párrafo contiene texto. Un bloque de código guarda código como texto plano. Una imagen lleva una referencia al archivo y un pie de imagen. El sistema recorre la lista y entrega cada tipo al componente que lo presenta.
Así una explicación puede tomar varias formas sin convertirlo todo en párrafos. Una sección puede comenzar con una pregunta, mostrar un fragmento corto del programa, explicarlo con palabras comunes y cerrar con una imagen. El orden pertenece al contenido; las reglas de presentación se comparten.
Las tarjetas desplegables son otra capa. Rodean la sección del proyecto; no son un bloque “collapsible” inventado dentro del documento. La página elige el título y el contenido en el idioma correspondiente y luego coloca el documento en CollapsibleSection. La tarjeta aporta el control para abrir y cerrar. BlockRenderer presenta lo que hay dentro.
La diferencia tiene valor para quien lee. Una persona puede entender el problema y la solución sin recorrer cada detalle técnico. Otra puede abrir una explicación completa del proceso de publicación. Por eso cada sección necesita contexto suficiente para entenderse sola, sin obligar a reconstruir un argumento con fragmentos dispersos.
La página también separa las secciones de galería de las secciones del artículo y organiza la navegación alrededor de ellas. En una pantalla ancha, el índice, el texto y el resumen del proyecto pueden verse uno al lado del otro. En una pantalla estrecha, se apilan en orden de lectura y un control compacto permite pasar entre secciones.
Otras funciones extraen texto y títulos de esos mismos documentos. La estimación de lectura usa la regla ceil(words / 200), con un mínimo de un minuto. Como ejemplo, 1.200 palabras dan seis minutos; 1.201 se redondean a siete. Es una referencia calculada a partir de la longitud, no una medición de cuánto tarda alguien en entender código o un diagrama.
El modelo tiene límites. Un tipo nuevo de contenido necesita una estructura definida y un componente que lo muestre. No aparece solo por pegar un formato desconocido en el editor. El modelo actual no tiene un bloque de video. Los pies de imagen y los textos alternativos también necesitan una separación más clara en el contrato de contenido.
Guardar un cambio todavía no produce una página pública nueva. En el recorrido normal de publicación con contenido reciente del CMS, hay que leer los datos, transformarlos, validarlos, generar los módulos de contenido, construir el sitio y desplegar esa nueva versión.
El paquete web ejecuta la exportación antes de construir el sitio. El exportador reúne el conjunto completo de datos requeridos, entre ellos proyectos, servicios, artículos, navegación y contenido de las páginas. Cada función conoce las relaciones de su colección. Produce objetos que la web puede usar sin pedirle a Directus que reconstruya esas relaciones en cada visita.
Por ejemplo, la función de proyectos convierte las traducciones de las secciones en conjuntos de valores por idioma y ordena el contenido repetido. Después valida la lista de proyectos con el esquema compartido. Que un campo exista en la base no basta si su forma exportada es incompatible con la aplicación.
Antes de preparar los archivos de salida, el registro de exportación comprueba que estén todos los datos requeridos. El proceso también prepara las variantes de medios que necesita. El resultado es un conjunto de módulos TypeScript y un manifiesto que registra las huellas de los archivos y el origen de los datos: una lectura del CMS o una copia en caché.
La construcción del sitio usa esos módulos. SvelteKit prepara las rutas que se pueden generar de antemano y Vercel sirve el despliegue. También quedan funciones de servidor e interacciones. Preparar el texto no elimina las solicitudes de imágenes, los envíos de contacto ni todas las conexiones externas.
Un ejemplo permite seguir el recorrido. Corrijo un párrafo francés en Directus y lo guardo. El editor muestra la corrección, pero la versión pública todavía contiene el contenido exportado antes. Una exportación y una construcción exitosas preparan la nueva versión. Poner esa versión en línea la hace disponible para los visitantes. Mirar solo el editor, o solo la generación de archivos, no confirmaría la publicación.
Esta organización corresponde a un sitio cuyas historias de proyectos y descripciones de servicios cambian a un ritmo editorial. Acepta un paso de publicación para servir contenido ya preparado. Habría que reconsiderarla para información que debe aparecer inmediatamente después de cada escritura, como un flujo operativo en vivo. La elección responde al contenido de este sitio, no a una regla que aplicaría a todos los proyectos.
En este sistema hay varias cachés y cada una resuelve un problema distinto. La de exportación guarda localmente una lectura anterior del CMS. Los módulos generados son el contenido que se registra o produce para construir el sitio. La caché de construcción puede reutilizar trabajo terminado. La caché de entrega ayuda a servir una respuesta desplegada. Llamarlas a todas “la caché” escondería la pregunta importante: qué versión se está usando y por qué.
La exportación trata el trabajo local de manera diferente a un despliegue autorizado que exige contenido reciente. Localmente, una lectura fallida del CMS puede recurrir a la copia guardada. Si tampoco hay una copia válida, el exportador puede dejar intactos los módulos existentes y señalar que no produjo archivos. Esto permite seguir trabajando en la interfaz, pero no convierte el resultado en una exportación reciente del CMS.
En un despliegue que exige esa lectura reciente, un resultado de otro origen debe producir un fallo. La decisión está expresada directamente:
export function decideExit(outcome: RunOutcome, policy: FallbackPolicy): number {
return policy === 'fail' && outcome.source !== 'live' ? 1 : 0;
}El número es un código de salida: cero permite que la orden termine correctamente; uno señala un error. Bajo la política estricta, una lectura reciente, identificada como live, da cero; los datos de caché dan uno; y no producir contenido también da uno. Bajo la política local flexible, la orden puede terminar con cero mientras informa claramente qué alternativa utilizó.
Imaginemos que el CMS no responde mientras ajusto el espacio de una tarjeta. El contenido de ayer todavía puede servir para ese trabajo local. Ahora imaginemos que acabo de corregir una descripción pública y espero verla en el despliegue. Sustituirla silenciosamente por el texto de ayer frustraría ese objetivo. El segundo caso necesita una construcción detenida que pueda investigar, no un resultado tranquilizador con contenido viejo.
Existe también una opción explícita para omitir la exportación. La integración continua y las vistas previas normales pueden construir el sitio con los módulos ya guardados en el repositorio sin contactar el CMS. La elección queda en la configuración; no se deduce únicamente de que una orden haya terminado.
El exportador tiene un límite de tiempo para lecturas bloqueadas. También exige el conjunto completo de datos, en lugar de presentar una selección parcial como una exportación completa. La escritura sigue siendo una secuencia de archivos, no una transacción de base de datos que los abarque a todos. Si se interrumpe, hay que verificar y regenerar el resultado antes de usarlo. La integridad del conjunto de datos no equivale a una garantía frente a cualquier fallo de disco.
El español, el francés y el inglés son mis idiomas de trabajo. Dentro del sitio afectan mucho más que el título inicial: navegación, explicaciones de proyectos, etiquetas del formulario, mensajes de validación y páginas relacionadas también deben contemplar el idioma.
El inglés usa las direcciones sin prefijo. El francés usa /fr y el español /es. En el contrato de contenido, los valores traducidos llevan las claves en, fr y es. Una sección tiene, por tanto, un conjunto de títulos y otro de documentos por idioma, en lugar de tres copias independientes del proyecto completo.
El esquema exige inglés como base. Francés y español son opcionales en la estructura compartida, lo que permite completar las traducciones con el tiempo. Un objeto válido no demuestra que los tres idiomas estén listos. Validar la estructura y revisar si el contenido está completo son tareas distintas.
Para los textos traducidos comunes, se rechaza un valor obligatorio en inglés que esté vacío o solo tenga espacios. La exportación lee los registros de traducción, conserva los valores reconocidos y forma el conjunto por idioma. El contenido enriquecido tiene su propio esquema. Una cadena cualquiera no reemplaza un documento cuando la interfaz espera una lista ordenada de bloques.
Pensemos en una sección con título y cuerpo en los tres idiomas. Son seis valores editoriales que deben mantener el mismo sentido: tres títulos y tres cuerpos. Corregir un dato en francés no actualiza por sí solo las otras dos versiones. La identidad y el orden pueden ser compartidos, pero el significado necesita revisión en cada idioma.
Quiero que las versiones se lean de forma natural para sus públicos. El francés de Québec, el español colombiano y el inglés canadiense no siempre usan las mismas construcciones ni los mismos términos cotidianos. Lo que debe mantenerse es el relato: las mismas funciones, responsabilidades, limitaciones y ejemplos. En cambio, traducir un identificador dentro de un fragmento de código modificaría el programa en vez de adaptar la explicación.
Esto lleva a una pregunta más útil que “¿existe el botón de idioma?”. ¿Puede alguien leer el proyecto, entender un error, seguir un enlace relacionado y contactarme en el idioma que eligió? El modelo permite organizar ese trabajo, pero no hace por sí solo la revisión editorial.
Imaginemos que alguien empieza un mensaje en español y después pasa la interfaz a francés. Las etiquetas deberían cambiar. Las palabras que escribió deben seguir siendo suyas.
El cambio de idioma también modifica la dirección. En esta implementación, la parte de la interfaz que corresponde a la página se crea de nuevo cuando cambia esa dirección. Los valores que vivieran solo en el componente anterior desaparecerían con él. Por eso el formulario registra explícitamente los tres datos que debe trasladar:
const name = persisted<string>('contact-name', '');
const email = persisted<string>('contact-email', '');
const message = persisted<string>('contact-message', '');Los identificadores estables importan. “contact-message” sigue representando el mismo campo sin importar si la etiqueta visible está en español, francés o inglés. Una etiqueta traducida sería una mala clave: el cambio de idioma modificaría el nombre que se necesita para recuperar el valor.
Antes de una navegación reconocida como cambio de idioma, el mecanismo recoge los valores registrados, la posición de lectura y la información del control activo. Guarda un registro versionado en el almacenamiento de la sesión. En la página nueva, los controles pueden recuperar sus valores; el foco y la posición se restablecen después de mostrarla y el registro de traslado se elimina. Es un paso entre páginas, no una promesa de conservar mensajes sin terminar para siempre.
La función también prepara los valores antes de que se vea el control nuevo. Así evita mostrar primero el valor por defecto y reemplazarlo después. En una sección desplegable, la misma idea evita abrir la tarjeta un instante antes de recuperar su estado cerrado.
La implementación distingue entre el hecho de que un envío fue exitoso y las frases traducidas que lo describen. Puede conservar ese resultado y reconstruir la confirmación en el idioma nuevo. Guardar la frase anterior dejaría una parte de la interfaz en el idioma previo.
Es un mecanismo concreto para valores registrados, no una afirmación de que todas las rutas entre idiomas estén resueltas. El enlace de contacto de un diagrama francés también necesita llegar a la versión francesa. Elegir ese destino y conservar el mensaje son responsabilidades diferentes. Ambas importan para quien usa el sitio.
El sitio toma referencias de la señalización del transporte público, los planos de rutas, el dibujo técnico y las ventanas de terminal. El naranja y el amarillo aparecen como puntos de referencia. Las marcas de secciones y el tablero de destinos mantienen ese interés a lo largo de las páginas. La referencia es personal, pero los componentes tienen funciones comunes: explicar una relación, identificar una acción o facilitar el recorrido de una página larga.
Los tokens de diseño les dan nombre a decisiones compartidas. Un componente puede usar un papel como color principal, borde o duración de movimiento, en vez de inventar otro valor aislado. El sitio también tiene decisiones propias de estilo y distribución. Reutilizar componentes básicos no obliga a que todas las páginas tengan la misma composición.
El paquete consumidor registra de dónde vienen sus recursos compartidos. Las copias versionadas mantienen una versión revisada disponible para la web, y un control de integridad puede compararla con la adopción registrada. Así se distingue el desarrollo del sistema compartido de su incorporación a este producto. Editar directamente una copia no se convierte automáticamente en una mejora de la fuente común.
La tarjeta desplegable muestra cómo se unen la apariencia y la interacción. Su encabezado es un botón real, con el estado de apertura conectado al componente base. Quien usa un puntero también puede hacer clic en una parte no interactiva de la tarjeta. El manejador deja que enlaces, campos y botones conserven su acción, evita que una tarjeta anidada cambie a su contenedora e ignora el clic que termina una selección de texto.
Esas excepciones tienen un propósito para quien lee. Copiar una frase no debería cerrar la sección. Seguir un enlace debería abrir ese enlace. Hacer clic en el encabezado debería alternar una sola vez, aunque la tarjeta completa también procese clics.
Los temas claro y oscuro, las distribuciones adaptables, las reglas de movimiento reducido y el modo tranquilo agregan otros contextos donde el contenido debe seguir siendo utilizable. La idea visual le da personalidad al sitio. Las piezas compartidas y sus reglas de interacción ayudan a que esa personalidad no estorbe la lectura.
La página de contacto ofrece un formulario corto, un correo directo y un enlace para agendar una llamada introductoria. También da contexto sobre la ciudad, los idiomas de trabajo y los tipos de problemas en los que puedo ayudar.
El formulario sigue una secuencia. Primero revisa nombre, correo y mensaje. Un valor vacío es diferente de una dirección que no pasa la comprobación de formato. Los errores vienen del contenido traducido y señalan el campo correspondiente. Solo un formulario válido llega al envío.
Mientras una solicitud está en curso, el manejador evita otro envío y desactiva el control. El botón informa que está ocupado y cambia su texto visible. La persona no debería tener que adivinar si el primer clic hizo algo.
La solicitud se envía a Web3Forms. Si el servicio informa un fallo o la solicitud produce un error, el formulario registra el problema y termina la indicación de envío. Sale antes de mostrar la secuencia de éxito. La confirmación se basa en la respuesta del servicio, no en una inspección independiente del correo de destino.
Hay además un momento anterior: el intervalo entre la aparición del HTML preparado y la activación del código JavaScript en el navegador. El botón sigue desactivado hasta que su manejador está listo. El código explica la razón: un envío nativo podría recargar la página y poner los datos ingresados en los parámetros de la dirección. El proceso de carga, la privacidad y la información visible se encuentran aquí en una decisión concreta.
Las vistas de escritorio y móvil pueden mostrar distribuciones distintas del formulario. Los identificadores de los elementos incluyen la distribución para que cada etiqueta y descripción de error apunten al control correcto. El identificador usado durante el cambio de idioma sigue siendo independiente de esa presentación: el campo del mensaje representa el mismo dato.
Pensemos en una conexión lenta. La persona envía una vez, ve la indicación de espera y después recibe un error. El resultado útil es un formulario que explica lo ocurrido y permite recuperarse. Una animación de éxito activada por un temporizador sería más fácil de dibujar, pero no contaría el resultado de la solicitud. La secuencia forma parte de lo que hace que contacto sea una función real.
Estos temas son más fáciles de analizar cuando se relacionan con una acción. En el formulario, las etiquetas deben identificar los campos. Un campo con error usa aria-invalid y enlaza su explicación mediante aria-describedby. Un envío en curso expone aria-busy. Esos atributos complementan la información visible, no la reemplazan.
En un artículo largo, el encabezado de una sección debe seguir siendo un control que se pueda usar con el teclado. El índice necesita destinos que correspondan al contenido. Abrir una tarjeta, seleccionar una frase y seguir un enlace son acciones distintas, aunque ocurran en el mismo rectángulo de la pantalla.
Los ejemplos de código tienen su propio tratamiento. El bloque guarda el programa como texto plano. La interfaz puede recibir el resaltado preparado en el servidor; si no está disponible, tiene una presentación simple con el texto escapado. La copia usa el cuerpo del código. Así la explicación sigue siendo legible sin pedirle al navegador que ejecute el ejemplo como parte de la página.
El texto enriquecido común es otro caso, porque el editor puede guardar marcas HTML dentro del texto. Un BlockEditorDoc válido describe una estructura; no establece por sí solo una política completa de limpieza del HTML. Los permisos de edición, el marcado admitido y la forma de mostrarlo requieren su propio análisis. La validación del esquema no reemplaza esa revisión.
De igual forma, comprobar el formato del correo en el navegador ayuda a llenar el formulario, pero no puede ser la autoridad que protege un servicio externo de envío. Una credencial usada para construir el sitio pertenece al entorno de construcción, no a un artículo público ni a los archivos que recibe el navegador. Y excluir una vista previa de los buscadores no la vuelve privada: noindex es una instrucción de indexación, no un control de acceso.
Son responsabilidades concretas que puedo examinar y mejorar. Describen decisiones de implementación, no una certificación de accesibilidad ni una afirmación general de que un sitio es seguro.
Cada comprobación responde una pregunta diferente. La revisión de tipos puede detectar una diferencia entre lo que espera un componente y lo que recibe. Los esquemas pueden rechazar datos del CMS con una estructura incorrecta. Las pruebas unitarias pueden recorrer una transformación o una decisión frente a un fallo. Las pruebas de navegador pueden ejecutar una interacción.
Los esquemas compartidos también comparan, durante la compilación, los tipos que producen con las interfaces escritas por separado. Esto ayuda a hacer visible un cambio de modelo en ambos lados del paso entre CMS y web. Sin esa relación, un campo podría agregarse a una interpretación y desaparecer de la otra.
Las pruebas de exportación cubren casos como una vista previa no autorizada que intenta leer contenido reciente, una espera que supera el tiempo permitido, un archivo de imagen local ausente y un resultado de caché bajo la política estricta. Las pruebas de la tarjeta revisan si el encabezado cambia una sola vez, si un elemento interactivo conserva su acción y si el botón mantiene la información de apertura. Son preguntas útiles porque corresponden a errores concretos.
El flujo de la web revisa tipos, pruebas unitarias, integridad del contenido generado, integridad de las copias de diseño, tokens del producto, el paquete compartido, la construcción y la cantidad de código enviada al navegador. También incluye una etapa de pruebas en el navegador. El CMS tiene sus propias validaciones y operaciones. Su presencia explica cómo se organiza el trabajo; una versión particular todavía necesita sus resultados.
La integridad del contenido generado es fácil de exagerar. El manifiesto registra una huella SHA-256 de cada archivo producido. Si un archivo cambia sin actualizar el manifiesto, la verificación puede detectar la diferencia. También queda registrado si los datos vinieron de una lectura reciente o de caché.
Una huella no evalúa si un párrafo dice la verdad. Si alguien modificara tanto el archivo como su huella, que coincidan no demostraría de forma independiente que el contenido salió del CMS. La comprobación sirve para detectar desviaciones, pero el proceso de publicación y la revisión siguen siendo responsables de la procedencia.
Por eso prefiero una afirmación concreta, como “esta prueba recorre un fallo de exportación”, a una cantidad grande de pruebas presentada como nota de calidad. El número no explica qué error importa, qué se revisó ni en qué puede confiar quien lee.
Cuando una página está mal, primero necesito identificar en qué parte está el problema. El registro del CMS puede conservar el texto anterior. El módulo exportado puede no incluir la última edición. El sitio puede haberse construido correctamente sin ese nuevo exportado. O la dirección pública puede seguir mostrando otro despliegue. Son situaciones diferentes y requieren correcciones diferentes.
Supongamos que un título corregido aparece en Directus, pero no en la página pública. Primero establecería qué registro de idioma se editó, qué origen de datos informó la exportación y a qué construcción y despliegue pertenece la página. Reescribir el componente en ese momento podría esconder un problema de publicación.
Las operaciones sobre el esquema requieren un recorrido distinto al de las correcciones editoriales. El repositorio contiene configuraciones del CMS y herramientas para comparar la estructura prevista con un entorno de destino. Aplicar un cambio puede afectar campos, relaciones o datos existentes. Por eso el flujo separa la validación y las comparaciones de solo lectura de las acciones operativas explícitas. Corregir un párrafo no es la misma operación que cambiar la estructura que lo almacena.
Desarrollo y producción también tienen funciones distintas. Un entorno de desarrollo sirve para revisar un cambio antes de que llegue al sitio público. Una operación en producción necesita el destino correcto, un alcance definido y evidencia de lo ocurrido. Una demostración local exitosa no debería convertirse silenciosamente en una afirmación sobre producción.
El diseño compartido agrega otra pregunta de mantenimiento. Si el problema está en un componente básico usado por varios productos, corregir solo la copia de este sitio puede crear una desviación. Si el problema pertenece únicamente a la distribución de proyectos, moverlo al paquete común puede llevar una suposición del producto a otros contextos. El lugar donde se hace la corrección forma parte del diseño.
Ese es el lado operativo de hacerse cargo de la web: explicar de dónde sale el contenido, dónde corresponde intervenir, qué establecen las verificaciones y qué debe pasar antes de que los visitantes vean una versión nueva.
Las herramientas de IA participaron en la implementación y la revisión. En el artículo que publiqué sobre este proyecto, describo a Claude como la herramienta principal de implementación y a Codex como una herramienta de revisión que también ayudó con algunos cambios. Yo dirigía la arquitectura, mantenía el contexto del proyecto y revisaba los resultados.
La separación del contenido ofrece un ejemplo. Una frase escrita directamente en un componente puede verse igual que una frase que llega del CMS. Encontré textos compartidos que todavía estaban en el frontend, aunque el modelo elegido indicaba que debían editarse en el CMS. Mirar la página no bastaba para encontrar la diferencia; había que seguir los datos en los archivos.
Ese ejemplo conecta las áreas descritas aquí. El resultado visible pertenecía a la web, la fuente prevista pertenecía al editor y el vínculo faltante correspondía a la transformación y exportación. Dar la página por terminada porque se veía bien habría dejado sin resolver el requisito real.
Los fragmentos cortos de código sirven por la misma razón. El esquema muestra qué puede contener una sección controlada desde el editor. La decisión de exportación muestra cuándo los datos de respaldo deben detener una construcción. Los valores registrados del formulario muestran qué información se prevé trasladar al cambiar de idioma. Cada fragmento sostiene una explicación limitada que se puede contrastar con la implementación que lo rodea.
No necesito decir que escribí manualmente cada línea para asumir la responsabilidad del resultado. Sí necesito entender las decisiones que presento, revisar los cambios en vez de aceptarlos por su apariencia y reconocer dónde hace falta investigar más. El código generado, los paquetes externos, los componentes compartidos y mis decisiones contribuyen al producto. Mi revisión tiene que considerar cómo se relacionan.
Cómo un portafolio trilingüe conecta SvelteKit, Directus y una publicación verificada, con contenido estructurado y un formulario que conserva el borrador.
Construyamos algoque se mueva.
Base de datos, pipeline, tablero, sitio web: donde se atasca la cosa, ahí empezamos.