Analysis and Documentation: - Add ANALISIS-ALINEACION-WORKSPACE-2025-12-08.md with comprehensive gap analysis - Document SIMCO v3.2 system with 20+ directives - Identify alignment gaps between orchestration and projects New SaaS Products Structure: - Create apps/products/pos-micro/ - Ultra basic POS (~100 MXN/month) - Target: Mexican informal market (street vendors, small stores) - Features: Offline-first PWA, WhatsApp bot, minimal DB (~10 tables) - Create apps/products/erp-basico/ - Austere ERP (~300-500 MXN/month) - Target: SMBs needing full ERP without complexity - Features: Inherits from erp-core, modular pricing SaaS Layer: - Create apps/saas/ structure (billing, portal, admin, onboarding) - Add README.md and CONTEXTO-SAAS.md documentation Vertical Alignment: - Verify HERENCIA-ERP-CORE.md exists in all verticals - Add HERENCIA-SPECS-CORE.md to verticals - Update orchestration inventories Updates: - Update WORKSPACE-STATUS.md with new products and analysis - Update suite inventories with new structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
14 KiB
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
// 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
// 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
// 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
// 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:
// 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
// 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:
// En service
toResponseDto(entity: UserEntity): UserResponseDto {
return {
...entity,
fullName: `${entity.firstName} ${entity.lastName}`,
};
}
4. CAMBIOS EN SERVICE
4.1 Agregar Metodo al Service
// CAMBIO: Agregar metodo de busqueda avanzada
async searchByFilters(filters: SearchFiltersDto): Promise<UserEntity[]> {
// ...
}
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
// CAMBIO: Agregar validacion de negocio en create
async create(dto: CreateOrderDto): Promise<OrderEntity> {
// 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:
// 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
// CAMBIO: Agregar endpoint de exportacion
@Get('export')
@ApiOperation({ summary: 'Exportar usuarios a CSV' })
async exportToCsv(): Promise<StreamableFile> {
// ...
}
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
// 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
// CAMBIO: De POST a PUT para update
// ANTES: @Post(':id/update')
// DESPUES: @Put(':id')
Impacto Frontend:
// 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
// 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
# 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