# 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