Migración de Salesforce Classic a Lightning Experience (Nova Manufacturing)
Migración de Classic a Lightning y refuerzo de seguridad Apex para un fabricante internacional de equipos industriales.
Contexto
> Caso de estudio reconstruido: el escenario, la empresa y las cifras son ficticios. Se inspira en el tipo de trabajo que realizo en mi puesto, cuyos detalles siguen siendo confidenciales, y no describe un encargo de cliente. Nova Manufacturing es un fabricante internacional de equipos industriales (~150 comerciales repartidos en 3 sedes/polos en Europa). Su CRM Salesforce, todavía mayoritariamente en Classic, acumulaba varias generaciones de desarrollos: páginas Visualforce, botones JavaScript, Process Builder, perfiles muy personalizados, integraciones REST con sistemas externos (ERP, facturación). Con la progresiva desaparición de Classic, el escenario plantea la modernización de la aplicación — con un mandato explícito: no limitarse a migrar la interfaz, sino reforzar también la seguridad de los desarrollos Apex heredados, varios de los cuales nunca habían sido auditados desde su puesta en producción inicial.
Componentes identificados y soluciones propuestas
- Página Visualforce Compte360 (objeto Account): búsqueda y visualización de pedidos y contratos vinculados a una cuenta, consulta SOQL construida dinámicamente en el controlador → convertida en un Lightning Web Component AccountOrdersOverview, conectado a AccountOrdersController.getOrders() (6 días)
- Botón JavaScript UpdateContractStatus (objeto Contract): actualización del estado del contrato sin verificación de permisos ni confirmación del usuario → sustituido por una Quick Action que lanza un Screen Flow con un método Apex invocable (3 días)
- Process Builder "Validación de pedido": flujo de aprobación multinivel disparado en la creación → migrado a un Record-Triggered Flow (before-save y after-save separados para respetar los Governor Limits) (4 días)
- 4 controladores Apex heredados: auditoría sistemática, sin ninguna prueba de permisos CRUD/FLS implementada → reconstruidos con un patrón with sharing estricto. Más 4 controladores nuevos creados para este proyecto, con seguridad integrada desde el diseño (5 días en total)
- Estimación total: 25 días (auditoría 2d, migración Visualforce→LWC 6d, botón JS→Quick Action/Flow 3d, Process Builder→Flow 4d, seguridad Apex 5d, pruebas 3d, documentación 2d), más 8h de formación de usuarios
Desarrollos entregados
- LWC AccountOrdersOverview: lightning-datatable con paginación en el servidor y búsqueda por palabra clave, conectado a un método Apex @AuraEnabled(cacheable=true) con WITH SECURITY_ENFORCED
- Record-Triggered Flow "Validación de pedido v2": lógica bulkificada que procesa la colección completa (el antiguo Process Builder no lo hacía y provocaba errores de Governor Limits en las importaciones masivas), con un sub-flow reutilizable para la parte de notificación
- Permission Set Groups: consolidación de 8 perfiles heredados casi duplicados en 5 grupos, reduciendo la deuda de configuración y facilitando la auditoría de accesos
- Named Credentials: sustitución de los endpoints REST codificados directamente (credenciales antes visibles en Custom Settings para cualquier administrador) por Named Credentials, con autenticación gestionada por la plataforma
Seguridad y buenas prácticas
- ContractService.updateStatus(): antes de la reconstrucción, escribía directamente en Contract sin verificación, y la clase se ejecutaba en without sharing por defecto de un antiguo controlador Visualforce. Después: Security.stripInaccessible(AccessType.UPDATABLE, records) antes de cada DML, with sharing explícito en la clase
- Prueba unitaria dedicada que simula un usuario sin permiso de edición sobre Contract.Statut__c para verificar que stripInaccessible() bloquea correctamente la escritura
- Auditoría de los 4 controladores heredados: no existía ninguna prueba de permisos CRUD/FLS antes de este proyecto — se añadieron verificaciones explícitas allí donde las consultas no eran elegibles para WITH SECURITY_ENFORCED. Seguridad integrada desde el diseño en los 4 controladores nuevos creados para el proyecto
- Matriz de comparación perfiles → permission sets validada con los responsables de negocio antes del cambio, para evitar cualquier regresión silenciosa en los derechos de acceso
Gestión de riesgos
- Incompatibilidad de controladores Apex existentes (impacto medio) → pruebas de no regresión en sandbox antes de cada cambio, despliegue componente por componente en lugar de todo a la vez
- Adopción por parte de los usuarios (probabilidad alta) → 8h de formación repartidas en 2 sesiones, documentación breve por rol en lugar de un manual único
- Errores de Governor Limits en los Flows migrados (impacto bajo, ya detectado una vez en sandbox) → bulkificación sistemática desde el diseño, probada con conjuntos de 200+ registros
- Regresión silenciosa en los derechos de acceso durante la consolidación de perfiles (impacto alto) → matriz de comparación perfiles → permission sets validada con los responsables de negocio antes de la puesta en producción
Stack y tecnologías
- Lightning Web Components, Apex, SOQL
- Flow (Record-Triggered, before-save/after-save)
- Permission Set Groups, Named Credentials
- Modelo de seguridad de Salesforce — CRUD/FLS, WITH SECURITY_ENFORCED, stripInaccessible()
Resultados
Limitaciones conocidas y decisiones
- Migración progresiva componente por componente en lugar de un big bang: más lenta, pero permite un rollback específico si un componente migrado revela un problema no anticipado en producción
- Páginas Visualforce simples sin valor añadido real de migrar se dejaron tal cual: Lightning Experience las soporta de forma nativa, migrar todo el alcance solo habría supuesto coste sin beneficio medible para el usuario
- Named Credentials desplegadas únicamente en las integraciones REST identificadas como prioritarias durante la auditoría — las integraciones secundarias siguen con el mecanismo antiguo, migración documentada como siguiente paso