Portfolio

Desarrollo E-commerce: haveabook.pl

Haveabook.pl es una plataforma dedicada a publicación e impresión, preparada para clientes exigentes de países escandinavos.

#Sitios web
Desarrollo E-commerce: haveabook.pl

#haveabook.pl - soluciones editoriales e impresión para clientes escandinavos

El sitio haveabook.pl presenta los servicios editoriales y de impresión de una imprenta que trabaja para clientes escandinavos, permite pedir presupuesto y documenta los trabajos realizados. La entrega fue en 2015 y el proyecto llevó unas seis semanas.

#Aquí el producto no tiene precio, tiene una función que lo calcula

La diferencia principal entre este proyecto y una tienda en línea corriente cabe en una frase: aquí el producto no tiene precio. Un libro que se va a imprimir es un conjunto de parámetros, y el precio es el resultado de una operación sobre ese conjunto. Formato, gramaje del papel, número de páginas, tipo de encuadernación, color o negro, tirada, acabados. Cada uno de ellos cambia el resultado y varios lo cambian a saltos.

Esto no se resuelve con una tarifa. El número de combinaciones crece de forma multiplicativa, así que escribirlas todas como filas de catálogo deja de ser viable a partir del tercer parámetro. El cálculo tiene que hacerse bajo demanda, a partir de una estructura de tarifas, y no leerse de una lista. Eso, a su vez, condiciona el resto de la arquitectura, porque los datos de entrada llegan de un formulario y el resultado debe aparecer enseguida y ser reproducible.

Hay una segunda característica del sector, menos evidente y fácil de pasar por alto en el código. El coste de imprimir no crece de forma lineal con la tirada, porque preparar la máquina cuesta lo mismo para cien ejemplares que para diez mil y ese coste se reparte entre la tirada. Además, cambiar de formato puede llevar el trabajo a otra máquina o a otro pliego, lo que mueve el coste a saltos y no de forma continua. Una implementación ingenua que interpola entre dos puntos de la tarifa da resultados correctos en mitad del intervalo y falsos justo en los umbrales, es decir, allí donde el cliente pregunta más. El cálculo tiene que reproducir los umbrales, no una curva trazada a través de ellos.

#El cliente: Have a Book, de Gdynia

Have a Book es una empresa de Gdynia que opera desde 2007, con sede en la calle Wierzbowa y varias decenas de empleados. Se describe como un único punto de contacto para editoriales educativas en Europa: maquetación y preimpresión, diseño gráfico, tipografía, impresión y encuadernación, además de conversión de publicaciones a formatos electrónicos atendiendo a la accesibilidad según WCAG. Sus clientes son editoriales educativas de Noruega, Francia, Suiza y Bélgica.

Ese perfil de comprador decide la forma del sitio. Una editorial educativa no compra por impulso ni compra un libro: compra una serie de títulos en varias variantes, y la decisión la toma un equipo en el que alguien mira el presupuesto, alguien el plazo y alguien más si la imprenta resuelve un tipo concreto de encuadernación en un manual que se abrirá a diario durante tres años. Un sitio que sostiene esa decisión necesita tres cosas a la vez: precio, plazo y prueba de la calidad de ejecución.

El mercado escandinavo añade sus propias exigencias. El sitio sirve contenido en sueco, noruego y danés además de en inglés, y eso significa bastante más que cuatro juegos de traducciones.

#Cuatro idiomas no son cuatro juegos de traducciones

El error más común en proyectos multilingües consiste en tratar el idioma como una etiqueta puesta sobre los mismos datos. Frente al mercado escandinavo, esa simplificación se rompe en un punto que nadie revisa antes de la entrega: la ordenación de listas.

Los alfabetos sueco y dano-noruego contienen caracteres que el inglés no tiene y, lo que importa más, los colocan en otro orden. No es un adorno tipográfico, es una regla de ordenación. Una lista de títulos o de clientes ordenada con una única regla para todos los idiomas estará, para una parte de los lectores, simplemente desordenada. En la búsqueda se suma que una frase escrita sin el signo diacrítico no encuentra la ficha que sí lo lleva. La solución es que la regla de comparación de texto sea una propiedad de la versión lingüística y no un ajuste global de la base de datos.

Lo segundo es distinguir idioma de mercado. Un cliente de Noruega y otro de Suecia pueden leer el sitio en inglés y aun así necesitar formatos de papel distintos y términos distintos para describir una encuadernación. El modelo de contenido tiene que admitir que la variante lingüística y la variante de mercado son dos ejes y no uno. Los sitios que los pegan en uno solo acaban traduciendo los mismos datos por segunda vez solo para cambiar una tabla.

Lo tercero son las direcciones. Cada versión lingüística necesita una URL propia y estable y una declaración de su relación con las demás, porque de lo contrario el buscador enseña la versión inglesa a un editor sueco, y eso en la práctica significa una solicitud de presupuesto que no llega.

#Catálogo y portfolio

El catálogo de servicios es una vista filtrada por categoría, tipo de servicio y especificación. El filtrado ocurre en la consulta y no en el navegador, por la misma razón que en cualquier catálogo técnico: el conjunto crece, y enviarlo entero al navegador deja de compensar mucho antes de que nadie lo note probando con datos de ejemplo.

El catálogo tiene además una propiedad que lo separa de un catálogo de productos. Una línea de la oferta de una imprenta no es una cosa, es una capacidad de ejecución, y se describe con rangos: de tantas a tantas páginas, en estos formatos, sobre papel de este gramaje, con esta encuadernación. Llevado al modelo de contenido, eso significa que el atributo de una ficha a veces es un intervalo y no un valor, y que el filtro por especificación tiene que preguntar por pertenencia al intervalo y no por igualdad. Los filtros construidos sobre igualdad parecen correctos durante la construcción y recortan en silencio media oferta en cuanto alguien escribe un número de páginas que no figura entre las variantes listadas.

El portfolio cumple aquí una función que no cumple en la mayoría de sitios de servicios. Un editor juzga una imprenta por el aspecto del libro terminado, y una foto de portada en baja resolución no dice nada sobre cómo se comporta el lomo al cabo de un año ni sobre cómo cae el color en un papel concreto. Las galerías tienen que mostrar detalle, es decir, archivos grandes, y de ahí viene el trabajo específico para que la página de galería no lo cargue todo de golpe. Primero las vistas previas, las versiones completas al abrir, y los archivos servidos desde la red de distribución de contenido y no desde el servidor de aplicación.

#Desafíos de desarrollo y soluciones

La primera decisión fue dónde vive la lógica de cálculo. Tienta calcular el precio en el navegador, porque así el resultado aparece al instante y no cuesta ninguna petición. Tentador y equivocado, porque la estructura de tarifas queda pública y una copia de la lógica en el navegador se desvía del servidor al primer cambio de tarifa que nadie traslade en ambos sentidos. El cálculo vive en el servidor, y el navegador se limita a reunir parámetros y mostrar el resultado.

El segundo reto fue la reproducibilidad. Un precio dado el lunes tiene que poder reconstruirse el jueves, aunque la tabla de tarifas haya cambiado entretanto. Por eso junto al presupuesto se guarda el conjunto completo de parámetros y la versión de la estructura de tarifas con la que se calculó, no solo la cifra. Sin eso, cada cambio de tarifas invalida el histórico y no se puede responder a la pregunta sencilla de por qué el cliente vio ese importe. La misma decisión ordena la caché: la clave del resultado guardado debe contener la versión de tarifas, porque si no el sitio sigue devolviendo importes viejos durante un tiempo tras la actualización, y lo hace sin dejar rastro en los registros.

El tercer reto fue el rendimiento con mucho material multimedia. La caché en memoria, con Redis y Memcached, acorta el trabajo de base de datos para lo que en cualquier caso pasa por la capa de aplicación: conjuntos del catálogo, tablas de tarifas, ajustes. La red de distribución se ocupa de los archivos. Son dos problemas distintos y conviene separarlos de forma explícita, porque se confunden a menudo: la caché en memoria no acelera la descarga de una imagen a resolución completa, y una capa de borde no acorta ninguna consulta a la base de datos.

El cuarto reto fue recibir archivos. Un encargo de impresión no es un carrito, es una orden de producción con material adjunto. El archivo de impresión suele ser grande, y enviarlo por un formulario corriente falla contra los límites del servidor y contra las conexiones que se cortan. A eso se suma que un archivo que se ve bien en el navegador puede ser inservible en producción porque tiene un espacio de color equivocado o le faltan sangrados. La comprobación inicial en el momento de recibirlo forma parte del proceso y no es un añadido, porque detectar ese fallo al recibir el encargo cuesta un minuto y detectarlo junto a la máquina cuesta la tirada entera.

El quinto reto fue la sincronización con los sistemas de la empresa: calendarios de producción y datos de disponibilidad de material. La solución es que la aplicación no consulta al sistema de producción mientras genera una página. Los datos se traen de forma independiente y se guardan en caché con un tiempo de vida elegido por separado para cada fuente, porque un calendario de producción cambia de otra manera que una tabla de tarifas. Lo más importante, sin embargo, es el comportamiento ante un fallo: cuando la fuente no está disponible, la vista muestra el último valor conocido o una variante sin esa sección, nunca un mensaje de error. El visitante no tiene por qué enterarse de que un sistema interno no responde en este momento.

#Herramientas y tecnologías

El servidor corre sobre PHP y MySQL, la capa interactiva sobre JavaScript y puntos de entrada propios, y los caminos rápidos de lectura sobre caché en memoria. La infraestructura es de nube y el código va en control de versiones, lo que en este proyecto tiene un significado concreto: la tabla de tarifas es un dato y las reglas que la aplican son código, y solo separar ambas cosas permite cambiar precios sin desplegar y cambiar una regla sin tocar los precios.

La capa de presentación se apoya en estándares responsive y en un preprocesador de hojas de estilo que mantiene los puntos de ruptura en un solo sitio. En un sitio con un formulario de más de diez campos eso no es cosmética. El formulario de presupuesto es la vista más importante del proyecto y a la vez la más difícil de componer en pantalla estrecha, porque los campos están relacionados entre sí y un cambio en uno suele verse en otro.

#La accesibilidad forma parte de lo que vende el cliente

Conviene señalar algo que no suele aparecer en la descripción de un proyecto. Have a Book convierte publicaciones a formatos electrónicos atendiendo a la accesibilidad según WCAG, es decir, vende una competencia que el sitio tiene que saber demostrar. La consecuencia es sencilla e incómoda: la web de una empresa que vende publicaciones accesibles no puede tener un catálogo inmanejable con teclado ni tablas de especificación sin relación entre encabezados y celdas.

Una tabla de parámetros técnicos sin esa relación es, para un lector de pantalla, una sucesión de números sin sentido, y en este sitio las tablas de especificación son el contenido principal. Lo mismo pasa con el formulario de presupuesto: los campos relacionados lógicamente deben estarlo también en el marcado, porque si no la información de que elegir una encuadernación ha limitado los formatos disponibles llega solo por vía visual, y solo a quien esté mirando la parte correcta de la pantalla.

#Soporte y desarrollo del servicio

El mantenimiento cubre actualizaciones, monitorización y cambios corrientes. En un sitio con calculadora se añade una obligación que una web de presentación no tiene: los cambios en la estructura de tarifas hay que comprobarlos contra datos históricos. Un cambio que parece correcto en un ejemplo puede desplazar el resultado en otro umbral de tirada, y de eso se entera antes el cliente que recibe un importe que no cuadra con el de la semana pasada.

Las actualizaciones pasan primero por una copia de producción, y no es una formalidad. Una instalación vacía no tiene un catálogo de este tamaño, ni cuatro versiones lingüísticas de la misma ficha, ni galerías con archivos a resolución de producción, ni un conjunto de presupuestos guardados con distintas versiones de tarifa. Esas cuatro cosas son exactamente donde se rompen las actualizaciones, y ninguna de ellas aparece en un entorno de pruebas levantado desde cero.

Las copias de seguridad siguen la regla de siempre: una copia que nadie ha restaurado es un archivo, no una copia. Aquí se suma que los archivos enviados por los clientes son material de producción y no contenido del sitio, y que perderlos es un suceso de otra categoría que perder la descripción de un servicio.

#Resumen y análisis de requisitos del cliente

haveabook.pl tenía que responder a cuatro requisitos a la vez. Primero, presentar una oferta que no se deja describir con una tarifa, porque el precio es el resultado de una operación sobre parámetros. Segundo, servir cuatro versiones lingüísticas, tres de ellas escandinavas, con las reglas de ordenación propias de cada una. Tercero, conectarse con los sistemas de la empresa sin trasladar las caídas de estos al sitio. Cuarto, recibir material de producción y no solo pedidos.

De esos cuatro requisitos sale toda la construcción: cálculo en el servidor, versionado de la estructura de tarifas junto al presupuesto guardado, caché con clave que incluye esa versión, separación de los ejes de idioma y de mercado en el modelo de contenido, y una capa de entrega de archivos mantenida lejos del servidor de aplicación. Lo que no se traslada a otro proyecto es ese modelo de contenido ni esas integraciones, escritos para una empresa y un briefing de la categoría Sitios web. Un segundo proyecto arranca con un análisis de alcance, y el presupuesto va después.

FAQ del artículo

Preguntas frecuentes

Respuestas prácticas para aplicar el tema en la ejecución real.

SEO-readyGEO-readyAEO-ready4 Q&A
¿Qué alcance tuvo el proyecto haveabook.pl?#
haveabook.pl es un proyecto de la categoría Sitios web, entregado en 2015. Detrás están PHP, JavaScript, Redis, MySQL y HTML5.
¿Cómo fue la entrega de haveabook.pl?#
La construcción duró unas seis semanas y salió a producción en 2015. Se apoya en PHP, JavaScript, Redis, MySQL y HTML5. El layout lo puso el cliente. Sobre él construí las plantillas y el modelo de contenido, y probé las rutas que llevan tráfico en una copia de producción, no en una instalación vacía.
¿Qué fue lo más difícil técnicamente en haveabook.pl?#
Rendimiento bajo tráfico real y caché. haveabook.pl necesitaba un entorno de pruebas cercano a producción.
¿Qué parte de haveabook.pl se puede reutilizar en otro proyecto?#
La capa técnica se traslada: PHP, JavaScript, Redis, MySQL y HTML5. En el siguiente proyecto se parece bastante. Lo que no se traslada es el modelo de contenido ni las integraciones, escritos contra los datos de un cliente y un briefing de la categoría Sitios web. Un segundo proyecto arranca con un análisis de alcance, y el presupuesto va después.

¿Necesitas un FAQ adaptado a tu sector y mercado? Preparamos una versión alineada con tus objetivos de negocio.

Hablemos