GitHub Copilot al mando: colección personal, admin y rediseño en vComics DB (código y post generados por IA)

Nueva entrega de vComics DB con GitHub Copilot (Claude Sonnet 4.6) al mando. Esta vez el salto ha sido especialmente visual y funcional: la app pasa de ser un catálogo de consulta a una herramienta real de gestión personal. Cada usuario puede ahora llevar el registro de sus cómics, gestionar sus colecciones y, si tiene rol de administrador, mantener el catálogo completo desde la propia app.

Y sí, este post también lo ha generado Copilot, con mi supervisión y edición final.


El proyecto

vComics DB es una aplicación web para gestionar colecciones de cómics. Está formada por un frontend en React 18 + Vite y un backend en Spring Boot 3 + Java. Esta entrega construye encima del sistema JWT y del módulo de colecciones introducidos en la iteración anterior, añadiendo la capa de colección personal por usuario, páginas de detalle y un panel de administración.

Código disponible en GitHub:
🖥️ Frontend: github.com/entorno5/front-comics
⚙️ Backend: github.com/entorno5/comics-backend

Nota: Tanto el código como este post han sido generados por GitHub Copilot (Claude Sonnet 4.6) bajo la supervisión del desarrollador. El flujo de trabajo ha sido: indicación → generación → revisión → ajuste → commit. Sin magia negra, con criterio humano encima.

⚙️ Backend Spring Boot — Lo que se ha añadido

👤 Colección personal de cómics por usuario

El cambio más importante del backend en esta iteración. Se ha implementado un módulo completo para que cada usuario autenticado lleve el registro de los cómics que tiene físicamente:

  • UserComic — Nuevo modelo de dominio que representa la relación entre un usuario y un cómic, incluyendo el campo units para registrar cuántas copias tiene.
  • UserComicRepository — Interfaz del repositorio, con implementación en memoria (InMemoryUserComicRepository) para el perfil mock.
  • UserComicService — Lógica de negocio completa: listar con paginación y búsqueda, obtener un cómic concreto, añadir, actualizar unidades y eliminar.
  • MyComicController — Endpoints REST bajo /api/v1/my/comics:
    • GET /api/v1/my/comics — Lista paginada de cómics del usuario, con filtro por texto.
    • GET /api/v1/my/comics/{id} — Obtener un cómic concreto de mi colección.
    • POST /api/v1/my/comics/{id} — Añadir un cómic a mi colección con el número de unidades.
    • PATCH /api/v1/my/comics/{id} — Actualizar el número de unidades.
    • DELETE /api/v1/my/comics/{id} — Eliminar un cómic de mi colección.
  • AddMyComicDTO, UpdateMyComicDTO, UserComicResponseDTO, UserComicPageResponse — DTOs de entrada y salida para el nuevo controlador.

📚 Colecciones personales por usuario

Paralelo al módulo de cómics, se ha añadido la gestión de colecciones propias de cada usuario:

  • UserCollectionService — Lógica para listar, crear, actualizar y eliminar colecciones de un usuario concreto.
  • MyCollectionController — Endpoints REST bajo /api/v1/my/collections para CRUD completo de colecciones personales.
  • CreateCollectionDTO — DTO de entrada para crear o editar una colección.
  • CollectionPageResponse — Respuesta paginada para el listado de colecciones.

📄 Paginación en el catálogo de colecciones

El CollectionController y el CollectionService se han extendido significativamente para soportar paginación real (parámetros page, size y q) y devolver los cómics que pertenecen a cada colección. El ComicService también ha recibido mejoras para soportar filtros adicionales desde el catálogo.

🔧 Configuración y tests

  • application-dev.properties — Nuevo fichero de configuración específico para el perfil de desarrollo, separando valores sensibles del properties principal.
  • SecurityRulesTest — Tests de integración que verifican que los endpoints protegidos devuelven 401 sin token y 200 con un token válido.
  • CollectionServiceTest — Suite de tests unitarios para el servicio de colecciones, que cubre creación, consulta, actualización y borrado.
  • ComicServiceTest — Extendido con nuevos casos de prueba para los filtros y la paginación.

🎨 Frontend React — Lo que se ha añadido

📖 Página de detalle de cómic

Nueva página ComicDetail accesible desde cualquier tarjeta del catálogo. Muestra la información completa del cómic y, si el usuario está autenticado, permite:

  • Ver si el cómic ya está en su colección personal.
  • Añadirlo con un clic.
  • Editar el número de unidades directamente en la página.
  • Eliminarlo de su colección.

La carga es paralela: se piden simultáneamente los datos del cómic del catálogo y el estado personal del usuario para ese cómic, usando Promise.all.

🗂️ Página de detalle de colección

Nueva página CollectionDetail que muestra todos los números (issues) de una colección. Para cada issue se puede marcar si está en la colección personal del usuario, toggling entre añadir y eliminar directamente desde la lista. Funciona tanto para colecciones propias como para colecciones publicadas del catálogo general.

🛡️ Panel de administración

Nueva página Admin, accesible únicamente para usuarios con rol de administrador:

  • Interfaz de pestañas para alternar entre el panel de Colecciones y el de Cómics.
  • CollectionsPanel — Gestión completa del catálogo de colecciones: listar con scroll infinito, crear, editar y eliminar.
  • ComicsPanel — Gestión completa del catálogo de cómics con las mismas operaciones.
  • AdminRoute — Componente protector que redirige a home si el usuario no tiene el rol ADMIN.

🧭 PageNav — Navegación unificada

Se ha creado un componente PageNav que reemplaza las distintas cabeceras que existían, ofreciendo una navegación consistente en toda la app:

  • Acceso a Inicio, Mis cómics, Mis colecciones, Cómics publicados y Colecciones publicadas.
  • Si el usuario es administrador, aparece además el enlace a Gestión.
  • Botón de logout integrado.
  • Toggle de modo oscuro.
  • Menú hamburguesa en mobile.

♾️ useInfiniteList — Scroll infinito genérico

Nuevo hook useInfiniteList que abstrae el patrón de scroll infinito sobre cualquier endpoint paginado. Recibe una función fetchPage(page, size) y gestiona internamente el estado de items, carga, errores, página actual y la detección del centinela (IntersectionObserver) para disparar la siguiente página. Lo usan los paneles del admin para cargar colecciones y cómics sin límite aparente.

🔌 Nuevos servicios

  • myComicService.js — Consume /api/v1/my/comics: obtener lista, añadir, actualizar unidades, eliminar y obtener todos los IDs de mi colección.
  • myCollectionService.js — Consume /api/v1/my/collections: CRUD completo de colecciones personales.
  • userService.js — Obtiene el perfil del usuario autenticado.
  • apiError.js — Utilidad centralizada para parsear errores de la API y extraer mensajes legibles.
  • comicService.js — Extendido con getComic(id), endpoints filtrados y soporte de paginación.
  • collectionService.js — Extendido con getCollection(id) y getCollectionComics(id) para las páginas de detalle.

🔑 isAdmin en AuthContext

El AuthContext ahora decodifica el JWT y expone el flag isAdmin a toda la aplicación. Esto permite que PageNav muestre u oculte el enlace de administración y que AdminRoute proteja la ruta sin necesidad de llamar al backend.

🖼️ Rediseño visual

Aprovechando la iteración, se ha realizado un rediseño visual completo de varios componentes y páginas:

  • HeroSection — Completamente reescrita con nueva estructura, tipografía y llamadas a la acción más claras. Se elimina el antiguo componente FeatureSection.
  • ComicCard — Nueva imagen de portada con fallback a comic-placeholder.svg, más información visible y mejor accesibilidad.
  • CollectionCard — Rediseñada con más contexto visual.
  • Home, Catalog, Collections — CSS Modules revisados para mayor coherencia visual y mejor comportamiento responsive.
  • IssueRow — Nuevo componente de fila para listar los números de una colección con botón de toggle de propiedad.
  • comic-placeholder.svg — Imagen SVG de relleno para portadas sin imagen.
  • utils/comicImage.js — Función que resuelve la URL de portada de un cómic y devuelve el placeholder si no hay imagen disponible.

✅ Tests

Todo el código nuevo tiene cobertura de tests con Vitest + Testing Library. Los tests existentes se han actualizado para adaptarse al rediseño. Tests nuevos:

  • AdminRoute.test.jsx
  • CollectionsPanel.test.jsx
  • IssueRow.test.jsx
  • PageNav.test.jsx
  • Collections.test.jsx
  • ComicDetail.test.jsx

Stack tecnológico

Frontend React 18, Vite, CSS Modules, React Router v7
Auth Frontend JWT decodificado en cliente, isAdmin desde token, AdminRoute
Tests Frontend Vitest, Testing Library
Backend Spring Boot 3, Java, Maven
Auth Backend Spring Security + JWT (HMAC-SHA256), rutas por rol
Persistencia Repositorios en memoria (perfil mock), separación de perfil dev
Tests Backend JUnit 5, Spring Security test slice, Mockito
IA utilizada GitHub Copilot — Claude Sonnet 4.6 (código + este post)
Control de versiones Git + GitHub

Reflexión final (del humano supervisor)

Esta iteración ha sido la más satisfactoria hasta ahora. La app ha pasado de ser un catálogo de consulta a tener una lógica de usuario real: cada persona puede registrar sus cómics, cuántas copias tiene, y gestionar sus propias colecciones. Y el admin puede mantener el catálogo sin tocar una base de datos.

Lo que más me ha sorprendido esta vez es la consistencia entre capas. Copilot ha generado los DTOs del backend, los servicios del frontend que los consumen y los tests de ambos en el mismo flujo de trabajo, y todo encajaba. Revisé los contratos de la API y los modelos de respuesta, y estaban alineados sin necesidad de corrección manual.

El rediseño visual también ha sido fluido: los componentes tienen mejor aspecto y la navegación es coherente en toda la app. El componente PageNav unifica algo que antes era inconsistente entre páginas.

Código generado por GitHub Copilot (Claude Sonnet 4.6), revisado y supervisado por mí. Este post también. Ya lo sabéis. 😄

Entradas relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *