B2B Commerce向けスケーラブルでセキュアなSalesforce Experience Cloudサイトの設計

背景と応用シナリオ

Salesforce Architect (Salesforce アーキテクト) の視点から、今日のデジタルファーストな世界における Salesforce Experience Cloud (エクスペリエンスクラウド) の戦略的な重要性について解説します。Experience Cloud は、かつて Community Cloud と呼ばれていた製品であり、企業が顧客、パートナー、従業員と繋がるためのブランド化されたデジタルエクスペリエンスを迅速に構築するためのプラットフォームです。特に B2B (企業間取引) Commerce の領域において、Experience Cloud は単なるポータルサイトを超え、ビジネス成長を加速させるための極めて重要な戦略的基盤となります。

B2B Commerce のシナリオでは、企業は数百、数千のビジネス顧客に対して、個々に最適化された購買体験を提供する必要があります。例えば、以下のような応用シナリオが考えられます。

  • セルフサービス購買ポータル: 顧客が自社の契約価格、製品カタログ、在庫情報をリアルタイムで確認し、24時間365日いつでも注文できるポータル。過去の注文履歴の確認や再注文も容易に行えます。
  • パートナーリレーションシップ管理 (PRM): 販売代理店や再販パートナーが、リードの登録、商談の管理、マーケティング資料へのアクセス、トレーニングの受講などを一元的に行える環境を提供します。
  • サプライヤー連携ポータル: サプライヤーが納品状況の更新、請求書の提出、在庫情報の共有などをセキュアに行えるポータルを構築し、サプライチェーン全体の効率を向上させます。

これらのシナリオを成功させるためには、単に機能的なサイトを構築するだけでは不十分です。将来のユーザー数増加、データ量の増大、そしてますます巧妙化するセキュリティ脅威に対応できる、スケーラブル (拡張可能)セキュア (安全) なアーキテクチャを初期段階で設計することが不可欠です。アーキテクトとして、我々は目先の要件だけでなく、3年後、5年後のビジネスの成長を見据えた技術的判断を下す責任があります。


原理説明

スケーラブルでセキュアな Experience Cloud サイトを設計するためのアーキテクチャ上の主要な考慮事項は、主に「ライセンスモデル」「共有とセキュリティ」「パフォーマンスとスケーラビリティ」「アイデンティティと認証」の4つの柱に集約されます。

1. ライセンスモデルの選択 (License Model Selection)

Experience Cloud のアーキテクチャ設計における最初の、そして最も重要な決定事項がライセンスモデルの選択です。ライセンスは、ユーザーがアクセスできるオブジェクト、利用できる機能、そして最終的なコストに直接影響します。B2B Commerce の文脈で主に比較検討されるのは以下のライセンスです。

  • Customer Community Plus: 高度な共有設定(ロール、共有ルール)が必要で、レポートやダッシュボードへのアクセス、そして標準オブジェクトに加えてカスタムオブジェクトへのアクセスを必要とする顧客向けポータルに適しています。B2B Commerce の購買担当者など、特定のアカウントに紐づくユーザーに最適です。
  • Partner Community: Customer Community Plus の全機能に加え、リード、商談、キャンペーンといった営業関連オブジェクトへのアクセス権が付与されます。販売代理店やリセラーなど、営業活動を共同で行うパートナー向けのポータルに必須のライセンスです。
  • B2B Commerce License: B2B Commerce の機能をフル活用するために必要なライセンスです。これには、複雑な価格設定、カスタムカタログ、迅速な再注文機能などが含まれます。通常、上記の Community ライセンスと組み合わせて使用されます。

アーキテクトは、将来的なユーザーペルソナの拡大を予測し、適切なライセンスを組み合わせることで、機能要件とコストのバランスを取る必要があります。例えば、最初は購買担当者向けの Customer Community Plus で開始し、将来的にパートナーチャネルを立ち上げる際に Partner Community ライセンスを追加するといった段階的なアプローチも有効です。

2. 共有モデルとセキュリティ (Sharing Model and Security)

B2B 環境では、各企業顧客(Account)に紐づくデータ(価格表、注文履歴、サポートケースなど)を他の企業顧客から厳密に分離する必要があります。これを実現するのが Salesforce の共有モデルです。Experience Cloud のセキュリティは、この共有モデルを外部ユーザー向けに拡張したものです。

  • 共有設定 (Sharing Settings): まず、組織の共有設定(Organization-Wide Defaults)で、関連するオブジェクト(Account, Order, Case など)を「非公開(Private)」に設定することが基本です。これにより、データはデフォルトで所有者以外には見えなくなります。
  • 共有セットと共有グループ (Sharing Sets and Share Groups): Experience Cloud サイトのユーザープロファイルに対して、共有セット(Sharing Set)を作成します。共有セットは、ログインユーザーの取引先(Account)や取引先責任者(Contact)レコードに基づいて、関連するレコードへのアクセスを動的に許可する強力な仕組みです。例えば、「ユーザーの取引先に紐づく全ての注文レコードへの参照・更新アクセスを許可する」といったルールを定義できます。より複雑な共有要件には、Apex Managed Sharing を利用した共有グループ(Share Group)が有効です。
  • ロール階層 (Role Hierarchy): Community ライセンスでは、ポータルユーザーのロール数を制限できます(通常、取引先ごとに1〜3階層)。これにより、同じ取引先内のマネージャーが部下のデータ閲覧を許可する、といった階層的なアクセス制御が可能になります。
  • ゲストユーザーのセキュリティ: 認証されていないゲストユーザーがアクセスできるデータを最小限に抑えることは、セキュリティの最重要課題です。最近の Salesforce のアップデートにより、ゲストユーザーの権限は大幅に制限されています。公開したい情報(例:公開カタログ)以外は、ゲストユーザープロファイルからオブジェクト権限や項目レベルセキュリティ(Field-Level Security)を厳しく見直す必要があります。

3. パフォーマンスとスケーラビリティ (Performance and Scalability)

サイトのユーザー数が数万人規模に拡大した場合でも、快適なレスポンスタイムを維持するための設計が不可欠です。

  • コンポーネント設計: UI は Lightning Web Components (LWC) で構築することを第一に検討します。LWC はブラウザで直接実行されるモダンな JavaScript フレームワークであり、従来の Aura Components よりも優れたパフォーマンスを発揮します。コンポーネントは再利用性を考慮し、疎結合になるように設計します。
  • データアクセス戦略: 大量のデータを一度に取得する Apex コントローラーや SOQL は避けるべきです。ページネーション(Pagination)や無限スクロール(Infinite Scrolling)を実装し、ユーザーが必要とするデータのみを遅延読み込み(Lazy Loading)する設計が重要です。また、Apex クラスでは @AuraEnabled(cacheable=true) アノテーションを積極的に活用し、サーバーへのラウンドトリップを減らします。
  • CDN の活用: Experience Cloud には標準で Salesforce の CDN (コンテンツ配信ネットワーク) が組み込まれています。画像や静的リソースをキャッシュすることで、ページの読み込み速度を世界中のどこからアクセスしても向上させることができます。

4. アイデンティティと認証 (Identity and Authentication)

B2B ユーザーにとって、シームレスで安全なログイン体験は極めて重要です。Experience Cloud は多様な認証方法をサポートしています。

  • 標準ログイン: メールアドレスとパスワードによる基本的な認証方法です。
  • シングルサインオン (SSO): 多くの企業は、自社の ID プロバイダー(IdP、例: Microsoft Azure AD, Okta)を使用して従業員やパートナーの認証を管理しています。SAML や OpenID Connect を用いた SSO を設定することで、ユーザーは既存の認証情報で Experience Cloud サイトにログインでき、利便性とセキュリティが向上します。
  • セルフ登録: 新規ユーザーが自身でアカウントを登録できる機能も提供できますが、B2B の場合は承認プロセスを挟むなど、無関係なユーザーが登録できないように制御するアーキテクチャが必要です。

示例代码

B2B Commerce サイトでは、ログインしているユーザーに紐づくカート情報を表示する要件が一般的です。ここでは、ConnectApi (Connect in Apex とも呼ばれる) を使用して、現在の有効なカートの概要を取得する Apex メソッドの例を示します。ConnectApi は、Experience Cloud のデータにプログラムでアクセスするための標準的な方法であり、共有ルールや権限を自動的に考慮してくれるため、セキュリティ上非常に安全です。

このコードは、LWC から呼び出されることを想定しており、現在のユーザーの有効なカートIDと合計金額を取得します。

/**
 * B2B Commerce のカート情報を取得するための Apex クラス
 */
public with sharing class B2BCartController {

    /**
     * @description LWCから呼び出されるメソッド。現在のコンテキストユーザーの有効なカート情報を取得する。
     * @return Map<String, Object> カート情報を含むマップ。成功時はカートIDと合計金額、失敗時はエラー情報を含む。
     */
    @AuraEnabled(cacheable=true)
    public static Map<String, Object> getCartSummary() {
        // 結果を格納するための Map を初期化
        Map<String, Object> result = new Map<String, Object>();
        // Experience Cloud サイトの ID を取得。ここでは WebStoreId を静的に取得するか、動的に渡す必要がある。
        // 実際のプロジェクトでは、カスタムメタデータやカスタム設定から取得することが推奨される。
        String webstoreId = B2BUtils.getWebstoreId();

        try {
            // ConnectApi.CommerceCart.getCartSummary を呼び出し、現在のユーザーの有効なカート概要を取得
            // このメソッドは、現在のユーザーセッションに基づいて自動的にカートを特定し、
            // 設定されている共有ルールや権限を遵守する。
            ConnectApi.CartSummary cartSummary = ConnectApi.CommerceCart.getCartSummary(webstoreId);

            // 取得したカート情報を Map に格納
            result.put('success', true);
            result.put('cartId', cartSummary.cartId);
            result.put('totalAmount', cartSummary.grandTotalAmount);
            
        } catch (ConnectApi.ConnectApiException e) {
            // ConnectApi の呼び出しで例外が発生した場合の処理
            System.debug('Error getting cart summary: ' + e.getMessage());
            result.put('success', false);
            result.put('error', e.getMessage());
        }

        return result;
    }

    // 補助的なメソッド(実際のプロジェクトではユーティリティクラスに配置)
    private class B2BUtils {
        public static String getWebstoreId() {
            // 本番環境では、動的に WebStoreId を特定するロジックを実装する
            // 例: `SELECT Id FROM WebStore WHERE Name = 'Your_Store_Name' LIMIT 1`
            // ここではドキュメント用のプレースホルダーを返す
            WebStore store = [SELECT Id FROM WebStore LIMIT 1];
            if (store != null) {
                return store.Id;
            }
            // ⚠️ 未找到官方文档支持 (WebStoreId を動的に取得するためのベストプラクティスに関する直接的なサンプルコードは見つかりませんでした。通常は組織に1つ、または識別可能な命名規則に基づきクエリで取得します。)
            return null;
        }
    }
}

コードの解説:

  • with sharing: クラス宣言に with sharing を指定することで、このクラスが実行される際に Salesforce の共有ルールが適用されることを強制します。これにより、ユーザーは自身がアクセス権を持つデータしか操作できなくなります。
  • @AuraEnabled(cacheable=true): このアノテーションにより、メソッドは LWC から呼び出し可能になり、かつクライアント側で結果がキャッシュされます。これにより、同じパラメータでの再呼び出し時にサーバーへのリクエストが発生せず、パフォーマンスが向上します。
  • - ConnectApi.CommerceCart.getCartSummary(webstoreId): これが中心となるメソッドです。B2B Commerce の現在のストア(webstoreId)における、現在のユーザーの有効なカート情報を取得します。API の内部で現在のユーザーコンテキストが自動的に認識されるため、開発者がユーザーIDを渡す必要はありません。

注意事項

Experience Cloud のアーキテクチャを設計・実装する際には、以下の点に特に注意が必要です。

  • 権限とプロファイル (Permissions and Profiles): 最小権限の原則(Principle of Least Privilege)を徹底してください。外部ユーザーに割り当てるプロファイルは、必要最低限のオブジェクト権限、項目レベルセキュリティ、Apex クラスアクセス権のみを持つようにクローンしてカスタマイズします。定期的な権限レビューを計画に含めることが重要です。
  • ガバナ制限 (Governor Limits): Experience Cloud サイトも Salesforce Platform 上で動作するため、SOQL クエリの発行回数、CPU 時間などのガバナ制限に従います。特に、多数のユーザーが同時にアクセスする B2B サイトでは、非効率な Apex コードが原因で制限に達しやすくなります。コードのバルク化(Bulkification)を徹底し、負荷テストを実施することが不可欠です。
  • API 制限 (API Limits): サイト内のコンポーネントが多くの Apex 呼び出しを行う場合や、外部システムとの連携が多い場合、組織全体のAPIコール制限に影響を与える可能性があります。Platform Events などの非同期処理パターンを検討し、リアルタイムでの同期的なAPIコールを最小限に抑える設計を心がけてください。
  • エラー処理 (Error Handling): カスタムコンポーネント内で発生したエラーは、ユーザーに分かりやすく表示する必要があります。try-catch ブロックで例外を適切に補足し、「予期せぬエラーが発生しました。管理者にお問い合わせください。」といった曖昧なメッセージではなく、ユーザーが次にとるべきアクションを示唆するような、具体的なフィードバックを提供することが望ましいです。

まとめとベストプラクティス

成功する B2B Commerce 向け Experience Cloud サイトは、優れた機能性だけでなく、それを支える堅牢なアーキテクチャに基づいています。Salesforce Architect として、我々は以下のベストプラクティスを遵守すべきです。

  1. セキュリティファーストのアプローチ: 設計の初期段階からセキュリティを最優先事項として組み込みます。データ共有モデル、プロファイル権限、ゲストユーザーのアクセス制御を厳密に定義します。
  2. 適切なライセンスの早期選定: ビジネス要件と将来の成長予測に基づき、最適なライセンスモデルを選択します。この決定は、後の拡張性やコストに大きな影響を与えます。
  3. パフォーマンスを意識した設計: 大規模なユーザーベースを想定し、コンポーネントの設計、データアクセスパターン、キャッシュ戦略を最適化します。LWC の採用と @AuraEnabled(cacheable=true) の活用は基本です。
  4. 標準機能を最大限に活用: カスタムコードを記述する前に、Experience Builder の標準コンポーネント、Flow、Connect API など、Salesforce が提供する標準機能で要件を満たせないか常に検討します。これにより、開発・保守コストを削減し、プラットフォームのバージョンアップにも追従しやすくなります。
  5. アイデンティティ管理の戦略的計画: ユーザーにとってシンプルでセキュアな認証体験を設計します。SSO の導入は、特に企業顧客を相手にする B2B シナリオにおいて、ユーザー満足度とセキュリティを両立させるための鍵となります。

これらのアーキテクチャ原則に従うことで、単なるウェブサイトではなく、ビジネスの成長を牽引し、顧客とのエンゲージメントを深化させる強力なデジタルプラットフォームとしての Experience Cloud を構築することが可能になります。

コメント