Skip to main content

Servidor de Reporting

1. Introducción i objetivos

El sistema sirve para gestionar plantillas de reporte y generar documentos como facturas, albaranes, pedidos...

Objetivos principales:

  • Agilizar la edición de plantillas.
  • Agilizar la generación de documentos.
  • Generar diferentes tipos de archivo con una misma plantilla.

2. Requisitos y convenciones

2.1. Requisitos funcionales

IDRequisito
RF1Tiene que haber un endpoint que dada un nombre de plantilla y un conjunto de datos genere un report.
RF2Las plantillas deben de guardarse en una carpeta en el servidor
RF3Debe generar como mínimo en formato PDF.
RF4La respuesta del endpoint que genera el report debe er la ruta al archivo generado.
RF5Se tiene que poder insertarle un código de barras.
RF6Se deben de poder imprimir reports de forma individual. (1 documento -> 1 pdf).
RF7 Se ha de establecer el numero de días que los documentos quedan en el servidor.
RF8Formatos soportados: A4, A5. Vertical u horizontal.
RF9Los documentos tienen que poder tener número de página en formato: "Pág n de m".
 RF10  Los documentos deben de poder tener sumatorios al inicio y fin de las tablas de datos para saber el valor acumulado.
RF11Las plantillas que se pueden guardar deben de ser en formato ODT, DOCX y XLSX.

2.2. Requisitos no funcionales

IDRequisito
RNF1El servidor debe funcionar en Linux, Windows y Mac.
RNF2El servicio debe ejecutarse en un contenedor de Docker.
RNF3Las plantillas y los reportes generados deben estar en un volumen de Docker.
RNF4Rendimiento objetivo: menos de 5 segundos por report.
RNF5Medida de los archivos generados: menos de 200 Kb.

2.3. Convenciones

IDRestricciónTrasfondo y motivación
C1Documentación de arquitecturaEstructura basada en la plantilla arc42
C2CódigoEl proyecto usa las guías de estilo de JavaScript de Google (https://google.github.io/styleguide/jsguide.html)
C3IdiomaLa documentación está en Español y el código en inglés.
C4Plantillas Usamos Carbone.io para guiarnos en la construcción de las plantillas Style guide to design a report(https://help.carbone.io/en-us/article/style-guide-to-design-a-report-z8lv57/). Documentation(https://carbone.io/documentation.html).
C5Códigos de barrasLos tipos de código de barras que usamos són el ean13 y el code128. Si se quiere usar un código de barras se debe poner en el body como "barcode" y en el "barcodeType" el tipo de código de barras. Sólo se pueden añadir en pdf.

3. Estrategia de soluciones

  1. Tencologias del servicio
  • Visual Studio Code: IDE.
  • Node.js 16.x: entorno del servicio.
  • Express.js: framweork de node.js para hacer APIs.
  • Carbone.js: generador de reportes.
  • Multer 1.4.5: middleware para gestionar archivos en node.
  • uuidv4 6.2.13: creador de UUIDs.
  • pdf-lib 1.3.1: crear y modificar documentos pdf en javascript.
  • node-schedule 2.1.1: programador de tareas para node.js.
  • Docker: Automatiza el despliegue de apps y servicios dentro de contenedores para que se puedan ejecutar en distintos sistemas operativos.

4. Vista de bloques

4.1. Nivel 1 - Vista General

El sistema se compone de:

  • API de generación de reportes: Servicio de Node.js que maneja solicitudes para gestionar plantillas y para generar reportes.
  • Sistema de almacenamiento: Volumen de Docker donde se almacenan las plantillas y reportes en la máquina host.
  • Servicio de plantillas: Módulo que maneja la carga y gestión de plantillas.

4.2. Nivel 2 - Vista Detallada

  • API:
    • POST /template: Guarda una plantilla. Se debe pasar el nombre de la plantilla por headers y por el body el archivo a pasar. Admite archivos con formato ODT, DOCX, PDF y XLSX. Se almacena en el volumen de Docker dentro de /reports/out/.
    • POST /report?plantilla=nombrePlantilla&formato=formatoDeSalida: Genera un reporte basado en una plantilla y datos proporcionados.
  • Sistema de alamcenamiento:
    • Volumen docker montado en '/...'

5. Vista de despliegue

5.1 Cómo ejecutar y desplegar el servicio?

Sin docker:

  1. Si lo usas sin docker necesitareis instalar el LibreOffice para la conversión de pdfs. Lo podéis hacer desde aquí
  2. La versión de node que se ha usado es la 18, por lo tanto para que funcione todo correctamente deberias usar esta versión.
  3. Ejecutar:
    1. npm install
    2. npm start
  4. Ya estará escuchando en el puerto 3000. Los ficheros se guardaran en la carpeta del proyecto /reports y /logs.

Con Dockerfile:

  1. Si no existen las carpetas, se deben crear con permisos de lectura y escritura. Debes crear varias carpetas:
    1. /reports
      1. /reports/out
      2. /reports/barcode
      3. /reports/plantillas
    2. /logs
  2. Añadir parámetros en el Dockerfile si no están:
ENV TEMPLATE_PATH=./reports/plantillas/
ENV OUT_PATH=./reports/out/
ENV BARCODE_PATH=./reports/barcode/
  1. Construir imagen de Docker:
docker build -t report-server .
  1. Ejecutar el contenedor (en el source del mount deben ir las variables de entorno que has definido antes en el Dockerfile pero en los reports sin el /out):
docker run --platform linux/amd64 -d --name report-server --mount type=bind,source="$HOME/reports",target=/app/reports --mount type=bind,source="$HOME/logs",target=/app/logs -p 3000:3000 report-server

Dónde $HOME/reports y $HOME/logs son las carpetas del host que se enlazarán con el volumen del contenedor para guardar reports y logs. Si no se añade "--platform linux/amd64" dará un warning en ordenadores con procesador arm64. El mount sirve para mapear la ruta del host a la ruta del contenedor para poder añadir y quitar plantillas manualmente.

  1. Para detener:
docker stop report-server

Con Docker Compose:

  1. Debes hacer el paso 1 del despliegue del servicio con el Dockerfile.
  2. Ahora debes añadir los parámetros en el docker-compose.yml. Por ejemplo:
vincoteam-reporting-api:
image: girosystem.azurecr.io/vincoteam-reporting-api:alpha
restart: unless-stopped
container_name: vincoteam-reporting-api
ports:
- "3000:3000"
volumes:
- /ruta/host/a/reports:/app/reports
- /ruta/host/a/logs:/app/logs
environment:
- REPORTS_HOST_FOLDER=/ruta/host/a/reports/out
- LOGS_HOST_FOLDER=/ruta/host/a/logs
  1. Para iniciar, ejecutar los comandos:
docker compose -f docker-compose-alpha.yml pull
docker compose -f docker-compose-alpha.yml up -d --remove-orphans
  1. Para detener, ejecutar el comando:
docker-compose down

5.2. Entornos

  • Desarrollo: Docker en local.
  • Producción: Servidor de producción con Docker.

5.3. Flujo de despliegue de nuevas versiones

  1. Realizar cambios en el código.
  2. Construir una nueva imagen de Docker.
  3. Detener y eliminar el contenedor antiguo.
  4. Ejecutar un nuevo contenedor con la nueva imagen.

6. Conceptos transversales (Cross-cutting)

6.1. Persistència

Los reportes y las plantillas se almacenan en un volumen de Docker.

6.2. Interfície de usuàrio

No aplicable para este servicio.

6.3. Transacciones

Cada generación de reporte es una transacción única.

6.4. Seguridad

Asegurar que el servicio esté detrás de un firewall y utilizar HTTPS.

6.5. Gestión de errores

Registrar todos los errores y manejar adecuadamente las excepciones.

6.6. Logging

Implementar un sisdema de logging para las solicitudes y los errores.

6.7. Configuraciones

Se usan variables de entorno para definir el puerto en el que escucha el servicio y las rutas de las carpetas dónde se guardan las plantillas y los reportes. Se guardan en el environment.env.

6.8. Localización

El idioma de los reportes dependen de los datos que le pasamos por el body y de las plantillas en si.
Lo que se puede editar es pasándole un campo "lang" en el json del body dónde si por ejemplo en la plantilla pones un formateador para que te lo detecte como valor de moneda, entonces si le pasas "en-us" te dará $, si le pasas "es-es" té pondrá €.

6.9. Testing

El test se ha hecho con jest.
Para ejecutarlo se hace así:

npm test