Aplicación web para que empresas PYME de logística controlen y gestionen los costes de Demurrage & Detention (D&D) de contenedores marítimos.
- ¿Qué es Fluster?
- Demo
- Características principales
- Stack tecnológico
- Estructura del proyecto
- Inicio rápido
- Desarrollo local (sin Docker)
- Datos de prueba (seed)
- Uso / Primeros pasos
- Variables de entorno
- Pruebas
- Documentación
Las empresas PYME de logística (importadores, transitarios, transportistas) gestionan contenedores marítimos con hojas de cálculo, fotos por WhatsApp y correos dispersos. Cuando un contenedor supera los días libres acordados con la naviera, comienzan a acumularse costes de Demurrage (contenedor en puerto) y Detention (contenedor con el cliente), que pueden alcanzar cientos de euros por día.
Fluster centraliza todo el ciclo de vida del contenedor, calcula automáticamente los costes D&D según tarifas por tramos, y ofrece un semáforo de riesgo visual para actuar antes de que los costes se disparen.
| Entorno | URL |
|---|---|
| Frontend | https://fluster-frontend.onrender.com |
| Backend API | https://fluster-vd09.onrender.com |
| Documentación API (Swagger) | https://fluster-vd09.onrender.com/api-docs |
| Diseño Figma | Archivo de diseño |
| Prototipo interactivo | Prototipo navegable |
| Wireframes | Wireframes |
| Diagrama de flujo (FigJam) | Diagrama de Flujo — Fluster |
| GitHub Projects | Tablero de planificación |
- Ciclo de vida completo del contenedor — registro de eventos con foto, timestamp y código BIC a lo largo de los estados INACTIVO, PUERTO y CLIENTE.
- Cálculo automático de D&D — costes calculados en tiempo real mediante tablas de tarifas por tramos configurables por naviera.
- Semáforo de riesgo visual — indicador verde/naranja/rojo basado en los días libres restantes para anticipar costes.
- OCR con Tesseract.js — lectura y validación automática del código BIC del contenedor a partir de una foto.
- Generación de informes PDF — exportación de resumen de costes con jsPDF para cotejar con las facturas de las navieras.
- Control de acceso por roles — admin, gestor y operador con permisos diferenciados.
- Documentación interactiva — Swagger UI disponible en
/api-docs. - Tema claro/oscuro — alternancia de tema persistente en la interfaz.
- Despliegue con Docker Compose — entorno completo reproducible en un solo comando.
Fluster/
├── backend/ # API REST (Express + MongoDB)
│ ├── src/
│ │ ├── routes/ # Definición de endpoints
│ │ ├── controllers/ # Entrada/salida HTTP
│ │ ├── services/ # Lógica de negocio
│ │ ├── models/ # Esquemas de Mongoose
│ │ ├── middlewares/ # Auth, roles, errores
│ │ ├── scripts/ # Seed de datos
│ │ ├── app.js # App Express (sin arrancar el servidor)
│ │ └── index.js # Punto de entrada (arranque)
│ ├── tests/ # Tests unitarios y de integración (Jest)
│ └── Dockerfile
├── frontend/ # SPA (React + Vite)
│ ├── src/
│ │ ├── components/ # Atomic Design: átomos, moléculas, organismos
│ │ ├── pages/ # Vistas por ruta
│ │ ├── hooks/ # Hooks reutilizables
│ │ ├── services/ # Cliente HTTP (Axios)
│ │ └── styles/ # ITCSS + SCSS
│ ├── tests/ # Tests Vitest (unitarios) y Playwright (e2e/)
│ ├── nginx/ # Configuración del reverse proxy
│ └── Dockerfile
├── docs/ # Documentación del proyecto (01–10 + diseño)
├── .github/workflows/ # CI, CD, Docker y escaneo de seguridad
└── docker-compose.yml # Orquestación de los 3 servicios
Requisitos previos: Docker y Docker Compose instalados.
# 1. Clonar el repositorio
git clone https://github.com/Agsergio04/Fluster.git
cd Fluster
# 2. (Opcional) Para una prueba local no hace falta configurar nada: el compose
# ya usa la Mongo del propio stack y un JWT_SECRET por defecto. docker compose
# NO lee backend/.env; para fijar tu propio secreto, expórtalo o ponlo en un
# .env en la RAÍZ del repo (compose lo sustituye en ${JWT_SECRET}):
# echo "JWT_SECRET=una_clave_larga_y_aleatoria" > .env
# 3. Levantar todos los servicios
docker compose up --buildAl arrancar, Docker siembra automáticamente la base de datos local (servicio seed de un solo uso): crea el administrador y los datos de demostración antes de poner en marcha el backend, usando la Mongo del propio stack (no el cluster Atlas). Inicia sesión como administrador con sergioaragongarcia@gmail.com / Sergio1234 (ver la tabla de usuarios de prueba).
Una vez iniciado, la aplicación estará disponible en http://localhost (puerto 80, servido por nginx). La API es accesible a través del proxy en http://localhost/api.
Si prefieres ejecutar los servicios directamente (por ejemplo, para desarrollar con recarga en caliente), necesitas Node.js 22+ y una instancia de MongoDB (local o Atlas).
# 1. Clonar el repositorio
git clone https://github.com/Agsergio04/Fluster.git
cd Fluster
# 2. Backend
cd backend
npm ci
cp .env.example .env # configurar MONGO_URI, JWT_SECRET (y CORS_ORIGIN si aplica)
npm run dev # arranca en http://localhost:3000 con recarga (nodemon)
# 3. Frontend (en otra terminal)
cd frontend
npm ci
cp .env.example .env # configurar VITE_API_URL=http://localhost:3000/api
npm run dev # arranca en http://localhost:5173 (Vite)El frontend de desarrollo (Vite) queda en http://localhost:5173 y llama al backend mediante la variable VITE_API_URL.
Con Docker estos scripts se ejecutan automáticamente al arrancar (servicio
seed), así que no necesitas lanzarlos a mano. Los comandos siguientes son para el flujo de desarrollo local sin Docker.
El backend incluye scripts para poblar la base de datos sin tener que crear los datos a mano:
cd backend
# Crear un usuario administrador inicial
npm run seed
# Poblar la BD con datos de demostración (usuarios, navieras, clientes,
# contenedores en distintos estados, ciclos y eventos)
npm run seed:datosTras npm run seed:datos, la consola muestra los usuarios creados (correo y rol). Hay un usuario de cada tipo para probar la aplicación, con estas credenciales:
| Rol | Correo | Contraseña | Notas |
|---|---|---|---|
| admin (protegido) | sergioaragongarcia@gmail.com |
Sergio1234 |
Administrador principal. No se le puede quitar el rol de admin ni eliminar (en el panel de control aparece como «Rol protegido» con los botones deshabilitados). |
| admin | admin@fluster.com |
Admin1234 |
Segundo administrador (sí editable). |
| gestor | gestor2@fluster.com |
Test1234 |
Seguimiento, tarifas, almacén e informes. |
| operador | operador2@fluster.com |
Test1234 |
Meter contenedores y registrar eventos. |
El administrador
sergioaragongarcia@gmail.comestá marcado como protegido (protegido: true): la API rechaza con 403 cualquier intento de cambiarle el rol o eliminarlo, de modo que el sistema siempre conserva su administrador principal.
Tras arrancar la aplicación y poblar la base de datos con npm run seed:datos, abre el frontend e inicia sesión con uno de los usuarios de prueba de la tabla anterior (admin, gestor u operador).
Flujo básico según el rol:
- Operador — Meter contenedor: sube una foto y el OCR lee el código BIC (o introdúcelo a mano) y consulta sus contenedores.
- Gestor — configura las Tarifas por naviera, vigila el Semáforo de riesgo D&D, gestiona el Almacén (entrada a puerto, salida a cliente y devolución) y genera Informes en PDF.
- Admin — administra los usuarios y sus roles desde el Panel de control.
La guía completa paso a paso, con capturas y detallada por rol, está en el Manual de usuario.
El archivo backend/.env debe contener las siguientes variables:
| Variable | Descripción | Ejemplo |
|---|---|---|
MONGO_URI |
URI de conexión a MongoDB Atlas | mongodb+srv://user:pass@cluster.mongodb.net/fluster |
PORT |
Puerto en el que escucha el servidor Express | 3000 |
JWT_SECRET |
Clave secreta para firmar los tokens JWT | una_clave_secreta_larga_y_aleatoria |
CORS_ORIGIN |
Orígenes permitidos por CORS, separados por comas. Si se omite, se permite cualquier origen (solo recomendable en local) | https://fluster-frontend.onrender.com |
El archivo frontend/.env debe contener:
| Variable | Descripción | Ejemplo |
|---|---|---|
VITE_API_URL |
URL base de la API que consume el frontend | http://localhost:3000/api |
| Ámbito | Comando | Herramienta |
|---|---|---|
| Backend (unitarios + integración) | cd backend && npm test |
Jest + mongodb-memory-server + Supertest |
| Backend (con cobertura) | cd backend && npm run test:coverage |
Jest |
| Frontend (unitarios) | cd frontend && npm test |
Vitest + React Testing Library |
| Frontend (end-to-end) | cd frontend && npm run test:e2e |
Playwright |
La integración continua (GitHub Actions) ejecuta los tests del backend y la build del frontend en cada push y Pull Request a main y dev.
| # | Documento | Descripción |
|---|---|---|
| 01 | Introducción | Origen, objetivos, análisis comparativo y alcance del MVP |
| 02 | Descripción del sistema | Visión general del sistema y sus componentes |
| 03 | Instalación | Guía de instalación y configuración del entorno |
| 04 | Guía de estilos | Convenciones de código, SCSS/ITCSS y Atomic Design |
| 05 | Diseño | Diagrama ER, casos de uso, diagramas de flujo, arquitectura y diseño de la API REST |
| 06 | Desarrollo | Secuencia de sprints, decisiones técnicas y fragmentos de código representativos |
| 07 | Pruebas | Estrategia de tests, cobertura y ejecución con Jest (backend) y Vitest (frontend) |
| 08 | Despliegue | CI/CD con GitHub Actions, configuración de Render y Docker |
| 09 | Manual de usuario | Guía de uso por rol: admin, gestor y operador |
| 10 | Conclusiones | Valoración del proyecto, mejoras futuras y aprendizajes |
- Diseño de Interfaces Web — índice con todos los RA y sus evidencias:
docs/diseño/README.md. - Despliegue de Aplicaciones Web — criterios C1, C2, C7 y C8 con evidencias (RA1 a recuperar):
docs/08-despliegue-eval.md.
Las contribuciones son bienvenidas. Consulta la guía de contribución completa para los detalles de entorno, convención de commits y proceso de Pull Request, y respeta el Código de Conducta. En resumen, el flujo de trabajo es:
- Crear una rama desde
devcon un nombre descriptivo (feat/nombre-featureofix/descripcion-bug). - Desarrollar y añadir tests si corresponde.
- Abrir una Pull Request hacia
dev. Los checks de CI (lint + tests) deben pasar antes de hacer merge. - Las releases a producción se realizan mediante PR de
devamain.
Por favor, respeta el estilo de código existente y añade tests para cualquier nueva funcionalidad: Jest en el backend (backend/tests/) y Vitest en el frontend (frontend/tests/).
Los cambios entre versiones se documentan en el CHANGELOG.
El proyecto incorpora medidas de seguridad básicas: autenticación JWT con roles, contraseñas hasheadas con bcrypt, cabeceras HTTP con Helmet, CORS configurable, escaneo de dependencias con Dependabot y de vulnerabilidades con Trivy en CI.
Si descubres una vulnerabilidad, no abras un issue público: sigue la política de seguridad.
Distribuido bajo la licencia MIT. Consulta el archivo LICENSE para más información.
Cuentas de prueba, una por cada rol, para evaluar la aplicación. Se crean al sembrar la base de datos (npm run seed:datos):
| Rol | Nombre | Correo | Contraseña |
|---|---|---|---|
| Operador | Juan José Arias | juanjoseariaslozano@gmail.com |
Juanjosearias1@ |
| Gestor de operaciones | Selena López | selenalopez@gmail.com |
Selenalopez1@ |
| Administrador | Pablo Amosa | pabloamosa@gmail.com |
Pabloamosa1@ |
Qué puede hacer cada rol:
- Operador — Meter contenedor: sube una foto y el OCR lee el código BIC (o se introduce a mano), y consulta sus contenedores.
- Gestor de operaciones — seguimiento de contenedores en el Semáforo, gestión de Tarifas, Almacén y generación de informes PDF.
- Administrador — además de lo anterior, el Panel de control para gestionar usuarios y sus roles.
Estas cuentas existen tras ejecutar el seed. Si evalúas la aplicación desplegada, deben estar creadas en su base de datos (ejecutar el seed apuntando a ella).