# IMPACTO DE CAMBIOS EN BACKEND **Version:** 1.0.0 **Fecha:** 2025-12-08 **Prioridad:** OBLIGATORIA - Consultar antes de modificar Backend **Sistema:** SIMCO + CAPVED --- ## PROPOSITO Documentar la cascada de cambios que ocurre cuando se modifica cualquier componente del Backend (Entity, DTO, Service, Controller) y su impacto en Frontend. --- ## 1. MATRIZ DE IMPACTO POR COMPONENTE ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ CAMBIO EN BACKEND → IMPACTO EN CAPAS │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ENTITY DTO SERVICE CONTROLLER FRONTEND │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │──────▶│ │───────▶│ │───────▶│ │───────▶│ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ Refleja Valida Logica Endpoints Types │ │ DDL Input Negocio REST Zod │ │ Hooks │ │ Components │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 2. CAMBIOS EN ENTITY ### 2.1 Agregar Campo a Entity ```typescript // CAMBIO: Agregar campo 'phone' a UserEntity @Column({ type: 'varchar', length: 20, nullable: true }) phone: string | null; ``` **Cascada de Cambios:** | Capa | Archivo | Accion | Obligatorio | |------|---------|--------|-------------| | DDL | `XX-users.sql` | Agregar columna (DDL-First) | SI - PRIMERO | | Entity | `user.entity.ts` | Ya agregado | SI | | CreateDto | `create-user.dto.ts` | Agregar campo + validacion | SI | | UpdateDto | `update-user.dto.ts` | Hereda de CreateDto | AUTO | | ResponseDto | `user-response.dto.ts` | Agregar campo | SI | | Service | `user.service.ts` | Sin cambios (TypeORM maneja) | NO | | Controller | `user.controller.ts` | Sin cambios | NO | | **Frontend** | `user.types.ts` | Agregar campo a interface | SI | | **Frontend** | `user.schema.ts` | Agregar a Zod schema | SI | | **Frontend** | `UserForm.tsx` | Agregar input si editable | CONDICIONAL | **Checklist:** ``` [ ] 1. DDL tiene la columna (DDL-First) [ ] 2. Entity refleja DDL exactamente [ ] 3. CreateDto tiene validacion apropiada [ ] 4. ResponseDto incluye el campo [ ] 5. Swagger muestra campo correctamente [ ] 6. Frontend types actualizados [ ] 7. Frontend Zod schema actualizado [ ] 8. Componentes de formulario actualizados (si aplica) [ ] 9. npm run build (backend) [ ] 10. npm run build (frontend) [ ] 11. npm run typecheck (frontend) ``` ### 2.2 Eliminar Campo de Entity ```typescript // CAMBIO: Eliminar campo 'legacyCode' de ProductEntity // @Column() legacyCode: string; // ELIMINADO ``` **Cascada de Cambios:** | Capa | Archivo | Accion | Obligatorio | |------|---------|--------|-------------| | DDL | `XX-products.sql` | DROP COLUMN (con migracion) | SI - PRIMERO | | Entity | `product.entity.ts` | Eliminar @Column | SI | | CreateDto | `create-product.dto.ts` | Eliminar campo | SI | | UpdateDto | `update-product.dto.ts` | Hereda cambio | AUTO | | ResponseDto | `product-response.dto.ts` | Eliminar campo | SI | | Service | `product.service.ts` | Eliminar referencias | VERIFICAR | | Controller | `product.controller.ts` | Eliminar de queries | VERIFICAR | | **Frontend** | `product.types.ts` | Eliminar de interface | SI | | **Frontend** | `product.schema.ts` | Eliminar de Zod | SI | | **Frontend** | Componentes | Eliminar referencias | SI | **ADVERTENCIA:** ``` ⚠️ ANTES DE ELIMINAR UN CAMPO: 1. Buscar TODAS las referencias en backend: grep -r "legacyCode" src/ 2. Buscar TODAS las referencias en frontend: grep -r "legacyCode" apps/ 3. Verificar que no hay datos importantes en la columna 4. Considerar soft-delete o campo deprecated primero ``` ### 2.3 Cambiar Tipo de Campo ```typescript // CAMBIO: price de number a Decimal // ANTES @Column({ type: 'integer' }) price: number; // DESPUES @Column({ type: 'decimal', precision: 10, scale: 2 }) price: string; // String para precision decimal ``` **Cascada de Cambios:** | Capa | Archivo | Accion | Obligatorio | |------|---------|--------|-------------| | DDL | `XX-products.sql` | ALTER COLUMN type | SI - PRIMERO | | Entity | `product.entity.ts` | Cambiar tipo TS | SI | | CreateDto | `create-product.dto.ts` | Cambiar validador | SI | | ResponseDto | `product-response.dto.ts` | Cambiar tipo | SI | | Service | `product.service.ts` | Ajustar transformaciones | VERIFICAR | | **Frontend** | `product.types.ts` | Cambiar tipo | SI | | **Frontend** | `product.schema.ts` | Cambiar validador Zod | SI | | **Frontend** | Componentes | Ajustar formateo/parsing | SI | --- ## 3. CAMBIOS EN DTO ### 3.1 Agregar Validacion a DTO ```typescript // CAMBIO: Agregar validacion de formato a email @IsEmail({}, { message: 'Email invalido' }) @MaxLength(255) @Transform(({ value }) => value?.toLowerCase().trim()) email: string; ``` **Impacto:** | Capa | Impacto | Accion Requerida | |------|---------|------------------| | Entity | Ninguno | - | | Service | Ninguno | - | | Controller | Ninguno (validacion automatica) | - | | Swagger | Actualiza automaticamente | Verificar | | **Frontend** | Debe sincronizar validacion | Actualizar Zod | **Frontend debe reflejar:** ```typescript // Zod schema debe coincidir con backend const userSchema = z.object({ email: z.string() .email('Email invalido') .max(255) .transform(v => v.toLowerCase().trim()), }); ``` ### 3.2 Agregar Campo a ResponseDto ```typescript // CAMBIO: Agregar campo calculado 'fullName' @ApiProperty({ example: 'Juan Perez' }) fullName: string; ``` **Impacto:** | Capa | Impacto | Accion Requerida | |------|---------|------------------| | Entity | Ninguno (campo calculado) | - | | Service | Debe calcular el campo | Agregar logica | | Controller | Ninguno | - | | **Frontend** | Debe tipar el campo | Actualizar interface | **Service debe mapear:** ```typescript // En service toResponseDto(entity: UserEntity): UserResponseDto { return { ...entity, fullName: `${entity.firstName} ${entity.lastName}`, }; } ``` --- ## 4. CAMBIOS EN SERVICE ### 4.1 Agregar Metodo al Service ```typescript // CAMBIO: Agregar metodo de busqueda avanzada async searchByFilters(filters: SearchFiltersDto): Promise { // ... } ``` **Impacto:** | Capa | Impacto | Accion Requerida | |------|---------|------------------| | Entity | Ninguno | - | | DTO | Crear SearchFiltersDto | SI | | Controller | Exponer endpoint | SI | | **Frontend** | Crear servicio + hook | SI | ### 4.2 Modificar Logica de Negocio ```typescript // CAMBIO: Agregar validacion de negocio en create async create(dto: CreateOrderDto): Promise { // NUEVA: Validar stock antes de crear await this.validateStock(dto.items); // ... resto } ``` **Impacto:** | Capa | Impacto | Accion Requerida | |------|---------|------------------| | Entity | Ninguno | - | | DTO | Posible nuevo error response | Documentar | | Controller | Ninguno | - | | Swagger | Documentar nuevo error | SI | | **Frontend** | Manejar nuevo error | SI | **Frontend debe manejar:** ```typescript // Hook debe manejar error especifico const { mutate } = useCreateOrder({ onError: (error) => { if (error.message.includes('stock')) { toast.error('Stock insuficiente'); } } }); ``` --- ## 5. CAMBIOS EN CONTROLLER ### 5.1 Agregar Endpoint ```typescript // CAMBIO: Agregar endpoint de exportacion @Get('export') @ApiOperation({ summary: 'Exportar usuarios a CSV' }) async exportToCsv(): Promise { // ... } ``` **Impacto Frontend:** | Componente | Accion Requerida | |------------|------------------| | `user.service.ts` | Agregar metodo `exportToCsv()` | | `useExportUsers.ts` | Crear hook (si necesario) | | Componente UI | Agregar boton de exportar | ### 5.2 Modificar Ruta de Endpoint ```typescript // CAMBIO: Renombrar endpoint // ANTES: @Get('by-email/:email') // DESPUES: @Get('search/email/:email') ``` **ADVERTENCIA - BREAKING CHANGE:** ``` ⚠️ CAMBIO DE RUTA ES BREAKING CHANGE PROCESO OBLIGATORIO: 1. Verificar que frontend no usa la ruta antigua 2. Si usa: Actualizar frontend PRIMERO 3. Considerar: Mantener ruta antigua con @Deprecated 4. Documentar en CHANGELOG BUSCAR EN FRONTEND: grep -r "by-email" apps/ grep -r "users/by-email" apps/ ``` ### 5.3 Cambiar Metodo HTTP ```typescript // CAMBIO: De POST a PUT para update // ANTES: @Post(':id/update') // DESPUES: @Put(':id') ``` **Impacto Frontend:** ```typescript // ANTES await api.post(`/users/${id}/update`, data); // DESPUES await api.put(`/users/${id}`, data); ``` --- ## 6. SINCRONIZACION BACKEND-FRONTEND ### 6.1 Mapeo de Tipos | Backend (NestJS) | Frontend (TypeScript) | Notas | |------------------|----------------------|-------| | `string` | `string` | Directo | | `number` | `number` | Directo | | `boolean` | `boolean` | Directo | | `Date` | `string` | ISO string en JSON | | `Decimal` (string) | `string` o `number` | Parsear si necesario | | `UUID` | `string` | Directo | | `enum Status` | `type Status = ...` | Replicar valores | | `T[]` | `T[]` | Directo | | `T \| null` | `T \| null` | Directo | ### 6.2 Patron de Sincronizacion ```typescript // BACKEND: ResponseDto define contrato export class UserResponseDto { @ApiProperty() id: string; @ApiProperty() email: string; @ApiProperty({ enum: UserStatus }) status: UserStatus; @ApiProperty() createdAt: Date; // Se serializa como ISO string } // FRONTEND: Interface refleja ResponseDto export interface User { id: string; email: string; status: UserStatus; createdAt: string; // String porque viene de JSON } // FRONTEND: Enum replicado export enum UserStatus { ACTIVE = 'active', INACTIVE = 'inactive', } // FRONTEND: Zod refleja CreateDto export const createUserSchema = z.object({ email: z.string().email(), // ... campos de CreateUserDto }); ``` ### 6.3 Checklist de Sincronizacion ``` Cuando cambias Backend, verificar en Frontend: [ ] 1. Interfaces actualizadas (types/*.ts) [ ] 2. Enums sincronizados [ ] 3. Zod schemas actualizados [ ] 4. Services API actualizados [ ] 5. Hooks actualizados (si cambia endpoint) [ ] 6. Componentes manejan nuevos campos [ ] 7. Componentes manejan campos eliminados [ ] 8. Manejo de errores actualizado [ ] 9. npm run typecheck pasa [ ] 10. npm run build pasa ``` --- ## 7. COMANDOS DE VERIFICACION ```bash # Buscar referencias a campo en backend grep -rn "fieldName" src/ # Buscar referencias a campo en frontend grep -rn "fieldName" apps/ shared/ # Verificar tipos TypeScript npm run typecheck # Verificar que Swagger refleja cambios curl http://localhost:3000/api-json | jq '.paths["/users"]' # Comparar DTO con Interface diff <(grep -A 50 "class UserResponseDto" src/modules/user/dto/user-response.dto.ts) \ <(grep -A 50 "interface User" apps/web/types/user.types.ts) ``` --- ## 8. ANTI-PATRONES ### Anti-Patron 1: Cambiar Backend sin Frontend ``` ❌ INCORRECTO: 1. Backend-Agent agrega campo a ResponseDto 2. Se hace deploy 3. Frontend falla porque no espera el campo (usualmente OK) 4. O peor: Frontend espera campo que ya no existe (ROMPE) ✅ CORRECTO: 1. Backend-Agent agrega campo 2. Frontend-Agent actualiza types ANTES de deploy 3. Deploy coordinado ``` ### Anti-Patron 2: Tipos Diferentes ``` ❌ INCORRECTO: // Backend @Column({ type: 'decimal' }) price: string; // String para precision // Frontend interface Product { price: number; // ← INCORRECTO: tipo diferente } ✅ CORRECTO: // Frontend interface Product { price: string; // String como backend } // O usar transformacion explicita const displayPrice = parseFloat(product.price).toFixed(2); ``` ### Anti-Patron 3: Validaciones Desincronizadas ``` ❌ INCORRECTO: // Backend: max 100 caracteres @MaxLength(100) name: string; // Frontend: max 50 caracteres const schema = z.object({ name: z.string().max(50) // ← INCORRECTO: limite diferente }); ✅ CORRECTO: // Mismos limites en ambos lados // Backend: @MaxLength(100) // Frontend: z.string().max(100) ``` --- ## 9. MATRIZ RESUMEN | Si Cambias... | Actualiza en Backend | Actualiza en Frontend | |---------------|---------------------|----------------------| | Entity campo | DTO, posible Service | Types, Schema, Components | | Entity relacion | DTO, Service | Types, Hooks | | CreateDto campo | - | Schema (Zod) | | CreateDto validacion | - | Schema (Zod) | | ResponseDto campo | Service (si calculado) | Types, Components | | Service metodo | Controller (si expuesto) | Service, Hook | | Service logica | - | Manejo errores | | Controller endpoint | Swagger | Service, Hook | | Controller ruta | Swagger | Service (URL) | --- **Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guia de Impacto