# IMPACTO: CAMBIOS EN DDL (Base de Datos)

**Versión:** 1.0.0
**Fecha:** 2025-12-08
**Prioridad:** CRÍTICA - Leer antes de modificar DDL
**Sistema:** SIMCO + CAPVED

---

## PROPÓSITO

Documentar el impacto cascada de cambios en DDL y las acciones requeridas en cada capa.

---

## PRINCIPIO FUNDAMENTAL

```
╔══════════════════════════════════════════════════════════════════════╗
║  CAMBIO EN DDL = CAMBIO EN CASCADA                                   ║
║                                                                       ║
║  DDL → Entity → DTO → Service → Controller → Frontend                ║
║                                                                       ║
║  ⚠️  NUNCA cambiar DDL sin actualizar las capas dependientes         ║
╚══════════════════════════════════════════════════════════════════════╝
```

---

## 1. AGREGAR COLUMNA

### Impacto por Capa

| Capa | Archivo(s) Afectado(s) | Acción Requerida |
|------|------------------------|------------------|
| **DDL** | `schemas/{schema}/tables/{tabla}.sql` | Agregar columna |
| **Entity** | `{nombre}.entity.ts` | Agregar @Column |
| **DTO Create** | `create-{nombre}.dto.ts` | Agregar campo (si input) |
| **DTO Update** | `update-{nombre}.dto.ts` | Heredado de Create |
| **DTO Response** | `{nombre}-response.dto.ts` | Agregar campo (si output) |
| **Service** | `{nombre}.service.ts` | Ajustar lógica si necesario |
| **Controller** | `{nombre}.controller.ts` | Swagger actualizado automático |
| **Frontend Types** | `{nombre}.types.ts` | Agregar campo |
| **Frontend Forms** | `{Nombre}Form.tsx` | Agregar input (si editable) |
| **Frontend Display** | `{Nombre}Card.tsx`, etc. | Mostrar campo (si visible) |
| **Tests** | `*.spec.ts`, `*.test.tsx` | Actualizar fixtures |

### Checklist: Agregar Columna

```
DDL (Database-Agent):
[ ] ALTER TABLE o modificar CREATE TABLE
[ ] Definir tipo correcto (ver MAPEO-TIPOS.md)
[ ] Definir NULL/NOT NULL
[ ] Definir DEFAULT si aplica
[ ] Crear índice si es buscable
[ ] Ejecutar carga limpia exitosa
[ ] Actualizar DATABASE_INVENTORY.yml

Backend (Backend-Agent):
[ ] Agregar @Column en Entity
    - type: coincide con DDL
    - nullable: coincide con DDL
    - default: coincide con DDL
[ ] Agregar campo en CreateDto (si es input)
    - Validaciones apropiadas
    - @ApiProperty con ejemplo
[ ] Agregar campo en ResponseDto (si es output)
[ ] Ajustar Service si hay lógica nueva
[ ] npm run build → pasa
[ ] npm run lint → pasa
[ ] Actualizar BACKEND_INVENTORY.yml

Frontend (Frontend-Agent):
[ ] Agregar campo en interface/type
[ ] Actualizar Zod schema si hay form
[ ] Agregar input en formulario (si editable)
[ ] Mostrar en UI (si visible)
[ ] npm run build → pasa
[ ] npm run lint → pasa
[ ] Actualizar FRONTEND_INVENTORY.yml

Integración:
[ ] Test e2e funciona
[ ] Swagger muestra campo nuevo
[ ] Frontend consume correctamente
```

### Ejemplo Completo: Agregar Campo `phone`

**1. DDL:**
```sql
-- schemas/auth/tables/01-users.sql
ALTER TABLE auth.users
ADD COLUMN phone VARCHAR(20);
```

**2. Entity:**
```typescript
// entities/user.entity.ts
@Column({ type: 'varchar', length: 20, nullable: true })
phone: string;
```

**3. DTO Create:**
```typescript
// dto/create-user.dto.ts
@ApiPropertyOptional({ description: 'Teléfono', example: '+521234567890' })
@IsOptional()
@IsPhoneNumber('MX')
phone?: string;
```

**4. DTO Response:**
```typescript
// dto/user-response.dto.ts
@ApiPropertyOptional()
phone?: string;
```

**5. Frontend Type:**
```typescript
// types/user.types.ts
interface User {
    id: string;
    email: string;
    name: string;
    phone?: string;  // ← NUEVO
}
```

**6. Frontend Form:**
```typescript
// components/UserForm.tsx
<FormField
    name="phone"
    label="Teléfono"
    placeholder="+52 123 456 7890"
/>
```

---

## 2. ELIMINAR COLUMNA

### Impacto por Capa

| Capa | Acción | Riesgo |
|------|--------|--------|
| **DDL** | `ALTER TABLE DROP COLUMN` | ALTO - Datos perdidos |
| **Entity** | Eliminar @Column | MEDIO |
| **DTO** | Eliminar campo | MEDIO |
| **Service** | Eliminar referencias | ALTO - Lógica rota |
| **Frontend** | Eliminar campo y usos | ALTO - UI rota |
| **Tests** | Actualizar fixtures | MEDIO |

### Checklist: Eliminar Columna

```
⚠️ ANTES DE ELIMINAR:
[ ] Confirmar que datos no son necesarios
[ ] Verificar que no hay dependencias en código
[ ] Grep en todo el proyecto: grep -rn "{columna}" apps/
[ ] Planificar migración de datos si necesario

DDL:
[ ] ALTER TABLE DROP COLUMN
[ ] Verificar que no rompe constraints/FK
[ ] Carga limpia exitosa

Backend:
[ ] Eliminar @Column de Entity
[ ] Eliminar de DTOs
[ ] Buscar y eliminar referencias en Services
[ ] npm run build → sin errores de tipo
[ ] npm run test → pasa

Frontend:
[ ] Eliminar de types/interfaces
[ ] Eliminar de formularios
[ ] Eliminar de displays
[ ] npm run build → sin errores de tipo

Post-eliminación:
[ ] Verificar que aplicación funciona
[ ] Verificar que no hay errores en consola
[ ] Actualizar documentación
```

---

## 3. MODIFICAR TIPO DE COLUMNA

### Impacto por Capa

| Cambio | Backend | Frontend | Riesgo |
|--------|---------|----------|--------|
| `VARCHAR(50)` → `VARCHAR(100)` | Cambiar length | - | BAJO |
| `VARCHAR` → `TEXT` | Cambiar type | - | BAJO |
| `INTEGER` → `BIGINT` | `number` → `string` | Cambiar tipo | MEDIO |
| `VARCHAR` → `ENUM` | Agregar enum | Agregar enum | MEDIO |
| `TEXT` → `JSON` | Cambiar tipo, parsear | Cambiar tipo | ALTO |

### Checklist: Modificar Tipo

```
DDL:
[ ] ALTER TABLE ALTER COLUMN TYPE
[ ] Verificar que datos existentes son compatibles
[ ] Carga limpia exitosa

Backend:
[ ] Actualizar @Column type
[ ] Actualizar tipo TypeScript si cambió
[ ] Actualizar validaciones en DTO
[ ] npm run build → pasa

Frontend:
[ ] Actualizar tipo en interface
[ ] Actualizar validación Zod
[ ] Ajustar componentes si tipo cambió
[ ] npm run build → pasa

Datos:
[ ] Migrar datos existentes si necesario
[ ] Validar integridad post-migración
```

---

## 4. AGREGAR/MODIFICAR FOREIGN KEY

### Impacto por Capa

| Capa | Acción |
|------|--------|
| **DDL** | Agregar FK + índice |
| **Entity** | Agregar @ManyToOne + @JoinColumn |
| **Service** | Validar existencia antes de insertar |
| **DTO** | Agregar campo ID de relación |
| **Frontend** | Agregar selector/dropdown |

### Checklist: Agregar FK

```
DDL:
[ ] Agregar columna FK (UUID)
[ ] Agregar FOREIGN KEY constraint
[ ] Definir ON DELETE (CASCADE/SET NULL/RESTRICT)
[ ] Crear índice en FK
[ ] Verificar que tabla referenciada existe

Backend:
[ ] Agregar columna en Entity: {relation}Id: string
[ ] Agregar relación: @ManyToOne(() => RelatedEntity)
[ ] Agregar @JoinColumn({ name: '{relation}_id' })
[ ] Validar existencia en Service antes de crear
[ ] Agregar en DTO con @IsUUID

Frontend:
[ ] Agregar campo en type
[ ] Crear selector si es editable
[ ] Mostrar relación en UI
```

---

## 5. AGREGAR/MODIFICAR ÍNDICE

### Impacto

- **DDL**: Agregar `CREATE INDEX`
- **Otras capas**: Sin impacto directo
- **Performance**: Mejora en queries

### Checklist: Agregar Índice

```
[ ] Identificar columnas frecuentemente buscadas
[ ] Agregar CREATE INDEX en DDL
[ ] Para búsquedas compuestas: índice compuesto
[ ] Ejecutar carga limpia
[ ] Verificar plan de query (EXPLAIN)
```

---

## 6. AGREGAR TABLA NUEVA

### Impacto Completo

```
NUEVA TABLA = Feature completa

DDL:
├── CREATE TABLE con todas las columnas
├── PRIMARY KEY
├── FOREIGN KEYS
├── INDEXES
├── COMMENTS
└── Actualizar DATABASE_INVENTORY.yml

Backend:
├── {nombre}.entity.ts
├── create-{nombre}.dto.ts
├── update-{nombre}.dto.ts
├── {nombre}-response.dto.ts
├── {nombre}.service.ts
├── {nombre}.controller.ts
├── {nombre}.module.ts
├── Tests unitarios
└── Actualizar BACKEND_INVENTORY.yml

Frontend:
├── {nombre}.types.ts
├── {nombre}.service.ts (API calls)
├── use{Nombre}.ts (hook)
├── {Nombre}Form.tsx
├── {Nombre}List.tsx
├── {Nombre}Page.tsx
├── Tests de componentes
└── Actualizar FRONTEND_INVENTORY.yml
```

---

## 7. ELIMINAR TABLA

### Impacto CRÍTICO

```
⚠️ ELIMINAR TABLA = DESTRUIR FEATURE

ANTES de eliminar:
[ ] Confirmar que feature ya no se usa
[ ] Backup de datos si necesario
[ ] Verificar que no hay FK apuntando a esta tabla
[ ] Grep completo: grep -rn "{tabla}" apps/

Orden de eliminación (inverso a creación):
1. Frontend: Eliminar páginas, componentes, types
2. Backend: Eliminar controller, service, entity, DTOs, module
3. DDL: DROP TABLE
4. Actualizar todos los inventarios

Post-eliminación:
[ ] Build pasa en todas las capas
[ ] Aplicación funciona sin errores
[ ] Documentación actualizada
```

---

## 8. MATRIZ DE PROPAGACIÓN RÁPIDA

```
┌─────────────────┬─────────┬────────┬─────────┬──────────┬──────────┐
│ Cambio DDL      │ Entity  │ DTO    │ Service │ Frontend │ Tests    │
├─────────────────┼─────────┼────────┼─────────┼──────────┼──────────┤
│ + Columna       │ +Column │ +Field │ ?Lógica │ +Type    │ +Fixture │
│ - Columna       │ -Column │ -Field │ -Refs   │ -Type    │ -Fixture │
│ ~ Tipo          │ ~Type   │ ~Valid │ ?Parse  │ ~Type    │ ~Fixture │
│ + FK            │ +Rel    │ +UUID  │ +Valid  │ +Select  │ +Test    │
│ + Índice        │ -       │ -      │ -       │ -        │ -        │
│ + Tabla         │ +Todo   │ +Todo  │ +Todo   │ +Todo    │ +Todo    │
│ - Tabla         │ -Todo   │ -Todo  │ -Todo   │ -Todo    │ -Todo    │
└─────────────────┴─────────┴────────┴─────────┴──────────┴──────────┘

Leyenda:
+ = Agregar
- = Eliminar
~ = Modificar
? = Posiblemente
```

---

## 9. COMANDOS DE VERIFICACIÓN

```bash
# Verificar que cambio DDL no rompe
cd {DB_SCRIPTS_PATH}
./recreate-database.sh  # Carga limpia completa

# Verificar build backend
cd {BACKEND_ROOT}
npm run build && npm run lint

# Verificar build frontend
cd {FRONTEND_ROOT}
npm run build && npm run lint && npm run typecheck

# Buscar referencias a columna/tabla
grep -rn "{nombre}" apps/

# Verificar alineación Entity-DDL
# Comparar @Column en Entity vs columnas en DDL
```

---

## 10. ANTI-PATRONES

```
❌ NUNCA: Cambiar DDL sin actualizar Entity
   → Resultado: Runtime error al acceder columna

❌ NUNCA: Agregar columna NOT NULL sin DEFAULT
   → Resultado: INSERT falla en registros existentes

❌ NUNCA: Eliminar columna sin verificar uso
   → Resultado: Código roto en múltiples lugares

❌ NUNCA: Cambiar tipo sin migrar datos
   → Resultado: Datos corruptos o perdidos

❌ NUNCA: Modificar FK sin ajustar relaciones en Entity
   → Resultado: ORM genera queries incorrectas

✅ SIEMPRE: DDL primero → Entity segundo → DTO tercero → Frontend cuarto
✅ SIEMPRE: Verificar build en TODAS las capas después de cambio
✅ SIEMPRE: Actualizar inventarios y trazas
✅ SIEMPRE: Grep antes de eliminar para encontrar usos
```

---

**Versión:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guía de Impacto
