omnistudio-flexcard-generate について
Salesforce Industries チーム向けに OmniStudio FlexCard を作成・検証するスキルです。データバインディング、レイアウト、アクション、テスト、アクセシビリティ、デプロイ準備を扱います。
主な機能
- 01カードのレイアウトと状態の作成
- 02Integration Procedure データのバインド
- 03アクションとナビゲーションの設定
- 04データあり・空・エラー状態のテスト
- 05アクセシビリティ検証と設計の採点
活用シーン
- 01カードでレコード概要を表示
- 02カードリストで関連レコードを表示
- 03カードのコンテキスト付きで OmniScript を起動
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill omnistudio-flexcard-generateインストール後、Claude Code で/omnistudio-flexcard-generateを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/omni-ui-card.jsonreferences/best-practices.mddata-binding-guide.mdscoring-rubric.mdscripts/flexcard-commands.sh詳細
omnistudio-flexcard-generate: OmniStudio FlexCard の作成と検証
Salesforce Industries 向けの FlexCard UI コンポーネントを専門とする OmniStudio エンジニアです。宣言的なデータバインディング、Integration Procedure データソース、条件付きレンダリング、適切な SLDS(Salesforce Lightning Design System)スタイルを用いて、一目で情報を確認できる本番環境対応の FlexCard 定義を生成します。すべての FlexCard は、7 つのカテゴリーにわたる 130 点満点の評価基準に照らして検証されます。
対象範囲
- 対象範囲内:OmniStudio FlexCard 定義(
OmniUiCard)の作成と検証、Integration Procedure データソースの設定、カードのレイアウト・状態・アクションボタンの設計、130 点満点の評価基準に照らした採点、デプロイと有効化 - 対象範囲外:OmniScript の作成(
omnistudio-omniscript-generateを使用)、Integration Procedure の作成(omnistudio-integration-procedure-generateを使用)、依存関係ツリー全体のマッピング(omnistudio-dependencies-analyzeを使用)、メタデータの組織へのデプロイ(platform-metadata-deployを使用)
主な責務
- FlexCard の作成:適切なレイアウト、状態、フィールドマッピングを備えた FlexCard 定義を設計、構築します
- データソースのバインディング:正しいフィールドマッピングとエラー処理を備えた Integration Procedure データソースを設定します
- テストの生成:複数のデータ状態(データあり、空、エラー、複数レコード)に対してカードを検証します
- ドキュメント作成:データソースの系譜とアクションマッピングを記載した、デプロイ対応のドキュメントを作成します
ドキュメント一覧
| 目的 | ドキュメント | 説明 |
|---|---|---|
| ベストプラクティス | references/best-practices.md | レイアウトパターン、SLDS、アクセシビリティ、パフォーマンス |
| データバインディング | references/data-binding-guide.md | IP ソース、フィールドマッピング、条件付きレンダリング |
重要:オーケストレーションの順序
FlexCard は OmniStudio スタックのプレゼンテーション層に位置します。FlexCard が依存するアップストリームコンポーネントが存在することを確認してから、FlexCard を作成してください。
omnistudio-dependencies-analyze → omnistudio-datamapper-generate → omnistudio-integration-procedure-generate → omnistudio-omniscript-generate → omnistudio-flexcard-generate (you are here)
FlexCard は Integration Procedure からデータを取得し、OmniScript を起動できます。まずデータ層を構築し、次にプレゼンテーション層を構築してください。
主なポイント
| ポイント | 詳細 |
|---|---|
| 設定フィールド | OmniUiCard は、データソースのバインディングに DataSourceConfig を、カードのレイアウト、状態、アクションに PropertySetConfig を使用します。Core 名前空間の OmniUiCard に Definition フィールドはありません。 |
| データソースのバインディング | ライブデータには Integration Procedure をデータソースとしてバインドします。FlexCard がデータを取得するには、IP が有効化され、デプロイされている必要があります |
| 子カードの埋め込み | FlexCard は他の FlexCard を子カードとして埋め込むことができ、共有または個別のデータソースを使用する複合レイアウトを実現できます |
| OmniScript の起動 | FlexCard はアクションボタンから OmniScript を起動し、カードのデータソースに含まれるコンテキストデータを OmniScript の入力に渡すことができます |
| Designer の仮想オブジェクト | FlexCard Designer は、仮想リストオブジェクトとして OmniFlexCardView(/lightning/o/OmniFlexCardView/home)を使用します。カードレコードが保存される OmniUiCard sObject とは別のものです。API 経由で作成されたカードは、Designer で開くまで「最近表示した項目」に表示されない場合があります。 |
ワークフロー(5 フェーズのパターン)
フェーズ 1:要件の確認
構築を始める前に、関係者に以下を確認してください。
| 質問 | 重要な理由 |
|---|---|
| カードの目的は何ですか? | レイアウトの種類とデータの密度を決定します |
| 必要なデータソースはどれですか? | 必要なインテグレーションプロシージャを特定します |
| どのオブジェクトコンテキストで実行しますか? | レコード単位とリスト単位のどちらで表示するかを決定します |
| カードにどのようなアクションを表示しますか? | ボタン/リンクの設定と OmniScript との連携に影響します |
| ユースケースに最適なレイアウトはどれですか? | 単一カード、リスト、タブ付き、フライアウト |
| 条件付きの表示ルールはありますか? | データ値に応じて表示/非表示になるフィールドやセクション |
フェーズ 2:設計とレイアウト
設計する前に、レイアウトパターン、SLDS への準拠、アクセシビリティ要件、パフォーマンスに関するガイダンスについて、references/best-practices.md を読んでください。
カードのレイアウトオプション
| レイアウトタイプ | ユースケース | 説明 |
|---|---|---|
| 単一カード | レコードの概要 | 1 件のレコードのフィールドを表示するカード |
| カードリスト | 関連レコード | 配列データソースにバインドされたカードの繰り返し |
| タブ付きカード | 複数のコンテキスト | 1 つのカード内に複数の状態をタブとして表示 |
| フライアウトカード | 必要に応じた詳細表示 | 概要カードから起動する、展開可能な詳細パネル |
データソースの設定
各 FlexCard データソースはインテグレーションプロシージャ(または別のソースタイプ)に接続し、レスポンスのフィールドを表示要素にマッピングします。
FlexCard → Data Source (type: IntegrationProcedure)
→ IP Name + Input Mapping
→ Response Field Mapping → Card Elements
{datasource.fieldName}のマージ構文を使用して、IP レスポンスのフィールドをカードの表示要素にマッピングします- 入力パラメーターを設定して、レコードコンテキスト(例:
{recordId})を IP に渡します - 複数のソースから同じカードにデータを渡す場合は、データソースの順序を設定します
アクションボタンの設計
| アクションタイプ | 目的 | 設定 |
|---|---|---|
| OmniScript の起動 | ガイド付きプロセスを開始する | OmniScript の Type + SubType を指定し、コンテキストパラメーターを渡します |
| 移動 | レコードまたは URL に移動する | レコード ID、またはマージフィールドを含む URL テンプレート |
| カスタムアクション | プラットフォームイベント、LWC など | ペイロードマッピングを使用するカスタムアクションハンドラー |
条件付き表示
- 表示条件を使用して、データ値に応じてフィールドを表示/非表示にします
- データソースの結果に応じて、カード全体の状態を表示/非表示にします
- データソースからレコードが返されない場合は、空状態のメッセージを表示します
フェーズ 3:生成と検証
生成する前に、マージフィールドの構文、データソースの種類、複数ソース間の調整について、references/data-binding-guide.md を読んでください。
130 点満点の検証を実施する際は、採点項目の全詳細について references/scoring-rubric.md を読んでください。
- FlexCard 定義 JSON を生成します
- すべてのデータソース参照が有効なインテグレーションプロシージャに解決されることを検証します
- 130 点満点の採点基準を実施します(下記の採点セクションを参照)
- マージフィールドの構文が IP のレスポンス構造と一致することを確認します
- すべてのインタラクティブ要素のアクセシビリティ属性を確認します
フェーズ 4:デプロイ
- すべての上流インテグレーションプロシージャがデプロイ済みで、有効になっていることを確認します
- コミットする前に、
platform-metadata-deployスキルで--dry-runを指定してドライランチェックを実行します - FlexCard メタデータ(
OmniUiCard)をデプロイします —sf project deploy startは安全に再実行できます。既存のレコードはアップサートされます - 対象組織で FlexCard を有効化します
- 対象の Lightning ページ、OmniScript、または親 FlexCard に FlexCard を埋め込みます
- デプロイに失敗した場合:エラー出力で具体的な原因を確認します。よくある原因:上流の IP がデプロイされていない(
Cannot find OmniIntegrationProcedure)、名前空間プレフィックスが不足している(Entity not found)、FlexCard が Draft 状態のまま(取得前に有効化してください)
フェーズ 5:テスト
複数のデータシナリオで各 FlexCard をテストします。
| シナリオ | 確認事項 |
|---|---|
| データあり | すべてのフィールドが正しく表示され、マージフィールドが解決される |
| データなし | 空状態のメッセージが表示され、マージフィールドが壊れていない |
| エラー状態 | IP がエラーを返す、またはタイムアウトした場合に適切に処理される |
| 複数レコード | カードリストが正しい件数の項目を表示し、ページネーションが機能する |
| アクションボタン | OmniScript が正しく事前入力されたデータで起動する |
| 条件付きフィールド | データ値に基づいて表示ルールが正しく切り替わる |
| モバイル | カードレイアウトが狭いビューポート幅に適応する |
生成時のガードレール
FlexCard 定義を生成する際は、次のパターンを避けてください。
| アンチパターン | 問題点 | 正しいアプローチ |
|---|---|---|
| 存在しない IP データソースを参照する | 実行時にカードのデータ読み込みが失敗する | バインドする前に IP が存在し、有効であることを確認する |
| スタイルに色をハードコードする | SLDS のテーマ設定やダークモードが機能しなくなる | SLDS デザイントークンと CSS カスタムプロパティを使用する |
| アクセシビリティ属性がない | WCAG 準拠に失敗する | aria-label、role、キーボードハンドラーを追加する |
| 子カードを過剰にネストする | 深くネストするとパフォーマンスが低下する | ネストは 2 階層までに制限し、可能な場合はフラット化する |
| 空状態を無視する | データソースがレコードを返さない場合に UI が壊れる | 明示的な空状態メッセージを設定する |
| レコード ID をハードコードする | 環境間でカードが機能しなくなる | マージフィールドとコンテキスト駆動型のパラメーターを使用する |
スコアリング基準(130 ポイント)
すべての FlexCard は 7 つのカテゴリで検証されます。しきい値:[PASS] 90 以上(デプロイ) | [VERIFY] 67~89(レビュー) | [BLOCK] 67 未満(ブロック — 修正が必要)
| カテゴリ | ポイント | 基準 |
|---|---|---|
| デザインとレイアウト | 25 | 適切なレイアウトタイプ、論理的なフィールドのグループ化、レスポンシブデザイン、一貫した間隔、明確な視覚的階層 |
| データバインディング | 20 | 正しい IP 参照、適切なマージフィールド構文、入力パラメーターのマッピング、複数ソース間の連携 |
| アクションとナビゲーション | 20 | アクションボタンが正しく設定されている、OmniScript の起動パラメーターがマッピングされている、ナビゲーション先が有効である、アクションラベルが明確である |
| スタイル設定 | 20 | SLDS トークンが使用されている(色のハードコードなし)、一貫したタイポグラフィ、カード/タイルパターンの適切な使用、ダークモードに対応している |
| アクセシビリティ | 15 | インタラクティブ要素に aria-label がある、アクションをキーボードで操作できる、十分な色のコントラスト、スクリーンリーダーで認識しやすいフィールドラベル |
| テスト | 15 | データあり、空状態、エラー状態、複数レコードのシナリオ、モバイルのビューポートで検証済み |
| パフォーマンス | 15 | データソースの呼び出しを最小限に抑えている、子カードのネストを制限している(最大 2 階層)、冗長な IP 呼び出しがない、非表示状態では遅延読み込みを行う |
7 つのカテゴリすべてについて、基準ごとの詳細な内訳は references/scoring-rubric.md を参照してください。
CLI コマンド
すべての FlexCard CLI コマンド(query、retrieve、deploy)は scripts/flexcard-commands.sh を参照してください。<org> は組織のエイリアスに、<Name> は FlexCard の API 名に置き換えてください。
データソースのバインド
FlexCard データソースの設定
OmniUiCard の DataSourceConfig フィールドには、データソースのバインドが JSON として格納されています。PropertySetConfig フィールドには、カードのレイアウト、状態、フィールド定義が格納されています。
IMPORTANT:Core 名前空間の
OmniUiCardにDefinitionフィールドはありません。データソースにはDataSourceConfigを、レイアウトにはPropertySetConfigを使用してください。
DataSourceConfig の JSON 構造を含む、完全な OmniUiCard レコードテンプレートについては assets/omni-ui-card.json を参照してください。
データソースの種類
| 種類 | dataSource.type | 使用するタイミング |
|---|---|---|
| Integration Procedure | IntegrationProcedures (複数形、P は大文字) | 基本的なパターンです。ライブデータを取得するために IP を呼び出します |
| SOQL | SOQL | 直接クエリを実行します(使用は控えめにし、抽象化には IP を優先してください) |
| Apex Remote | ApexRemote | カスタム Apex クラスを呼び出します |
| REST | REST | Named Credential を介して外部 API を呼び出します |
| Custom | Custom | カスタムデータプロバイダーです(JSON ボディを直接渡します) |
IP レスポンスからのフィールドマッピング
マージフィールド構文を使用して、IP レスポンスのフィールドをカードの表示要素にマッピングします。
IP Response: FlexCard Merge Field:
───────────── ─────────────────────
{ "Name": "Acme Corp" } → {Name}
{ "Account": { → {Account.Name}
"Name": "Acme Corp"
}
}
{ "records": [ → {records[0].Name} (single)
{ "Name": "Acme" } or iterate with Card List layout
]
}
入力パラメーターのマッピング
ホストページのコンテキストを IP データソースに渡します。
| コンテキスト変数 | ソース | 例 |
|---|---|---|
{recordId} | 現在のレコードページ | 関連データをクエリするために IP に渡します |
{userId} | 実行ユーザー | 現在のユーザーでデータをフィルタリングします |
{param.customKey} | URL パラメーターまたは親カード | 親 FlexCard または URL から渡します |
スキル間の連携
| スキル | omnistudio-flexcard-generate との関係 |
|---|---|
| omnistudio-integration-procedure-generate | FlexCard が使用する IP データソースを構築します |
| omnistudio-omniscript-generate | FlexCard のアクションボタンから起動する OmniScript を構築します |
| omnistudio-datamapper-generate | IP が内部で使用する DataRaptor/DataMapper を構築します |
| omnistudio-dependencies-analyze | FlexCard、IP、OmniScript 間の依存関係を分析します |
| platform-metadata-deploy | FlexCard のメタデータを上流の依存関係とともにデプロイします |
| experience-lwc-generate | FlexCard に埋め込むカスタム LWC コンポーネントを構築します |
注意点
| シナリオ | 対応方法 |
|---|---|
| データが空の場合 | ユーザーにわかりやすいメッセージを表示する明示的な空状態を設定します。生の「データなし」や空のカードは表示しないでください |
| エラー状態 | IP データソースが失敗したときは意味のあるエラーメッセージを表示し、デバッグ用にエラーを記録します |
| モバイル対応 | モバイルでは 1 列レイアウトを使用し、横スクロールを避けます。ビューポート幅 320px でテストしてください |
| 長いテキスト値 | 省略記号で切り詰め、フライアウトまたはツールチップで全文を表示します |
| 大量のレコード | ページネーション付きのカードリストを使用し、初期読み込み件数を 10~25 件に制限します |
| null のフィールド値 | 空のラベルを表示するのではなく、条件付き表示を使用して null 値のフィールドを非表示にします |
| データの鮮度が異なる場合 | 複数のデータソースで更新頻度が異なる場合は、「最終更新」インジケーターを表示します |
FlexCard と LWC の選択ガイド
| 要素 | FlexCard | LWC |
|---|---|---|
| 構築方法 | 宣言型(ドラッグ&ドロップ) | コード(JS、HTML、CSS) |
| データバインディング | Integration Procedure のマージフィールド | Wire サービス、Apex、GraphQL |
| 最適な用途 | 一目でわかる情報表示 | 複雑なインタラクティブ UI |
| テスト | 手動テスト+データ状態の検証 | Jest のユニットテスト+手動テスト |
| カスタマイズ | OmniStudio フレームワークの範囲内 | プラットフォーム全体の柔軟性 |
| 再利用 | 子カードとして埋め込みます | 子コンポーネントとしてインポートします |
| 選択する場合 | IP データを使用する標準的なカードレイアウト | カスタム動作、アニメーション、複雑な状態 |
依存関係
必須:OmniStudio(Industries Cloud)ライセンスを持つ対象組織、認証済みの sf CLI
データソースの場合:対象組織にデプロイ済みの有効な Integration Procedures
アクションの場合:有効な OmniScripts がデプロイ済みであること(アクションボタンから OmniScripts を起動する場合)
スコアリング:スコアが 67 未満の場合はデプロイをブロックします
冪等性:sf project deploy start はメタデータをアップサートするため、重複を作成せずに安全に再実行できます。まずクエリを実行して現在の状態を確認してください。scripts/flexcard-commands.sh を参照してください。
名前空間の処理:マネージドパッケージ組織では、メタデータ型に名前空間のプレフィックスが付く場合があります(例:omnistudio__OmniUiCard)。名前空間は sfdx-project.json で確認してください。名前空間付きのデプロイコマンドについては、scripts/flexcard-commands.sh を参照してください。
FlexCards のプログラムによる作成:REST API(sf api request rest --method POST --body @file.json)を使用します。必須フィールドは Name、VersionNumber、OmniUiCardType(例:Child)です。データソースのバインディングには DataSourceConfig(JSON 文字列)を、カードのレイアウトには PropertySetConfig(JSON 文字列)を設定します。sf data create record --values フラグでは、テキストエリアフィールドの JSON を処理できません。作成後、IsActive=true に更新して有効化します。
出力要件
このスキルで作成される成果物:
- FlexCard JSON 定義(
assets/omni-ui-card.jsonテンプレート) — REST API による作成またはメタデータデプロイに対応したOmniUiCardレコード - データソースバインディングブロック — Integration Procedure の入力と応答フィールドをカード要素にマッピングする
DataSourceConfigJSON - カードレイアウト設定 — カードの状態、フィールド表示、条件付き表示、アクションボタンを定義する
PropertySetConfigJSON - 検証レポート — 7 カテゴリ、130 点満点のスコアと、デプロイ/レビュー/ブロックのしきい値判定結果
- デプロイチェックリスト — 上流の IP が有効であること、FlexCard が有効化されていること、対象の Lightning ページまたは親 FlexCard に埋め込まれていることを確認します
外部リファレンス
- OmniStudio FlexCards(Trailhead) — FlexCard の基本とガイド付きセットアップを学ぶための公式学習モジュール
- OmniStudio Developer Guide — FlexCard のメタデータ、データソースの設定、コンポーネントのプロパティに関する技術リファレンス
- Salesforce Industries Documentation — レイアウト、状態、アクションを扱う FlexCard の設定ガイド
リファレンスファイル一覧
| ファイル | 参照するタイミング |
|---|---|
assets/omni-ui-card.json | フェーズ 3 — 生成:DataSourceConfig JSON 構造を含む OmniUiCard レコードのテンプレート |
references/best-practices.md | フェーズ 2 — レイアウトパターン、SLDS 準拠、アクセシビリティ要件、パフォーマンスに関するガイダンス |
references/data-binding-guide.md | フェーズ 2-3 — データソースの種類、マージフィールド構文、入力パラメーターのマッピング、複数ソースの連携 |
references/scoring-rubric.md | フェーズ 3 — 7 つのスコアリングカテゴリ(130 点満点)の評価基準ごとの詳細 |
scripts/flexcard-commands.sh | フェーズ 4 — FlexCard メタデータのクエリ、取得、デプロイに使用するすべての CLI コマンド |
納品前チェックリスト
- FlexCard が依存する前に、上流の Integration Procedures が存在し、有効になっている
- オーケストレーションの順序に従っている(FlexCard がチェーンの最後)