Salesforce Flow 現代化
模型會預設採用其訓練資料中的 Flow 模式:Loop + Decision + Assignment、迴圈內進行 DML、觸發記錄的儲存後更新、用於重新計算的多餘畫面。此技能將這些模式取代為目前平台上的元素,並為每個元素提供已部署驗證的中繼資料範例,儲存在 examples/ 目錄中。
以下規則決定了大部分情況的處理方式:
- 現代元素是預設選擇。 使用 Loop 必須宣告一個明確的逃脫條件(請見下方)。當某個元素的 XML 不熟悉時,請從其範例檔案複製結構,而非避免使用該元素。
- 無法驗證不等於無法使用。 元素的可用性取決於組織的 API 版本及下方的表格。若某元素的最低支援 API 版本等於或低於組織的版本,您不需要網路存取即可使用它。部署驗證才是最終的確認方式。
- 每個迴圈和每個替代方案都必須說明原因。 在 Loop 的描述和交付成果中命名逃脫條件。如果沒有命名的逃脫條件,就不要撰寫 Loop。
工作流程
將此清單複製到您的工作筆記中,並逐項勾選:
- [ ] 1. 閱讀 references/org-conventions.md;列出此任務依賴但尚未設定的項目
- [ ] 2. 確認組織 API 版本
- [ ] 3. 分類任務:建立、稽核或遷移;Flow 類型、觸發事件、執行身分
- [ ] 4. 將每個需求對應到決策表;開啟您將使用的每個範例
- [ ] 5. 撰寫中繼資料(或建置規格)
- [ ] 6. 執行 scripts/check-flow.mjs;修正所有 ERROR,對每個 WARNING 做出決定
- [ ] 7. 當有可用的組織時進行部署驗證;否則將 XML 標記為未驗證
- [ ] 8. 執行 references/delivery.md 中的審查清單並交付
步驟 1. 慣例。 org-conventions.md 中已填寫的項目會凌駕於此技能的預設值。空白的項目表示套用預設值,且交付成果應將其列於開放決策項目中。
步驟 2. API 版本。 若有組織,sf org display --target-org <別名> 會顯示「Api Version」。若無組織,則使用專案 sfdx-project.json 中的 sourceApiVersion,若仍無此值則使用 67.0,並於交付成果中說明。將新 Flow 的 apiVersion 設定為該版本。
步驟 3. 分類。 現有 Flow 或新建構。Flow 類型(畫面、記錄觸發-更新前或更新後儲存、自動啟動、排程觸發、平台事件觸發)。觸發物件和觸發事件,應從需求中獲取答案,然後再開啟任何範例。需要確認的問題是:一個已符合條件的記錄是否會觸發,還是只有「變為」符合條件的記錄才會觸發。設定為「僅在更新為符合條件時」的「建立與更新」會在這種建立情境下觸發,而僅「更新」不會。如果需求未說明,請提問或陳述假設(record-triggered.md)。執行身分(使用者、系統、代理人)。必須同步完成的事項。對於畫面 Flow,需要知道嵌入它的表面(Surfaces)、它接收什麼以及回傳什麼。
步驟 4. 對應。 對於每個集合操作、選擇清單、畫面互動、記錄更新、時間需求與整合,從決策表中選取對應的行。閱讀您將撰寫的每個元素的範例檔案,以及其領域參考來了解限制。只閱讀任務所觸及領域的參考文件。
步驟 5. 撰寫。 中繼資料放置於 force-app/main/default/flows/<ApiName>.flow-meta.xml(需調整為專案的套件目錄)。命名預設:Flow API 名稱 Object_Verb_Condition,元素名稱 Type_Purpose(Get_Open_Cases、Filter_High_Priority、Transform_To_Tasks、Dec_Is_Renewal),除非 org-conventions.md 另有規定。設定 <status>Draft</status>,除非使用者明確要求啟用中的 Flow,或 activation-policy 項目已設定為啟用。範例僅因實際執行過而為 Active。將相同類型的所有元素保持在一起(分組會導致部署失敗)。若無 CLI 存取權限,則以 delivery.md 中定義的格式交付建置規格。
步驟 6. 檢查。 對您撰寫或被要求審查的每個 Flow 執行檢查器。它只需要 Node:
node <技能目錄>/scripts/check-flow.mjs --api <組織 API 版本> force-app/main/default/flows/<ApiName>.flow-meta.xml
ERROR 表示舊模式或平台不接受的形式,因此必須修正。WARNING 需要做出決定,您需在交付成果中說明。
步驟 7. 驗證。 使用已驗證的組織時,明確指定組織名稱,而不是依賴 CLI 的預設組織:
sf project deploy validate --source-dir force-app/main/default/flows/<ApiName>.flow-meta.xml --target-org <別名>
根據確切的錯誤訊息進行修正並重新執行。未經驗證的 XML 應在交付成果中直接標記為未驗證。
步驟 8. 審查與交付。 執行 delivery.md 中的審查清單。在交付成果的結尾加上以下區塊,並填寫每一行:
模式: 中繼資料 | 建置規格
檢查器: <命令> → <n> 個錯誤, <n> 個警告 (<每個警告的決策>)
部署驗證: <命令與結果> | 未執行,未驗證 (<原因>)
狀態: 草稿 | 啟用 (<原因>)
執行上下文: <runInMode 或預設值,以及這對此 Flow 類型的意義>
逃脫條件: <E-id 和每個迴圈或替代方案的原因> | 無
開放決策: <此 Flow 依賴但未設定的慣例項目> | 無
執行上下文預設值 (runInMode DefaultMode):記錄觸發、排程觸發和平台事件觸發的 Flow 以系統上下文執行(不共用)。畫面 Flow 和自動啟動 Flow 從 UI 或 REST API 啟動時以使用者上下文執行,從 Apex 或其他 Flow 呼叫時則以呼叫者的上下文執行。自動啟動並非「預設為系統」。
稽核與遷移
對於現有 Flow,先對其執行檢查器,然後對照決策表的最後一欄盤點剩餘的舊模式。在任何改寫之前,先交付 delivery.md 中定義的稽核報告,並按影響程度排序:主管限制、安全性上下文、使用者體驗。除非被要求,否則不要修改 Flow。當被要求時,按照報告中的遷移計畫依序進行。描述模式,而非建立它們的人員,因為大多數舊模式在當時是被建議的做法。 Process Builder 和工作流程規則的對應資訊在 legacy-migration.md 中。
決策表
「Org API」是指擁有該元素的最低組織 API 版本(Flow, Metadata API 開發指南)。範例位於 examples/flows/,已在 API 67.0 上部署並執行。
| 需求 | 使用 | 中繼資料 | Org API | 範例 | 取代 |
|---|---|---|---|---|---|
| 從集合中保留符合條件的項目 | 集合篩選 (Collection Filter) (條件或公式) | collectionProcessors, FilterCollectionProcessor | 53 | Opportunity_Create_Followup_Tasks | Loop + Decision + Assignment |
| 從集合建立記錄、重塑欄位 | 轉換 (Transform), 映射 (Map) | transforms | 59 | Opportunity_Create_Followup_Tasks | 建立集合的 Loop + Assignment |
| 對集合進行加總或計數 | 轉換 (Transform), 總和 (Sum) / 計數 (Count)。在更新前儲存 Flow 中,使用 Filter + Assignment AssignCount,或使用 Loop 進行 Sum(E3) | transforms, inputParameters | 59 (基本目標 62) | Opportunity_Create_Followup_Tasks, Account_Before_Save_Count_Contacts | Loop 計數器 |
| 透過鍵值合併兩個集合 | 轉換 (Transform), 內部聯結 (InnerJoin),使用同一個 Transform 中的映射 | transforms, JoinDefinition | 63 | Opportunity_Create_Account_Tasks_Joined | 巢狀 Loop,迴圈內取得記錄 |
| 排序集合 | 集合排序 (Collection Sort)(原地排序) | SortCollectionProcessor | 50 | Opportunity_Allocate_Budget_Waterfall | 在 Loop 中手動排序 |
| 大量建立、更新或刪除多筆記錄 | 對準備好的集合執行一次 DML | recordCreates inputReference | 任意 | Opportunity_Create_Followup_Tasks | 迴圈內進行 DML |
| 來自記錄或選擇清單的選項 | 記錄 / 選擇清單選擇集 (Record / Picklist Choice Set) | dynamicChoiceSets | 任意 | Account_Order_Entry_Screen | 取得記錄 + 建立選擇的 Loop |
| 根據輸入變化的總計、可見性或文字 | 反應式公式 (Reactive Formula), visibilityRule | formulas, 畫面欄位 | 59 | Account_Order_Entry_Screen | 用於重新計算的第二個畫面 |
| 畫面輸入規則 | 元件 validationRule | 畫面 fields | 任意 | Account_Order_Entry_Screen | 畫面後的決策回錯誤畫面 |
| 不離開畫面執行伺服器邏輯 | 畫面動作 (Screen Action) + 動作按鈕 (Action Button) | screens.actions, triggers | 59 | Account_Check_Pipeline_Screen | 下一步、取得記錄、再返回 |
| 設定觸發記錄的欄位 | 更新前儲存 Flow,對 $Record 進行 Assignment | triggerType RecordBeforeSave | 任意 | Opportunity_Before_Save_Set_Next_Step | 對 $Record 的更新後儲存更新記錄 |
| 用訊息阻止儲存 | 自訂錯誤 (Custom Error) | customErrors | 59 | Opportunity_Before_Save_Set_Next_Step | 更新後儲存的補償邏輯 |
| 僅在相關欄位變更時執行 | 項目條件 (Entry Conditions),搭配 ISCHANGED 的 filterFormula,「僅在更新為符合條件時」 | start | 55 (公式) | Opportunity_Before_Save_Set_Next_Step, Opportunity_Closed_Won_Handover | 作為第一個元素的決策 |
| 使用者無需等待的呼叫、電子郵件、不相關 DML | 非同步路徑 (Asynchronous Path) | scheduledPaths AsyncAfterCommit | 53 | Opportunity_Closed_Won_Handover | 所有同步操作 |
| 在記錄日期前後的工作 | 排程路徑 (Scheduled Path) | scheduledPaths RecordField | 51 | Opportunity_Closed_Won_Handover | 輪詢即將到期記錄的排程觸發 Flow |
| 回應平台事件 | 平台事件觸發 Flow | triggerType PlatformEvent | 49 | Order_Event_Create_Task | 為啟動 Flow 邏輯而撰寫的 Apex 觸發程序 |
| 暫停直到事件到達 | 含平台事件的等候元素 (Wait Element) | waits | 任意 | Order_Wait_For_Confirmation | 輪詢 |
| 為 Agentforce 代理人提供的 Flow 邏輯 | 帶有描述輸入和輸出的自動啟動 Flow | variables description | 任意 | Case_Get_Status_For_Agent | 可呼叫的 Apex 包裝器 |
| 同一個物件上 Flow 的執行順序 | 觸發順序 (Trigger Order) | triggerOrder | 54 | Opportunity_Closed_Won_Handover | 依賴建立順序 |
| 呼叫 REST API | HTTP 呼叫動作 (HTTP Callout Action) | actionCalls (Builder 產生) | 請參閱整合參考 | 無 | 僅為呼叫而撰寫的 Apex |
在更新前儲存的 Flow 中不允許使用轉換 (Transform)(部署錯誤)。更新前儲存的優先級高於轉換,因此觸發記錄上的值會保持在更新前儲存中,那裡的 Sum 將在 E3 規則下使用 Loop,絕不使用更新後儲存的 Transform 加上第二次儲存。以上其他所有元素在所有具有該概念的 Flow 類型中都可運作,領域參考文件會列出例外情況。
逃脫條件
僅在以下情況之一成立時,才能正確使用舊模式。在 Loop 的 <description> 中宣告為 Escape: E<n> <原因>,並在交付成果中說明。
| 編號 | 允許 | 僅當以下情況成立 |
|---|---|---|
| E1 | 一個 Loop | 每個項目需要單獨呼叫一個僅接受單一值的動作、子流程或 Apex 外掛程式。Loop 主體包含該呼叫。 |
| E2 | 一個 Loop | 項目的結果取決於先前的項目(不僅是總和或計數):如運行中的餘額、分配、序號、輪詢分配。 |
| E3 | 一個 Loop | 更新前儲存 Flow 需要一個 Sum(那裡不允許使用 Transform)。這是刻意的,因為記憶體中的 Loop 比更新後儲存的第二次儲存成本更低。計數應使用 Filter + AssignCount 替代。 |
| E4 | 在同步路徑上工作 | 同一個交易中的後續元素會讀取此結果,或者使用者必須在儲存完成前看到它。 |
| E5 | 不使用反應式或較新的畫面功能 | 命名的嵌入表面不支援這些功能:Salesforce Classic 執行階段、Slack(元件集有限),或反應式文件列為非反應式的元件。 |
| E6 | 保留舊模式不變 | 僅限稽核範圍:該 Flow 不在您被要求進行的變更範圍內。不適用於新建或重寫的 Flow。 |
以下情況不視為逃脫條件:
- 「我無法驗證此元素是否存在於此組織」(適用規則 2,因此請檢查 API 版本,然後進行部署驗證)。
- 「我不確定 XML 的寫法」(複製範例)。
- 「Loop 比較簡單或清楚」。
- 「每個項目的條件值不同」(在 Transform 公式中使用
IF())。 - 「一次傳遞中進行篩選和映射」(先 Filter,再 Transform)。
- 「表面可能不支援」(請指定表面名稱或將其列為開放決策,因為未知表面不屬於 E5)。
- 在迴圈內進行 DML 或取得記錄。沒有任何逃脫條件允許它們。
使用最簡單、足夠的元件。這意味著僅需篩選時使用 Filter,選項清單固定時使用靜態選擇,對於只有一個呼叫者的邏輯不要使用子流程。
先驗證再斷言
- 可用性:根據表格檢查組織 API 版本。將受許可證限制的功能(Agentforce、Einstein、Data 360、某些協調版本)視為假設,直到組織確認它們為止,並在文件中說明。
- 會改變設計或稽核結果的限制和 GA 狀態:引用官方來源(help.salesforce.com、developer.salesforce.com)。不要憑記憶引用數字,因為領域參考文件已提供經過驗證的數字。
錯誤處理
- CLI 缺失或組織無法連線:交付標記為未驗證的中繼資料或建置規格,並說明是哪一種。
- 驗證失敗:根據確切的錯誤訊息修正,重新執行檢查器和驗證。領域參考文件列出了目前遇到的部署錯誤。
- 組織中無此功能(API 版本、版本、許可證):使用表格中最接近的支援行,說明差距和使用的逃脫條件。
參考資料
閱讀任務所需的文件:
- org-conventions.md:團隊的決定,凌駕於預設值之上。
- collections.md:Filter、Sort、Transform (map、sum、count、join)、大量 DML、Loop。
- screens.md:選擇集、反應式畫面、驗證、畫面動作、嵌入。
- record-triggered.md:觸發事件語意、過濾條件。
- scheduled-paths.md:非同步和排程路徑。
- platform-events.md:平台事件觸發和等候。
- legacy-migration.md:從 Process Builder 和工作流程規則遷移。
- delivery.md:最終審查清單和交付格式。