|
|
@@ -0,0 +1,182 @@
|
|
|
+# Análisis de Impacto: Eliminación del campo `reportId`
|
|
|
+
|
|
|
+**Fecha**: 16 de octubre de 2025
|
|
|
+**Objetivo**: Eliminar el campo redundante `reportId` del modelo `Appointment`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📊 Contexto
|
|
|
+
|
|
|
+### Historia del Campo
|
|
|
+1. **8 Oct 2025**: Se creó `Appointment` con `recordId` (con relación a `Record`) ✅
|
|
|
+2. **13 Oct 2025**: Se agregó `reportId` (sin relación, solo string) ❌
|
|
|
+3. **16 Oct 2025**: Detectado el problema - ambos campos coexisten causando confusión
|
|
|
+
|
|
|
+### Problema Actual
|
|
|
+- `recordId`: Campo correcto con relación a tabla `Record`
|
|
|
+- `reportId`: Campo redundante sin relación, solo almacena string
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🔍 Archivos Impactados
|
|
|
+
|
|
|
+### 1. Schema de Prisma
|
|
|
+**Archivo**: `prisma/schema.prisma`
|
|
|
+- **Línea 78**: `reportId String?`
|
|
|
+- **Impacto**: ⚠️ ALTO - Requiere migración de base de datos
|
|
|
+- **Acción**: Eliminar línea
|
|
|
+
|
|
|
+### 2. Backend - API Routes
|
|
|
+
|
|
|
+#### `src/app/api/appointments/route.ts`
|
|
|
+- **Línea 151**: `const { fechaSolicitada, motivoConsulta, recordId, reportId } = body;`
|
|
|
+- **Línea 178**: `...(reportId && { reportId }),`
|
|
|
+- **Impacto**: ⚠️ MEDIO - El API acepta `reportId` pero NO se usa
|
|
|
+- **Acción**: Eliminar destructuring y spread de `reportId`
|
|
|
+- **Breaking Change**: NO (nadie está enviando este campo actualmente)
|
|
|
+
|
|
|
+### 3. TypeScript Types
|
|
|
+
|
|
|
+#### `src/types/appointments.ts`
|
|
|
+- **Línea 10**: `reportId: string | null;`
|
|
|
+- **Impacto**: ⚠️ MEDIO - El tipo incluye el campo
|
|
|
+- **Acción**: Eliminar línea
|
|
|
+- **Breaking Change**: NO (el campo nunca se usa en el código)
|
|
|
+
|
|
|
+### 4. Frontend - Components
|
|
|
+
|
|
|
+#### `src/components/chatbot/AppointmentModalFromChat.tsx`
|
|
|
+- **Línea 22**: `reportId?: string;` (prop)
|
|
|
+- **Línea 29**: `reportId,` (destructuring)
|
|
|
+- **Línea 49**: `recordId: reportId || undefined,` (mapeo correcto)
|
|
|
+- **Impacto**: ✅ BAJO - Ya está mapeando correctamente a `recordId`
|
|
|
+- **Acción**: Renombrar prop a `recordId` para claridad
|
|
|
+- **Breaking Change**: NO (uso interno del componente)
|
|
|
+
|
|
|
+#### `src/components/appointments/ReportViewer.tsx`
|
|
|
+- **Línea 12**: `reportId: string;` (prop)
|
|
|
+- **Línea 19**: `reportId,` (destructuring)
|
|
|
+- **Línea 33**: Uso en nombre de archivo de descarga
|
|
|
+- **Impacto**: ✅ NINGUNO - Este es el ID del `Record`, no del campo `reportId`
|
|
|
+- **Acción**: Renombrar prop a `recordId` para claridad semántica
|
|
|
+- **Breaking Change**: NO (el prop recibe `appointment.record.id`)
|
|
|
+
|
|
|
+#### `src/app/appointments/[id]/page.tsx`
|
|
|
+- **Línea 422**: `reportId={appointment.record.id}`
|
|
|
+- **Impacto**: ✅ NINGUNO - Ya está pasando el `record.id`, no `reportId`
|
|
|
+- **Acción**: Cambiar a `recordId={appointment.record.id}`
|
|
|
+- **Breaking Change**: NO
|
|
|
+
|
|
|
+### 5. Frontend - Hooks
|
|
|
+
|
|
|
+#### `src/hooks/useChat.ts`
|
|
|
+- **Línea 489**: `handleScheduleFromAlert = async (onSuccess: (reportId: string) => void)`
|
|
|
+- **Línea 510**: `const reportId = data.id;`
|
|
|
+- **Línea 513**: `onSuccess(reportId);`
|
|
|
+- **Impacto**: ✅ NINGUNO - Es una variable local con el ID del Record
|
|
|
+- **Acción**: Renombrar variable a `recordId` para claridad
|
|
|
+- **Breaking Change**: NO (scope interno)
|
|
|
+
|
|
|
+#### `src/components/chatbot/ChatInterface.tsx`
|
|
|
+- **Línea 41**: `appointmentReportId` state
|
|
|
+- **Línea 142-143**: Callback que recibe y setea `reportId`
|
|
|
+- **Línea 277**: Pasa al modal
|
|
|
+- **Impacto**: ✅ NINGUNO - Variable de estado interna
|
|
|
+- **Acción**: Renombrar a `appointmentRecordId` para claridad
|
|
|
+- **Breaking Change**: NO
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🎯 Plan de Acción
|
|
|
+
|
|
|
+### Fase 1: Cambios de Nomenclatura (Sin Breaking Changes)
|
|
|
+1. ✅ Renombrar props y variables locales de `reportId` → `recordId`
|
|
|
+2. ✅ Actualizar comentarios para clarificar que es el ID del Record
|
|
|
+3. ✅ NO afecta funcionalidad existente
|
|
|
+
|
|
|
+### Fase 2: Limpieza del Backend
|
|
|
+1. ⚠️ Eliminar `reportId` del destructuring en API
|
|
|
+2. ⚠️ Eliminar línea del spread en Prisma create
|
|
|
+3. ⚠️ Eliminar del tipo TypeScript
|
|
|
+
|
|
|
+### Fase 3: Migración de Base de Datos
|
|
|
+1. ⚠️ Crear migración para eliminar columna `reportId`
|
|
|
+2. ⚠️ Verificar que no hay datos en esa columna
|
|
|
+3. ⚠️ Aplicar migración
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🚨 Riesgos Identificados
|
|
|
+
|
|
|
+### Riesgo 1: Datos Huérfanos
|
|
|
+**Probabilidad**: 🟡 MEDIA
|
|
|
+**Impacto**: 🟡 MEDIO
|
|
|
+**Descripción**: Podría haber citas con `reportId` poblado pero sin `recordId`
|
|
|
+
|
|
|
+**Mitigación**:
|
|
|
+```sql
|
|
|
+-- Verificar antes de eliminar
|
|
|
+SELECT id, reportId, recordId
|
|
|
+FROM "Appointment"
|
|
|
+WHERE reportId IS NOT NULL AND recordId IS NULL;
|
|
|
+```
|
|
|
+
|
|
|
+### Riesgo 2: Código Legacy
|
|
|
+**Probabilidad**: 🟢 BAJA
|
|
|
+**Impacto**: 🟢 BAJO
|
|
|
+**Descripción**: Código no encontrado que use `reportId`
|
|
|
+
|
|
|
+**Mitigación**: Búsqueda exhaustiva completada - solo 33 referencias, todas identificadas
|
|
|
+
|
|
|
+### Riesgo 3: Breaking Changes en API
|
|
|
+**Probabilidad**: 🟢 BAJA
|
|
|
+**Impacto**: 🟢 BAJO
|
|
|
+**Descripción**: Clientes externos enviando `reportId` en requests
|
|
|
+
|
|
|
+**Mitigación**: El campo nunca fue documentado oficialmente y el código actual ya usa `recordId`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## ✅ Beneficios
|
|
|
+
|
|
|
+1. **Claridad del Código**: Solo un campo para referenciar Reports
|
|
|
+2. **Consistencia**: Uso de relaciones Prisma adecuadas
|
|
|
+3. **Mantenibilidad**: Menos confusión para futuros desarrolladores
|
|
|
+4. **Performance**: Elimina campo innecesario en queries
|
|
|
+5. **Type Safety**: TypeScript más preciso
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📝 Recomendación Final
|
|
|
+
|
|
|
+### ✅ PROCEDER CON LA ELIMINACIÓN
|
|
|
+
|
|
|
+**Justificación**:
|
|
|
+- El campo `reportId` nunca tuvo una relación definida
|
|
|
+- El código actual ya usa `recordId` correctamente
|
|
|
+- Solo requiere cambios de nomenclatura (no funcionales)
|
|
|
+- Bajo riesgo de breaking changes
|
|
|
+- Alto beneficio en claridad y mantenibilidad
|
|
|
+
|
|
|
+**Orden de Ejecución Recomendado**:
|
|
|
+1. Fase 1: Refactor de nombres (sin impacto)
|
|
|
+2. Verificar que todo funciona
|
|
|
+3. Fase 2: Limpieza de backend
|
|
|
+4. Verificar que todo funciona
|
|
|
+5. Fase 3: Migración de DB (después de verificar datos)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📋 Checklist de Implementación
|
|
|
+
|
|
|
+- [ ] Verificar datos en columna `reportId` en producción
|
|
|
+- [ ] Renombrar variables/props en frontend (Fase 1)
|
|
|
+- [ ] Probar creación de citas desde chatbot
|
|
|
+- [ ] Probar visualización de reportes en detalle de cita
|
|
|
+- [ ] Eliminar código backend relacionado (Fase 2)
|
|
|
+- [ ] Actualizar tipos TypeScript
|
|
|
+- [ ] Crear migración de Prisma (Fase 3)
|
|
|
+- [ ] Aplicar migración
|
|
|
+- [ ] Verificar funcionalidad end-to-end
|
|
|
+- [ ] Actualizar documentación
|
|
|
+
|