Create README.md
This commit is contained in:
@@ -0,0 +1,300 @@
|
|||||||
|
📊 Análisis del Dashboard JIRA - DashLabs
|
||||||
|
🏗️ Arquitectura del Proyecto
|
||||||
|
Stack Tecnológico
|
||||||
|
|
||||||
|
Frontend: HTML5 + Vanilla JavaScript + Chart.js 4.4.1
|
||||||
|
Backend: Node.js Serverless (Vercel Function)
|
||||||
|
API: JIRA REST API v3
|
||||||
|
Autenticación: Basic Auth (Email + Token JIRA)
|
||||||
|
Caching: En memoria (24hs) + CDN (Vercel)
|
||||||
|
|
||||||
|
Estructura de Archivos
|
||||||
|
dashlabs-master/
|
||||||
|
├── index.html (25 KB - Frontend completo)
|
||||||
|
└── api/
|
||||||
|
└── data.js (5.5 KB - Backend serverless)
|
||||||
|
|
||||||
|
📋 Componentes Principales
|
||||||
|
Frontend (index.html)
|
||||||
|
Elementos Visuales
|
||||||
|
|
||||||
|
Header
|
||||||
|
|
||||||
|
Título y metadata del proyecto
|
||||||
|
Botón de actualización manual
|
||||||
|
Badge de timestamp y estado de caché
|
||||||
|
|
||||||
|
|
||||||
|
Sección 1: Estado Actual del Equipo
|
||||||
|
|
||||||
|
4 KPIs principales:
|
||||||
|
|
||||||
|
SP En Progreso (color azul)
|
||||||
|
SP Por Hacer (color naranja)
|
||||||
|
SP Completados Total (color verde)
|
||||||
|
Devs Activos (color púrpura)
|
||||||
|
|
||||||
|
|
||||||
|
2 Gráficos:
|
||||||
|
|
||||||
|
SP en Progreso por Desarrollador (barras)
|
||||||
|
Estado Actual por Desarrollador (barras agrupadas)
|
||||||
|
|
||||||
|
|
||||||
|
Tabla Detallada:
|
||||||
|
|
||||||
|
Muestra por cada dev: Completados, En Progreso, Por Hacer
|
||||||
|
Barra de progreso visual
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Sección 2: Completados por Período
|
||||||
|
|
||||||
|
Filtro por mes (dropdown)
|
||||||
|
3 KPIs dinámicos:
|
||||||
|
|
||||||
|
SP Completados en el período
|
||||||
|
Devs que completaron
|
||||||
|
Promedio SP por dev
|
||||||
|
|
||||||
|
|
||||||
|
3 Gráficos:
|
||||||
|
|
||||||
|
Velocity por mes (barras apiladas)
|
||||||
|
Top 15 Épicas
|
||||||
|
SP Completados por Desarrollador (período filtrado)
|
||||||
|
|
||||||
|
|
||||||
|
Tabla de Historial:
|
||||||
|
|
||||||
|
SP completados con % de participación
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Backend (api/data.js)
|
||||||
|
Configuración JIRA
|
||||||
|
javascriptJIRA_HOST = 'invera.atlassian.net'
|
||||||
|
JQL = 'project = LABS AND cf[10016] is not EMPTY ORDER BY updated DESC'
|
||||||
|
Campos Customizados Mapeados
|
||||||
|
CampoCodeDescripciónStory Points Estimatecustomfield_10016Story points estimadoStory Points Finalescustomfield_11019SP final (prioridad sobre estimate)Desarrollador (Multi)customfield_10622Campo multi-usuario de asignaciónParentparentÉpicaResolution DateresolutiondateFecha de completado
|
||||||
|
Flujo de Datos
|
||||||
|
1. fetchJiraIssues()
|
||||||
|
├── Autentica con Basic Auth (JIRA_EMAIL + JIRA_TOKEN)
|
||||||
|
├── Ejecuta JQL query contra JIRA API
|
||||||
|
└── Retorna issues con campos específicos
|
||||||
|
|
||||||
|
2. processIssues()
|
||||||
|
├── Mapea developers (customfield_10622 → displayName)
|
||||||
|
├── Extrae SP (prioriza customfield_11019)
|
||||||
|
├── Categoriza por status (done/indeterminate/todo)
|
||||||
|
├── Agrupa:
|
||||||
|
│ ├── Por desarrollador (assigneeData)
|
||||||
|
│ ├── Por mes (monthlyDone)
|
||||||
|
│ └── Por épica (epicData)
|
||||||
|
└── Retorna DATA object estructurado
|
||||||
|
|
||||||
|
3. Caching
|
||||||
|
├── En memoria: 24 horas
|
||||||
|
├── CDN (Vercel): s-maxage=86400
|
||||||
|
└── Parámetro ?refresh=1 fuerza actualización
|
||||||
|
|
||||||
|
🔑 Características Principales
|
||||||
|
✅ Fortalezas Actuales
|
||||||
|
|
||||||
|
✨ Diseño limpio - UI coherente con color scheme profesional
|
||||||
|
📊 Múltiples perspectivas - Estado actual + Histórico
|
||||||
|
🎯 Enfoque en Story Points - Métrica clara de trabajo
|
||||||
|
⚡ Rendimiento - Arquitectura serverless + caché eficiente
|
||||||
|
🔄 Auto-refresh - Actualización automática cada 24hs
|
||||||
|
📱 Responsive - Funciona en móviles (media queries)
|
||||||
|
🎨 Charts.js - Gráficos interactivos y claros
|
||||||
|
|
||||||
|
⚠️ Áreas de Mejora
|
||||||
|
1. Hardcoding de Configuración
|
||||||
|
javascript// Actualmente:
|
||||||
|
const JIRA_HOST = 'invera.atlassian.net';
|
||||||
|
const JQL = 'project = LABS AND cf[10016] is not EMPTY...';
|
||||||
|
|
||||||
|
// Debería ser:
|
||||||
|
// Variables de entorno / archivo config
|
||||||
|
2. Limitación de Resultados
|
||||||
|
javascriptconst MAX_RESULTS = 100; // ⚠️ Solo trae primeros 100 tickets
|
||||||
|
Si LABS tiene >100 tickets, faltan datos en el dashboard.
|
||||||
|
3. Sin Control de Errores Robusto
|
||||||
|
|
||||||
|
El error banner es genérico
|
||||||
|
No hay retry automático
|
||||||
|
La caché nunca se invalida si hay error
|
||||||
|
|
||||||
|
4. Sin API REST moderna
|
||||||
|
|
||||||
|
El data.js es una Vercel Function directa
|
||||||
|
No hay validación de parámetros
|
||||||
|
Sin autenticación en el frontend
|
||||||
|
|
||||||
|
5. Estado Global con DATA
|
||||||
|
javascript// En window.DATA - manejo de estado débil
|
||||||
|
// Mejor: Usar módulo o estado centralizado
|
||||||
|
|
||||||
|
📈 Propuestas de Mejora
|
||||||
|
Fase 1: Críticas (Deberías hacer ya)
|
||||||
|
|
||||||
|
Aumentar MAX_RESULTS a 500 (o implementar paginación)
|
||||||
|
|
||||||
|
javascript const MAX_RESULTS = 500;
|
||||||
|
// O mejor: implementar loop hasta total
|
||||||
|
|
||||||
|
Validar tokens y secrets en variables de entorno
|
||||||
|
|
||||||
|
javascript if (!email || !token) throw new Error('...');
|
||||||
|
// ✅ Ya está, pero log más claro
|
||||||
|
|
||||||
|
Separar configuración de código
|
||||||
|
|
||||||
|
javascript // config.js
|
||||||
|
export const CONFIG = {
|
||||||
|
jiraHost: process.env.JIRA_HOST || 'invera.atlassian.net',
|
||||||
|
jiraProject: process.env.JIRA_PROJECT || 'LABS',
|
||||||
|
customFields: { /* ... */ }
|
||||||
|
};
|
||||||
|
Fase 2: Mejoras UX (Agregar valor)
|
||||||
|
|
||||||
|
Filtros interactivos en "Estado Actual"
|
||||||
|
|
||||||
|
Por desarrollador
|
||||||
|
Por status
|
||||||
|
Por épica
|
||||||
|
Por rango de SP
|
||||||
|
|
||||||
|
|
||||||
|
Tabla detallada de tickets
|
||||||
|
|
||||||
|
Mostrar tickets abiertos con links a JIRA
|
||||||
|
Filtros por dev, status, épica
|
||||||
|
Buscar por summary
|
||||||
|
|
||||||
|
|
||||||
|
Comparativas entre períodos
|
||||||
|
|
||||||
|
Velocidad mes a mes
|
||||||
|
Trending
|
||||||
|
Predictibilidad
|
||||||
|
|
||||||
|
|
||||||
|
Alertas/Warnings
|
||||||
|
|
||||||
|
Tickets en progreso > X días
|
||||||
|
SP sin asignar
|
||||||
|
Devs con carga desequilibrada
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Fase 3: Arquitectura (Scaling)
|
||||||
|
|
||||||
|
API REST con autenticación
|
||||||
|
|
||||||
|
javascript // api/issues - GET listar con filtros
|
||||||
|
// api/devs - GET listar desarrolladores
|
||||||
|
// api/epics - GET listar épicas
|
||||||
|
// api/stats - POST calcular período custom
|
||||||
|
|
||||||
|
Frontend modular
|
||||||
|
|
||||||
|
Separar en componentes
|
||||||
|
State management (Zustand / Pinia)
|
||||||
|
Mejorar mantenibilidad
|
||||||
|
|
||||||
|
|
||||||
|
Database (opcional)
|
||||||
|
|
||||||
|
Guardar snapshots diarios
|
||||||
|
Querys históricas más rápidas
|
||||||
|
Trend analysis
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
🔧 Guía de Configuración
|
||||||
|
Variables de Entorno Requeridas (Vercel)
|
||||||
|
JIRA_EMAIL=tu-email@example.com
|
||||||
|
JIRA_TOKEN=abc123xyz... # Generar en atlassian.net/account
|
||||||
|
Campos Customizados a Verificar
|
||||||
|
Cada Jira tiene IDs diferentes. Verificar en:
|
||||||
|
|
||||||
|
Settings → Custom fields
|
||||||
|
O ejecutar: curl -u email:token https://invera.atlassian.net/rest/api/3/fields
|
||||||
|
|
||||||
|
Para este proyecto:
|
||||||
|
cf[10016] → Story points estimate
|
||||||
|
cf[11019] → Story Points Finales
|
||||||
|
cf[10622] → Desarrollador (multi-user)
|
||||||
|
⚠️ IMPORTANTE: Estos IDs pueden cambiar entre instancias JIRA.
|
||||||
|
|
||||||
|
📊 Ejemplos de Datos Procesados
|
||||||
|
assigneeData
|
||||||
|
javascript{
|
||||||
|
"Juan López": {
|
||||||
|
done: 34,
|
||||||
|
in_progress: 8,
|
||||||
|
todo: 5
|
||||||
|
},
|
||||||
|
"María García": {
|
||||||
|
done: 28,
|
||||||
|
in_progress: 13,
|
||||||
|
todo: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monthlyDone
|
||||||
|
javascript{
|
||||||
|
"2024-12": { "Juan López": 15, "María García": 12 },
|
||||||
|
"2025-01": { "Juan López": 12, "María García": 18 },
|
||||||
|
"2025-02": { "Juan López": 7, "María García": -2 }
|
||||||
|
}
|
||||||
|
epicData
|
||||||
|
javascript[
|
||||||
|
{
|
||||||
|
name: "Refactor Backend API",
|
||||||
|
done: 45,
|
||||||
|
in_progress: 21,
|
||||||
|
todo: 8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
🚀 Próximos Pasos Recomendados
|
||||||
|
|
||||||
|
Inmediato:
|
||||||
|
|
||||||
|
Verificar campos customizados en tu instancia JIRA
|
||||||
|
Aumentar MAX_RESULTS
|
||||||
|
Revisar que caché funciona (badge de timestamp)
|
||||||
|
|
||||||
|
|
||||||
|
Corto plazo (1-2 semanas):
|
||||||
|
|
||||||
|
Agregar tabla de tickets con detalles
|
||||||
|
Implementar filtros en "Estado Actual"
|
||||||
|
Mejorar manejo de errores
|
||||||
|
|
||||||
|
|
||||||
|
Mediano plazo (1 mes):
|
||||||
|
|
||||||
|
API REST modularizada
|
||||||
|
Database para históricos
|
||||||
|
Alertas y predicciones
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
📝 Notas Finales
|
||||||
|
El proyecto es sólido y bien estructurado para un dashboard rápido. La arquitectura serverless de Vercel es ideal para consultas ocasionales. Si la demanda crece (100s de consultas/día) o necesitas más features, considera:
|
||||||
|
|
||||||
|
Agregar backend Node.js con Express
|
||||||
|
Database (PostgreSQL/MongoDB)
|
||||||
|
State management moderno
|
||||||
|
Testing automatizado
|
||||||
|
|
||||||
|
¿Necesitas ayuda implementando alguna de estas mejoras?
|
||||||
Reference in New Issue
Block a user