Evaluador GAN — NutriTrack Dashboard

gan-harness/feedback/feedback-002.md · Agentes IA · CULTIVA IA

Iteración #2
FAIL — 6.2 / 10
Cliente
NutriTrack
SaaS B2B Dietética
Modo evaluación
Playwright
localhost:3000 · Chromium
Iteración anterior
5.4 / 10
+0.8 pts mejora
Umbral de aprobado
7.0 / 10
Faltan +0.8 pts
6.2 / 10

FAIL — No apto para producción

El dashboard ha mejorado visualmente respecto a la iteración #1 pero sigue mostrando síntomas claros de AI-slop: diseño plano sin carácter, tabla de pacientes sin estados de carga, y 3 de 8 features de la spec sin implementar. No está listo para mostrarse a un cliente beta.

Umbral: 7.0 · Diferencia: −0.8 pts · Requiere iteración #3

📊 Rúbrica de puntuación

Criterio Puntuación Barra Peso Ponderada
Diseño visual 6 / 10
×0.3 1.80
Originalidad 5 / 10
×0.2 1.00
Craft (código/interacción) 7 / 10
×0.3 2.10
Funcionalidad (spec coverage) 6.5 / 10
×0.2 1.30
TOTAL PONDERADO 6.20 / 10
Fórmula: (diseño × 0.3) + (originalidad × 0.2) + (craft × 0.3) + (funcionalidad × 0.2)

🔴 Problemas críticos — deben corregirse

Crítico #1
Export PDF no implementado (Feature #5 de la spec)
El botón "Exportar informe" existe visualmente pero al hacer clic lanza un console.error: exportPDF is not a function. 3 clics seguidos no provocan ninguna respuesta visual. La función está marcada como // TODO en el código.
Cómo corregirlo
Implementar con @react-pdf/renderer. Mínimo: window.print() con estilos @media print. Mostrar spinner durante la generación. Deshabilitar el botón con disabled mientras procesa.
Crítico #2
Estado vacío ausente en la tabla de pacientes
Con 0 pacientes la tabla renderiza una fila vacía con los encabezados flotando sobre un fondo blanco roto. El spec requiere un empty state explícito. Se probó borrando todos los pacientes del mock: resultado — pantalla rota sin mensaje.
Cómo corregirlo
Añadir condicional: if (patients.length === 0) return <EmptyState />. Componente EmptyState debe mostrar: icono ilustrado, título "Aún no tienes pacientes", subtítulo, y CTA "Invitar primer paciente".
Crítico #3
Sin manejo de error de red — pantalla en blanco
Simulando fallo de red (DevTools → Network offline) la página queda en blanco con spinner infinito. No hay timeout, no hay retry, no hay mensaje de error. El spec requiere explícitamente manejo de datos corruptos y errores de red.
Cómo corregirlo
Envolver fetches con try/catch. Usar React Query o SWR para gestionar estados isError. Mostrar <ErrorBanner message="No se pudo cargar..." retry={refetch} /> tras 5s de timeout.

🟡 Problemas mayores — deberían corregirse

Mayor #1
Diseño sin carácter — AI-slop de segunda generación
Se eliminaron los gradientes azul-morado de la iteración #1 (bien), pero el reemplazo es un fondo gris liso #f5f5f5 sin ninguna identidad visual. Los cards son cajas blancas genéricas con box-shadow de Tailwind por defecto. Parece un boilerplate sin personalizar.
Cómo corregirlo
Aplicar la paleta de marca NutriTrack: verde salud (#2d9b6f) como primario. Los KPI cards deben tener un acento de color sutil en el borde izquierdo, no un shadow genérico. Crear un archivo theme.ts con todos los tokens.
Mayor #2
Tabla de pacientes sin skeleton loader — CLS de 0.31
La tabla aparece después de 800ms con un salto visual brusco (CLS medido: 0.31, umbral Google: menos de 0.1). No hay skeleton ni placeholder durante la carga. El resto del dashboard carga instantáneamente con mocks, haciendo el salto aún más evidente.
Cómo corregirlo
Añadir 5 filas skeleton con animate-pulse y dimensiones fijas mientras isLoading === true. Fijar la altura del contenedor de la tabla a la altura esperada (min 300px) para evitar el layout shift.
Mayor #3
Responsive roto en 375px — sidebar se solapa con contenido
En viewport de 375px el sidebar lateral no colapsa. Se superpone sobre el área de contenido principal, haciendo ilegible el 40% izquierdo del dashboard. No hay breakpoint mobile definido en el layout principal.
Cómo corregirlo
En @media (max-width: 768px): sidebar debe cambiar a position: fixed; transform: translateX(-100%) con un botón hamburguesa. El grid principal debe cambiar a una sola columna.

🔵 Problemas menores — nice to have

Menor #1
Tooltips del gráfico sin formato de fecha localizado
El tooltip del gráfico de macros muestra "2024-01-15" en lugar de "15 ene 2024". El contexto es España; el formato ISO queda poco profesional para usuarios finales.
Cómo corregirlo
Usar date.toLocaleDateString('es-ES', { day:'numeric', month:'short', year:'numeric' }) en el formatter del tooltip de Recharts.
Menor #2
Sin estados hover en filas de la tabla
Las filas no tienen feedback visual en hover. El cursor cambia a pointer (correcto) pero no hay cambio de color de fondo. Sensación de tabla estática.
Cómo corregirlo
Añadir hover:bg-gray-50 o equivalente. La transición debe ser suave: transition: background-color 150ms ease.

↔ Comparativa con iteración #1

Mejoras confirmadas
  • Eliminados gradientes azul-morado genéricos de la iteración #1
  • Panel de alertas muestra prioridad alta/media/baja con colores
  • Búsqueda en tabla funciona con caracteres especiales (antes rompía)
  • Gráfico de macros tiene leyenda y ejes etiquetados
  • KPI widgets muestran tendencia (flecha arriba/abajo)
  • Navegación con teclado (Tab) funciona en los filtros
Regresiones introducidas
  • Sorting de columnas funcionaba en iteración #1; ahora roto al hacer click en encabezado
  • Contador de pacientes activos muestra "undefined" al cargar (antes mostraba 0)
  • Color de texto en alertas altas: contraste insuficiente (ratio 2.1:1, mínimo WCAG: 4.5:1)

💡 Sugerencias concretas para iteración #3

1
Prioridad absoluta: implementar Export PDF. Es la única feature de monetización directamente visible por el cliente beta. Usar @react-pdf/renderer con template básico: logo NutriTrack, nombre paciente, gráfico de macros y tabla de adherencia. Máximo 2 horas de implementación.
2
Resolver los 3 críticos antes de cualquier mejora visual. El diseño puede mejorar incrementalmente; una pantalla en blanco por error de red es inaceptable para una demo beta. Aplicar React Query con manejo de errores en todos los data fetches.
3
Añadir design tokens de NutriTrack. Crear un archivo theme.ts con la paleta completa: primary #2d9b6f, danger #ef4444, warning #f59e0b, text tokens, spacing scale. Aplicar consistentemente. Esto sube el score de originalidad de 5 a ~7.
4
Test de regression obligatorio antes de entregar. Las 3 regresiones de esta iteración indican falta de testing básico. Añadir al menos un test de integración con @testing-library/react que verifique los valores de los KPI widgets.
5
Fix urgente de accesibilidad en alertas. Ratio de contraste 2.1:1 viola WCAG AA. Cambiar color de texto a #b91c1c (rojo oscuro) sobre fondo #fef2f2. Bloqueante legal en contextos sanitarios.

📸 Capturas de Playwright

🖥️
initial-load.png
✓ Carga sin errores JS
📋
table-empty-state.png
✗ Pantalla rota — sin empty state
📱
mobile-375px.png
✗ Sidebar superpuesto 40%
📄
export-pdf-click.png
✗ console.error en DevTools
📶
network-offline.png
✗ Pantalla en blanco / spinner infinito
🔍
search-special-chars.png
✓ Búsqueda robusta sanitizada
🚨
alerts-panel.png
⚠ Contraste insuficiente (2.1:1)
📈
macro-chart.png
✓ Gráfico legible con leyenda

🏷 Contexto técnico

React 18 TypeScript Tailwind CSS Recharts Playwright MCP localhost:3000 · Chromium Harness GAN · Iteración #2