Uno de los proyectos en los que he estado trabajando últimamente, y que es otro de los proyectos en los que he usado IA generativa, ha sido el desarrollo de una aplicación destinada a gestionar de manera masiva las fechas de fotografías digitales.

El Problema: Una Cámara Kodak con Fecha de Caducidad
El motivo por el que empecé a pensar en este desarrollo fue que una de mis cámaras fotográficas, una veterana Kodak EasyShare P712. A pesar de su antigüedad, sigue sigue siendo una cámara fotográfica con una óptica estupenda, que permite sacar fotografías estupendas pese a sus 7.1 megapíxeles de resolución. Sin embargo, como muchos dispositivos electrónicos de cierta edad, tiene una limitación importante en su firmware: su sistema de fecha no admite valores posteriores al 31 de diciembre de 2025. Esto significa que, a partir de esa fecha, cualquier foto que se tome con ella tendrá una fecha incorrecta en sus metadatos EXIF, lo que dificulta enormemente la organización y gestión cronológica de las fotografías en mi sistema de almacenamiento, que se basa en la utilización de esta información EXIF para mostrar una línea cronológica.

Los metadatos EXIF (Exchangeable Image File Format) son cruciales. No solo registran la fecha y hora de la captura, sino también información sobre la cámara, la exposición, la ubicación GPS (en el caso de teléfonos) y mucho más. Perder la precisión en la fecha es como perder una parte de la historia de cada foto. Ante esta obsolescencia contenida en el firmware, decidí que no iba a dejar que mi Kodak se jubilara antes de tiempo. Existen aplicaciones que permiten cambiar esta información en las fotografías, la mayoría de las veces desde línea de comandos, o bien de manera individualizaba. Pero no encontraba soluciones satisfactorias para realizar el cambio de fechas de manera masiva y, sobre todo, conservando las diferencias horarias relativas entre fotografía y fotografía. Y la solución para ello iba a ser el construir una aplicación que me permitiera corregir estas fechas de forma sencilla y eficiente.
Una solución software: Aplicación Editor de Fecha EXIF
Así nació el «Editor de Fecha EXIF de Imágenes». Es una aplicación web diseñada para corregir las fechas de captura (DateTimeOriginal, CreateDate, DateTime) en archivos JPEG, tanto de forma individual como por lotes. Pero la solución no se queda ahí; la aplicación también permite descargar las imágenes corregidas y, lo que es más importante, subirlas directamente a plataformas como Piwigo o a un servidor SFTP.

Para elaborarlo, utilicé dyad como entorno de desarrollo basado en IA. La idea era tener un entorno completamente desplegado en un servidor Debian, sin dependencias externas con Supabase o cualquier otro tipo de plataforma ajena al propio servidor.
El proceso de desarrollo fue guiado tanto en lo referente al frontal, que fue un proceso relativamente sencillo y sin grandes particularidades, como en lo relativo al backend. Esto sí presentó más inconvenientes, ya que Dyad tiene una fuerte apetencia por hacer uso de Supabase, y fue preciso ser muy insistente para conseguir que el desarrollo se orientara hacia un backend convencional.
Características Clave:
- Edición Flexible: Corrige fechas individualmente o aplica correcciones por lotes basadas en una fecha de referencia.
- Previsualización Instantánea: Visualiza las imágenes con sus fechas originales y las fechas corregidas.
- Descarga Segura: Descarga las imágenes procesadas en un archivo ZIP.
- Integración con Piwigo: Configura tus credenciales, navega por tus álbumes, crea nuevos y sube imágenes directamente.
- Integración con SFTP: Conéctate a tu servidor SFTP, navega por directorios, crea carpetas, renombra, elimina y sube tus imágenes corregidas de forma segura.
- Persistencia de Configuración: Todas las configuraciones (servidor EXIF, Piwigo, SFTP) se guardan de forma segura en una base de datos.
Bajo el Capó: Arquitectura y Tecnologías
La aplicación sigue una arquitectura cliente-servidor, dividida en un frontend interactivo y un robusto backend.
Frontend: La Interfaz de Usuario
El frontend está construido con React y TypeScript, lo que nos permite crear una interfaz de usuario dinámica y mantener la robustez del código gracias al tipado estático. Para el estilo, he optado por Tailwind CSS, un framework que facilita la creación de diseños responsivos y atractivos con clases de utilidad. Los componentes de UI provienen de shadcn/ui y Radix UI, garantizando accesibilidad y un aspecto pulido.
La navegación se gestiona con React Router, mientras que la carga de imágenes se simplifica con react-dropzone. Para la manipulación de fechas, date-fns es nuestro aliado, y para la descarga de múltiples imágenes, JSZip se encarga de empaquetarlas en un archivo ZIP. Las notificaciones al usuario se manejan con sonner, proporcionando un feedback claro y conciso.

La modificación de fechas puede realizarse por lotes al conjunto de imágenes, o de manera individual. También es posible corregir tanto fecha y hora como sólo fecha, conservando la hora original de las imágenes. En el caso de la modificación por lotes de fecha y hora, las horas de las imágenes conservarán el diferencial con respecto a la primera imagen del lote que tuvieran originalmente.
Una vez modificadas las fechas, es posible realizar tres acciones con las imágenes:
- Descarga de las imágenes al equipo local: Las imágenes se descargan mediante un fichero zip.
- Subir las imágenes a Piwigo: Es posible definir un servidor Piwigo con el que interactuar. Se dispone de una interfaz de subida de imágenes a esta plataforma, que muestra los álbumes a los que el usuario tiene permiso, y se permite subir imágenes a cualquiera de estos álbumes, o bien definir un álbum nuevo.
- Subir las imágenes a un servidor SFTP: La última opción para almacenar las imágenes es cargarlas a un servidor SFTP. Igual que en el caso anterior, se puede navegar por la estructura de carpetas, y crear subcarpetas de acuerdo a nuestras necesidades.


Backend: El Cerebro de la Operación
El backend, desarrollado en Node.js con el framework Express, es el encargado de la lógica pesada. Aquí es donde ocurre la magia de la edición EXIF.
- Procesamiento EXIF: La joya de la corona es la integración con
exiftool, una potente herramienta de línea de comandos. El backend utilizachild_processpara ejecutar comandos deexiftool, leyendo y escribiendo los metadatos de las imágenes. Esto permite una manipulación precisa y fiable de las fechas. - Gestión de Archivos: Multer se encarga de la subida de archivos desde el frontend, gestionando los datos
multipart/form-data. - Base de Datos: La configuración de Piwigo, SFTP y la URL del servidor EXIF se almacenan de forma persistente en una base de datos MariaDB/MySQL, utilizando el cliente
mysql2/promisepara interacciones asíncronas. - Seguridad: Las credenciales sensibles (como las contraseñas de Piwigo y SFTP) se cifran antes de ser almacenadas en la base de datos, utilizando el módulo
cryptode Node.js con una clave de cifrado definida en las variables de entorno. - Comunicación Externa:
node-fetchyform-datase utilizan para interactuar con la API de Piwigo, permitiendo la autenticación, listado de álbumes, creación de nuevos álbumes y la subida de imágenes. Para SFTP, se utilizassh2-sftp-clientpara la navegación y subida de archivos. - CORS: El middleware CORS está configurado para permitir la comunicación segura entre el frontend (que se ejecuta en un puerto diferente) y el backend.
Comunicación Frontend-Backend
La comunicación entre el frontend y el backend se realiza a través de una API REST. Para simplificar el desarrollo y evitar problemas de CORS en entornos de desarrollo, se utiliza un proxy configurado en vite.config.ts. Este proxy redirige las peticiones a rutas como /exif, /piwigo y /sftp directamente al backend, que escucha en el puerto 8082.
Proceso de Desarrollo
El desarrollo se centró en la modularidad y la reusabilidad. Se crearon componentes específicos para cada parte de la interfaz (como ImageCard para mostrar y editar imágenes individualmente, o los diálogos de configuración para Piwigo y SFTP). El uso de TypeScript fue fundamental para detectar errores en tiempo de desarrollo y mejorar la mantenibilidad del código a medida que la aplicación crecía en complejidad. La separación clara de responsabilidades entre frontend y backend permitió un desarrollo paralelo y una mayor escalabilidad.
Despliegue en un Servidor Debian con Systemd
Para llevar la aplicación a producción, opté por un despliegue robusto y gestionado por Systemd en un servidor Debian. Esto asegura que tanto el frontend como el backend se inicien automáticamente al arrancar el servidor y se reinicien en caso de fallos.
Prerrequisitos del Servidor:
- Node.js y npm: Para ejecutar las aplicaciones.
- MariaDB/MySQL: Para la base de datos de configuración.
- Exiftool: Instalado y accesible en el servidor para el procesamiento de imágenes.
Configuración de la Base de Datos:
Se crea una base de datos y un usuario específico, y se ejecuta un script SQL (database_setup.sql) para crear la tabla piwigo_config, que almacenará las configuraciones de la aplicación.
Despliegue del Backend:
- Los archivos del backend se copian a una ubicación en el servidor (ej.
/var/www/exif-backend). - Se crea un archivo
.envcon la clave de cifrado (¡32 caracteres exactos!) y las credenciales de la base de datos. - Se define un servicio
systemd(exif-backend.service) que especifica el usuario bajo el cual se ejecutará, el directorio de trabajo y el comando de inicio (/usr/bin/node server.js). Este servicio se configura para escuchar en el puerto8082y reiniciarse automáticamente.
Despliegue del Frontend:
- El frontend se construye localmente con
npm run build, generando una carpetadistcon los archivos estáticos. - Esta carpeta
distse copia al servidor (ej./var/www/exif-frontend). - Se instala globalmente el paquete
servede npm en el servidor. - Se crea un servicio
systemd(exif-frontend.service) que utilizaserve -s dist -l 8081para servir los archivos estáticos del frontend en el puerto8081, también con reinicio automático.
Configuración del Firewall:
Es crucial abrir los puertos 8081 (frontend) y 8082 (backend) en el firewall del servidor (por ejemplo, con ufw) para permitir el acceso externo a la aplicación.
Conclusión
Con este proyecto he podido gestionar el inconveniente de las fechas incorrectas que voy a tener en mi cámara Kodak a partir de 2026. Además, me ha permitido explorar y consolidar conocimientos en desarrollo asistido por IA, con trabajos relacionados con el desarrollo web full-stack, seguridad y despliegue en entornos de producción.