- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
GAP Analysis: Manejo de Fechas Nulas en Admin Portal
ID: GAP-DATE-HANDLING-001 Fecha: 2025-11-24 Severidad: ALTA (P1) Analista: Architecture-Analyst Estado: En corrección
1. RESUMEN EJECUTIVO
Se identificó un patrón inseguro de conversión de fechas en múltiples componentes del Admin Portal donde se llama new Date(value) sin validar si value es null o undefined, resultando en "Invalid Date".
2. CAUSA RAÍZ
El campo lastLogin puede ser null
Cuando un usuario nunca ha iniciado sesión, lastLogin es null. Al ejecutar:
new Date(null) // → Thu Jan 01 1970 00:00:00 (epoch)
new Date(undefined) // → Invalid Date
El error "date invalid" aparece cuando toLocaleDateString() se llama sobre un Invalid Date.
Flujo del error:
Backend envía: { lastLogin: null } // Usuario nunca ha iniciado sesión
↓
Frontend: new Date(null).toLocaleDateString()
↓
Resultado: "1/1/1970" (incorrecto) o "Invalid Date" (error)
3. INSTANCIAS DEL PROBLEMA
Archivo Principal (Error Reportado)
| Archivo | Línea | Código Problemático |
|---|---|---|
UserManagementTable.tsx |
106 | {new Date(user.lastLogin).toLocaleDateString()} |
Otros Archivos con Mismo Patrón
| # | Archivo | Línea | Campo |
|---|---|---|---|
| 1 | TeacherClassroomsTab.tsx |
181 | classroom.assignedAt |
| 2 | ClassroomTeachersTab.tsx |
214 | teacher.assignedAt |
| 3 | ErrorTrackingTab.tsx |
212 | trend.time_bucket |
| 4 | UserActivityMonitor.tsx |
211 | activity.timestamp |
| 5 | SystemHealthIndicators.tsx |
215 | incident.timestamp |
| 6 | SystemPerformanceDashboard.tsx |
219 | metrics.timestamp |
| 7 | AdminContentPage.tsx |
141, 228, 275 | row.createdAt, row.uploadedAt |
| 8 | AdminInstitutionsPage.tsx |
180 | row.createdAt |
| 9 | AdminGamificationPage.tsx |
114 | stats.lastModified |
| 10 | TenantManagementPanel.tsx |
349, 355 | createdAt, lastActive |
| 11 | FeatureFlagControls.tsx |
345, 357, 365, 396 | Múltiples campos |
| 12 | ABTestingDashboard.tsx |
306, 314 | startDate, endDate |
| 13 | MediaLibraryManager.tsx |
260 | file.uploadedAt |
| 14 | EconomicInterventionPanel.tsx |
384, 388 | startDate, endDate |
| 15 | ContentApprovalQueue.tsx |
165, 284 | item.submittedAt |
| 16 | ContentVersionControl.tsx |
114, 138, 192, 234 | version.timestamp |
| 17 | AdminDashboardHero.tsx |
171 | health.lastCheck |
| 18 | SystemAlertsPanel.tsx |
204 | selectedAlert.timestamp |
| 19 | RecentActionsTable.tsx |
318, 418 | action.timestamp |
| 20 | OrganizationsTable.tsx |
140 | org.createdAt |
| 21 | SystemLogsViewer.tsx |
135 | log.timestamp |
4. PATRÓN CORRECTO
Implementación Segura (Ya existe en AdminUsersPage.tsx:370)
// ✅ CORRECTO - Con validación
{usr.lastLogin ? new Date(usr.lastLogin).toLocaleDateString('es-ES') : 'Nunca'}
Función Utilitaria Recomendada
// apps/frontend/src/shared/utils/formatters.ts
/**
* Formatea una fecha de forma segura, manejando null/undefined
* @param dateValue - Valor de fecha (string, Date, null, undefined)
* @param options - Opciones de formato
* @param fallback - Texto a mostrar si la fecha es inválida
* @returns Fecha formateada o fallback
*/
export function formatDateSafe(
dateValue: string | Date | null | undefined,
options: Intl.DateTimeFormatOptions = { dateStyle: 'short' },
fallback: string = 'N/A'
): string {
if (!dateValue) return fallback;
const date = new Date(dateValue);
if (isNaN(date.getTime())) return fallback;
return date.toLocaleDateString('es-ES', options);
}
5. PLAN DE CORRECCIÓN
Prioridad 1: Error Reportado
- Archivo:
UserManagementTable.tsx - Línea: 106
- Acción: Agregar validación de null
Prioridad 2: Componentes de Alta Visibilidad
RecentActionsTable.tsx(Dashboard principal)OrganizationsTable.tsx(Dashboard principal)SystemAlertsPanel.tsx(Dashboard principal)
Prioridad 3: Resto de Componentes
- Aplicar patrón seguro a todos los archivos listados
6. CRITERIOS DE ACEPTACIÓN
UserManagementTable.tsxno genera "Invalid Date"- Todos los componentes usan el patrón
value ? new Date(value)... : fallback npm run type-checkpasa sin errores relacionados- Las fechas null muestran texto apropiado ("Nunca", "N/A", "Sin fecha", etc.)
7. ARCHIVOS A MODIFICAR
| # | Archivo | Tipo de Cambio |
|---|---|---|
| 1 | UserManagementTable.tsx |
Agregar validación null para lastLogin |
| 2 | TeacherClassroomsTab.tsx |
Agregar validación null para assignedAt |
| 3 | ClassroomTeachersTab.tsx |
Agregar validación null para assignedAt |
| 4+ | (Ver lista completa arriba) | Mismo patrón |
Versión: 1.0 Estado: Listo para implementación