はじめに:仕様書がない。でもテストは始まる。
入社して間もなく参画したSalesforceプロジェクト。
すでに開発はひととおり終わっていて、「これからテストフェーズです」という状態でした。
ところが渡された“要件初期ドキュメント”は、
見事なまでにブラッシュアップされておらず、実装の進行とともに形骸化……。
気づけば、今のシステム仕様がどこにもまとまっていない。
それでも総合テスト・受入テストのタイムリミットはどんどん迫ってくる。
「これはもう、開発環境を“見て”、仕様を“逆に”作るしかない」
そんな状況で始まった、“実装から仕様書を作る”という逆仕様ドキュメンテーションの実体験を、整理してみようと思います。
どこから仕様を復元するか?まずはメタデータを洗い出す
仕様が残っていないなら、“動いているSalesforce環境そのもの”を仕様とみなすしかない。
そこでまずは、以下のような情報を取り出して、ベースとすることにしました:
- オブジェクト構造(項目・型・選択リストなど)
- 各オブジェクト間のリレーション(親子構造・参照関係)
- 自動処理(Flow)とその条件・アクション
とはいえ、これらを画面から手作業で拾うのは非現実的。
そんな中で めちゃくちゃ助けられたのが「Salesforce DevTools」 というChrome拡張です。
🛠️ Salesforce DevToolsが神だった話
この拡張機能、使ったことがない方は今すぐ入れてほしいレベルです。
主な機能として:
- オブジェクト定義書をCSVで出力(項目名/ラベル/型/選択肢/必須設定 など)
- ER図を自動生成(しかもSVGで出力可能)
- SOQLやSchema構造のクエリ支援
- 選択リストの中身だけ抜き出すことも可能
→ 正直、この拡張がなければ仕様書再構築の速度は1/3以下だったと思います。
Flowの中身をどう読むか?メタデータ(.flow)の構造解析
Flowの仕様はUI上で可視化されてはいるものの、
分岐条件や変数の扱いなど“本当の仕様”を把握するには限界があります。
そこで、Flowの構造をXMLで出力して中身を直接読むというアプローチを取りました。
📦 Flowメタデータの取得方法
- Salesforce Workbench にログイン
-
Metadata > Retrieve
を選択し、対象のFlowを指定(複数指定も可) - 取得したZIPファイルを解凍
すると、以下のようなファイル構成になります:
unpackaged/flows/
├── CreatePurchaseOrderHistory1.flow
├── CreatePurchaseOrderHistory2.flow
├── ...
├── CreateSalesAmountRecord.flow
├── ProjectDeliveryFlow.flow
├── QuoteRequestFlow3.flow
└── ...
※このとき
.flow
ファイルの中身はXML形式で記述されており、
各要素(<recordCreate>
,<decision>
,<variable>
など)によって処理フローが定義されています。
🔍 .flowファイルの中に含まれる主な構造(例)
-
processMetadataValues
:Flowのプロパティやアクティブ状態など -
status
:Active
/Draft
など -
recordCreates
,recordUpdates
:レコード操作系の処理 -
decisions
:条件分岐ロジック -
assignments
:変数の値の変更処理 -
interviewLabel
:ユーザーに見える処理名 -
processType
:Flow
,AutoLaunchedFlow
,Workflow
など
詳しくはSalesforce側のドキュメント参照
https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/meta_visual_workflow.htm
👓 補足:XMLの中身を確認するには?
おすすめは以下の2つのツール:
- VS CodeのXML拡張(構造が折りたためて見やすい)
- XML Viewer などのWebツールでビジュアルに確認
このようにして、UIでは見えない処理条件・変数・フローの接続構造を精査し、
業務要件とのギャップがないか、制御の意図が一貫しているかを判断していきました。
Flow構造の読み解き例:現場で整理した動作条件の一覧
Flowの仕様を明確にするために、実際には以下のように
Google Sheetsで構造を整理しながら一覧化していきました。
(※プロジェクト名や項目名は仮名化しています)
API名 | 表示ラベル名 | 有効状態 | トリガー条件 | 開始ノード | アクション条件 | アクション内容 |
---|---|---|---|---|---|---|
SampleFlow1 | 【ダミー】サンプルフロー1 | Active | No Record Trigger | UpDate | なし | レコード更新: 親商談の金額を再計算 |
SampleFlow2 | 【ダミー】サンプルフロー2 | Obsolete | No Record Trigger | Check | 項目チェック済み: and($Record.A, $Record.B)
|
レコード更新: フェーズを「製造管理」に更新 |
SampleFlow3 | 【ダミー】サンプルフロー3 | Obsolete | No Record Trigger | Check | 項目チェック済み: and($Record.phase, ...)
|
レコード更新: フェーズを「増減見積」に更新 |
SampleFlow4 | 【ダミー】サンプルフロー4 | Obsolete | No Record Trigger | Check | 項目チェック済み: and($Record.partner, ...)
|
レコード更新: 「追加見積」に変更 |
SampleFlow5 | 【ダミー】サンプルフロー5 | Active | No Record Trigger | HavingARecord | 発注明細がある: or($Record.UnitCost > 100000)
|
レコード更新: アラートをON、対象金額も再設定 |
このように整理することで、
- 実行条件や分岐ロジック
- 開始ノードやアクション対象
- 更新されるデータと期待される結果
を仕様として復元することができました。
この記事は「逆仕様シリーズ - Flow編」の第1回でした。
次回以降は、MashmatrixのUI制御、権限セットによる活性化/非活性化ロジック、
バリデーション定義書との突合など、“ドキュメントに載ってない仕様”をどう整理したかを掘り下げていきます。