Modernización de Flows de Salesforce
Los modelos por defecto usan los patrones de sus datos de entrenamiento: Bucle + Decisión + Asignación, DML dentro de bucles, actualizaciones post-guardado del registro disparador, pantallas extra para recalcular. Este skill los reemplaza con los elementos actuales y te proporciona metadatos verificados para cada uno en examples/.
Estas reglas deciden la mayoría de los resultados:
- El elemento moderno es la opción por defecto. Un bucle necesita una condición de escape explícita (ver abajo). Cuando el XML de un elemento no te sea familiar, copia la estructura de su archivo de ejemplo en lugar de evitar el elemento.
- No verificable no significa no disponible. La disponibilidad sigue la versión de API de la organización y la tabla inferior. No necesitas acceso web para usar un elemento cuyo mínimo esté en o por debajo de la versión de la org. La validación de despliegue es la comprobación.
- Cada bucle y cada retroceso se explican. Nombra el escape en la descripción del Bucle y en el entregable. Sin un escape nombrado, no escribas el bucle.
Flujo de trabajo
Copia esta lista de verificación en tus notas de trabajo y márcala:
- [ ] 1. Leer references/org-conventions.md; listar los slots no configurados de los que depende esta tarea
- [ ] 2. Establecer la versión de API de la organización
- [ ] 3. Clasificar la tarea: construir, auditar o migrar; tipo de flow, evento disparador, ejecutado como quién
- [ ] 4. Mapear cada requisito a través de la tabla de decisión; abrir cada ejemplo que uses
- [ ] 5. Escribir los metadatos (o la especificación de construcción)
- [ ] 6. Ejecutar scripts/check-flow.mjs; corregir cada ERROR, decidir cada ADVERTENCIA
- [ ] 7. Validar el despliegue cuando una org esté disponible; de lo contrario, etiquetar el XML como no validado
- [ ] 8. Ejecutar la lista de verificación de revisión en references/delivery.md y entregar
Paso 1. Convenciones. Un slot rellenado en org-conventions.md anula los valores por defecto de este skill. Un slot vacío significa que se aplica el valor por defecto y el entregable lo lista bajo decisiones abiertas.
Paso 2. Versión de API. Con una org, sf org display --target-org <alias> muestra "Api Version". Sin una, usa sourceApiVersion del archivo sfdx-project.json del proyecto, o 67.0 si también falta, y dilo. Establece el apiVersion de los nuevos flows a esa versión.
Paso 3. Clasificar. Flow existente o nueva construcción. Tipo de flow (de pantalla, disparado por registro antes o después de guardar, autoejecutado, disparado por programación, disparado por evento de plataforma). Objeto disparador y evento disparador, respondido a partir del requisito antes de abrir cualquier ejemplo. La pregunta es si un registro creado que ya cumple la condición cuenta, o solo uno que cambia para cumplirla. Crear y actualizar con "solo cuando se actualiza para cumplir la condición" se dispara en dicha creación, mientras que solo actualización no. Si el requisito no lo dice, pregunta o indica la suposición (record-triggered.md). Quién lo ejecuta (usuario, sistema, agente). Qué debe suceder sincrónicamente. Para flows de pantalla, la superficie que lo incrusta y qué recibe y devuelve.
Paso 4. Mapear. Para cada operación de colección, lista de opciones, interacción de pantalla, actualización de registro, necesidad de sincronización e integración, toma la fila de la tabla de decisión. Lee el archivo de ejemplo para cada elemento que vayas a escribir y la referencia de dominio para sus límites. Lee solo las referencias para los dominios que toca la tarea.
Paso 5. Escribir. Los metadatos van a force-app/main/default/flows/<ApiName>.flow-meta.xml (ajusta al directorio de paquete del proyecto). Nombres por defecto: nombres de API de flow Objeto_Verbo_Condición, nombres de elementos Tipo_Propósito (Obtener_Casos_Abiertos, Filtrar_Alta_Prioridad, Transformar_En_Tareas, Dec_Es_Renovacion), a menos que org-conventions.md diga lo contrario. Establece <status>Draft</status> a menos que el usuario pida explícitamente un flow activo o el slot de política de activación lo indique. Los ejemplos están Activos solo porque se ejecutaron. Mantén todos los elementos de un mismo tipo juntos en el archivo (los grupos divididos fallan en el despliegue). Sin acceso a CLI, entrega una especificación de construcción en el formato de delivery.md.
Paso 6. Verificar. Ejecuta el verificador en cada flow que escribiste o te pidieron revisar. Solo necesita Node:
node <skill-dir>/scripts/check-flow.mjs --api <org-api-version> force-app/main/default/flows/<ApiName>.flow-meta.xml
Los ERRORES son patrones heredados o formas que la plataforma rechaza, así que corrígelos. Las ADVERTENCIAS necesitan una decisión, que indicas en el entregable.
Paso 7. Validar. Con una org autenticada, nombra la org explícitamente en lugar de depender de la org por defecto de la CLI:
sf project deploy validate --source-dir force-app/main/default/flows/<ApiName>.flow-meta.xml --target-org <alias>
Corrige según el error exacto y vuelve a ejecutar. El XML que no fue validado se etiqueta como no validado en el entregable, claramente.
Paso 8. Revisar y entregar. Ejecuta la lista de verificación de revisión en delivery.md. Termina el entregable con este bloque, cada línea rellenada:
Modo: metadatos | especificación de construcción
Verificador: <comando> → <n> errores, <n> advertencias (<decisión por advertencia>)
Validación de despliegue: <comando y resultado> | no ejecutado, no validado (<razón>)
Estado: Borrador | Activo (<por qué>)
Contexto de ejecución: <runInMode o defecto, y qué significa para este tipo de flow>
Escapes: <E-id y razón por bucle o retroceso> | ninguno
Decisiones abiertas: <slots de convención no configurados de los que depende este flow> | ninguna
Valores por defecto del contexto de ejecución (runInMode DefaultMode): los flows disparados por registro, por programación y por evento de plataforma se ejecutan en contexto de sistema sin compartir. Los flows de pantalla y autoejecutados se ejecutan en contexto de usuario cuando se lanzan desde la UI o la API REST, y en el contexto de quien llama cuando se invocan desde Apex u otro flow. Autoejecutado no es "sistema por defecto".
Auditorías y migraciones
Para un flow existente, ejecuta primero el verificador, luego inventaría los patrones heredados restantes contra la última columna de la tabla de decisión. Entrega el informe de auditoría definido en delivery.md antes de cualquier reescritura, clasificado por impacto: límites de gobernador, luego contexto de seguridad, luego experiencia de usuario. No modifiques el flow a menos que se te pida. Cuando se te pida, sigue el plan de migración del informe en orden. Describe patrones, nunca a las personas que los construyeron, porque la mayoría de los patrones heredados eran el enfoque recomendado cuando se escribieron. El mapeo de Process Builder y reglas de workflow está en legacy-migration.md.
Tabla de decisión
"API de Org" es la versión de API de org más baja que tiene el elemento (Flow, Guía del desarrollador de Metadata API). Los ejemplos están en examples/flows/, desplegados y ejecutados en la API 67.0.
| Requisito | Usar | Metadatos | API de Org | Ejemplo | Reemplaza |
|---|---|---|---|---|---|
| Mantener los elementos de una colección que coinciden con criterios | Collection Filter (condiciones o fórmula) | collectionProcessors, FilterCollectionProcessor | 53 | Opportunity_Create_Followup_Tasks | Bucle + Decisión + Asignación |
| Construir registros a partir de una colección, reformar campos | Transform, Map | transforms | 59 | Opportunity_Create_Followup_Tasks | Bucle + Asignación construyendo una colección |
| Sumar o contar una colección | Transform, Sum / Count. En flows de pre-guardado, Filter + Asignación AssignCount, o un Bucle para una Suma (E3) | transforms, inputParameters | 59 (destino primitivo 62) | Opportunity_Create_Followup_Tasks, Account_Before_Save_Count_Contacts | Contadores de bucle |
| Combinar dos colecciones por una clave | Transform, InnerJoin, con el mapeo en el mismo Transform | transforms, JoinDefinition | 63 | Opportunity_Create_Account_Tasks_Joined | Bucles anidados, Obtener Registros dentro de un bucle |
| Ordenar una colección | Collection Sort (ordena en el lugar) | SortCollectionProcessor | 50 | Opportunity_Allocate_Budget_Waterfall | Ordenación manual en un bucle |
| Crear, actualizar o eliminar muchos registros | Un DML sobre la colección preparada | recordCreates inputReference | cualquiera | Opportunity_Create_Followup_Tasks | DML dentro de un bucle |
| Opciones a partir de registros o un picklist | Choice set de registros / picklist | dynamicChoiceSets | cualquiera | Account_Order_Entry_Screen | Obtener Registros + Bucle construyendo opciones |
| Totales, visibilidad o texto que siguen a la entrada | Fórmula reactiva, visibilityRule | formulas, campos de pantalla | 59 | Account_Order_Entry_Screen | Una segunda pantalla para recalcular |
| Reglas de entrada en una pantalla | validationRule de componente | fields de pantalla | cualquiera | Account_Order_Entry_Screen | Decisión después de la pantalla de vuelta a una pantalla de error |
| Lógica de servidor sin salir de la pantalla | Acción de pantalla + Botón de acción | screens.actions, triggers | 59 | Account_Check_Pipeline_Screen | Siguiente, Obtener Registros, volver |
| Establecer campos en el registro disparador | Flow de pre-guardado, Asignación a $Record | triggerType RecordBeforeSave | cualquiera | Opportunity_Before_Save_Set_Next_Step | Actualizar Registros post-guardado en $Record |
| Bloquear un guardado con un mensaje | Custom Error | customErrors | 59 | Opportunity_Before_Save_Set_Next_Step | Compensación post-guardado |
| Ejecutar solo cuando cambien campos relevantes | Condiciones de entrada, filterFormula con ISCHANGED, "solo cuando se actualiza para cumplir la condición" | start | 55 (fórmula) | Opportunity_Before_Save_Set_Next_Step, Opportunity_Closed_Won_Handover | Decisión como primer elemento |
| Llamadas, correos electrónicos, DML no relacionados que el usuario no necesita esperar | Ruta asíncrona | scheduledPaths AsyncAfterCommit | 53 | Opportunity_Closed_Won_Handover | Todo sincrónico |
| Trabajar antes o después de una fecha de registro | Ruta programada | scheduledPaths RecordField | 51 | Opportunity_Closed_Won_Handover | Flow disparado por programación consultando registros vencidos |
| Reaccionar a un evento de plataforma | Flow disparado por evento de plataforma | triggerType PlatformEvent | 49 | Order_Event_Create_Task | Disparador Apex escrito para iniciar lógica de Flow |
| Pausar hasta que llegue un evento | Elemento Wait con un evento de plataforma | waits | cualquiera | Order_Wait_For_Confirmation | Sondeo |
| Lógica de Flow para un agente Agentforce | Flow autoejecutado con entradas y salidas descritas | variables description | cualquiera | Case_Get_Status_For_Agent | Envoltorio Apex invocable |
| Orden entre flows en un mismo objeto | Trigger Order | triggerOrder | 54 | Opportunity_Closed_Won_Handover | Depender del orden de creación |
| Llamar a una API REST | Acción HTTP Callout | actionCalls (generado por Builder) | ver referencia de integración | ninguno | Apex escrito solo para la llamada |
Transform no está permitido en flows de pre-guardado (error de despliegue). Pre-guardado tiene prioridad sobre Transform, por lo que un valor en el registro disparador permanece como pre-guardado, y una Suma allí es un Bucle bajo E3, nunca un Transform post-guardado más un segundo guardado. Todo lo demás arriba funciona en todo tipo de flow que tenga el concepto, y las referencias de dominio enumeran las excepciones.
Condiciones de escape
Un patrón heredado es correcto solo cuando se cumple una de estas condiciones. Decláralo en la <description> de un Bucle como Escape: E<n> <razón>, y en el entregable.
| Id | Permite | Se cumple solo cuando |
|---|---|---|
| E1 | Un Bucle | Cada elemento necesita su propia llamada a una acción, subflow o plugin de Apex que solo acepta valores individuales. El cuerpo del bucle contiene esa llamada. |
| E2 | Un Bucle | El resultado de un elemento depende de elementos anteriores más allá de una suma o cuenta: un saldo corriente, asignación, número de secuencia, round robin. |
| E3 | Un Bucle | Un flow de pre-guardado necesita una Suma (Transform no está permitido allí). Esto es deliberado, porque el Bucle en memoria es más barato que un segundo guardado post-guardado. Los conteos usan Filter + AssignCount en su lugar. |
| E4 | Trabajo en la ruta síncrona | Un elemento posterior en la misma transacción lee el resultado, o el usuario debe verlo antes de que se complete el guardado. |
| E5 | Sin características de pantalla reactiva o más nuevas | La superficie de incrustación nombrada no las soporta: tiempo de ejecución de Salesforce Classic, Slack (conjunto de componentes limitado), o un componente que los documentos reactivos enumeran como no reactivo. |
| E6 | Dejar un patrón heredado en su lugar | Solo ámbito de auditoría: el flow está fuera del cambio que se te pidió hacer. Nunca se aplica a flows nuevos o reescritos. |
Estas no cuentan como condiciones de escape:
- "No puedo verificar que el elemento existe en esta org" (se aplica la regla 2, así que verifica la versión de API, luego valida el despliegue).
- "No estoy seguro del XML" (copia el ejemplo).
- "Un bucle es más simple o más claro."
- "Valores condicionales por elemento" (usa
IF()en una fórmula de Transform). - "Filtrar y mapear en un solo paso" (Filter, luego Transform).
- "La superficie podría no soportarlo" (nombra la superficie o listala como una decisión abierta, porque una superficie desconocida no es E5).
- DML u Obtener Registros dentro de un bucle. Ningún escape lo permite.
Usa el elemento más simple suficiente. Eso significa Filter solo cuando solo se filtra, opciones estáticas cuando la lista de opciones es fija, y ningún subflow para lógica con un solo llamante.
Verificar antes de afirmar
- Disponibilidad: versión de API de la org contra la tabla. Trata las funciones limitadas por licencia (Agentforce, Einstein, Data 360, algunas ediciones de orquestación) como suposiciones hasta que la org las confirme, y dilo.
- Límites y estado de disponibilidad general que cambian un diseño o un hallazgo de auditoría: cita la fuente oficial (help.salesforce.com, developer.salesforce.com). No cites números de memoria, porque las referencias de dominio proporcionan los verificados.
Manejo de errores
- CLI faltante o org inalcanzable: entrega metadatos etiquetados como no validados, o una especificación de construcción, y di cuál.
- La validación falla: corrige según el mensaje exacto, vuelve a ejecutar el verificador y la validación. Las referencias de dominio enumeran los errores de despliegue vistos hasta ahora.
- Característica no en la org (versión de API, edición, licencia): usa la fila compatible más cercana de la tabla, nombra la brecha y el escape.
Referencias
Lee las que la tarea necesite:
- org-conventions.md: las decisiones del equipo, que anulan los valores por defecto.
- collections.md: Filter, Sort, Transform (mapa, suma, cuenta, unión), DML masivo, bucles.
- screens.md: choice sets, pantallas reactivas, validación, acciones de pantalla, incrustación.
- record-triggered.md: condiciones de entrada, modos de disparo, orden, objeto de programación.
- asynchronous.md: rutas asíncronas y programadas, Wait, eventos de plataforma.
- integration.md: llamadas HTTP, acciones de agente, invocación Apex.
- security-sharing.md: contexto de usuario frente a sistema, Modo sin compartir, permiso de acceso a la API de Flow.
- limits.md: tamaño de colección, profundidad de anidamiento, número de elementos, tiempo de ejecución, límites de API de Metadata.
- delivery.md: formato de entregable, lista de verificación de revisión, plantilla de informe de auditoría.
- legacy-migration.md: mapeo de Process Builder y reglas de workflow a Flows.
- agent-actions.md: acciones de agente para Agentforce.