--- sidebar_position: 1 title: "システム概要" --- # ポータルの仕組み(概要) 目的:ポータルの機能、各システムが管理するデータ、データの鮮度管理方法を説明します。 ## コアコンポーネントと責務 - Portal UI (Next.js) + BFF API (NestJS):すべてのユーザートラフィックを処理し、外部システムを呼び出します。 - Postgres:ポータルユーザーとクロスシステムマッピング `user_id ↔ whmcs_client_id ↔ sf_account_id` を保存。 - Redisキャッシュ:**グローバル**キャッシュ(商品カタログなど)と**アカウントスコープ**キャッシュ(利用資格など)の組み合わせで負荷を軽減し、顧客データの混在を防ぎます。 - WHMCS:請求の管理システム(クライアント、住所、請求書、支払い方法、サブスクリプション)。 - Salesforce:CRM(アカウント/コンタクト)、商品カタログ/価格表、注文、サポートケースの管理システム。 - Freebit:SIMプロビジョニングのみ、モバイル/SIM注文のフルフィルメント時に使用。 ## 高レベルデータフロー - **サインアップ**:ポータルがSalesforceでCustomer Numberを確認 → WHMCSクライアント(請求アカウント)を作成 → ポータルユーザー + マッピングを保存 → Salesforceをポータルステータス + WHMCS IDで更新。 - **ログイン/リンク**:既存WHMCSユーザーがWHMCS認証情報を検証。ポータルユーザーを作成し、IDをマッピングし、Salesforceアカウントをポータルアクティブとしてマーク。 - **サービス & チェックアウト**:商品/価格はSalesforceのポータル価格表から取得。利用資格はアカウントごとに確認。チェックアウト前にWHMCSの支払い方法が必要。 - **注文**:Salesforceに住所スナップショット付きで作成。Salesforce変更イベントがフルフィルメントをトリガーし、対応するWHMCS注文を作成しSalesforceステータスを更新。 - **請求**:請求書、支払い方法、サブスクリプションはWHMCSから読み取り。WHMCS内での請求書支払い用に安全なSSOリンクを生成。 - **サポート**:ケースはOrigin = "Portal Website"でSalesforceに直接作成/読み取り。 ## データ所有権チートシート - ID & セッション:Portal DB(ハッシュ化パスワード、WHMCS/SF認証情報の保存なし) - 請求プロフィール & 住所:WHMCS(権威的ソース)。ポータルが変更をWHMCSに書き戻し。 - 注文 & 注文ステータス:Salesforce(真のソース)。フルフィルメント時にWHMCSが請求/プロビジョニングコピーを受信。 - サポートケース:Salesforce(ポータルはアカウントのケースのみフィルター)。 ## キャッシュ & 鮮度(Redis) - サービスカタログ:イベント駆動(Salesforce CDC)+ 12時間の安全TTL。「volatile」データは60秒TTL。 - 注文:イベント駆動(Salesforce CDC)、TTLなし。 - 請求書:一覧90秒キャッシュ、詳細5分キャッシュ。 - サブスクリプション/サービス:一覧5分、個別10分キャッシュ。 - 支払い方法:15分キャッシュ。決済ゲートウェイ一覧:1時間キャッシュ。 - WHMCSクライアントプロフィール:30分キャッシュ。 - サポートケース:Salesforceからライブ読み取り(キャッシュなし)。 ## エラー時の動作 - 安全に失敗し明確なメッセージを表示:Customer Number不明、重複アカウント、支払い方法不足など。 - WHMCS/Salesforceが一時的に利用不可の場合、部分的なデータではなく「後でやり直してください」メッセージを表示。 - フルフィルメントがエラーコード/メッセージをSalesforceに書き戻し、チームがプロビジョニング停止の理由を確認可能。 ## パブリック vs アカウントAPIの境界 BFFは2種類のサービスカタログエンドポイントを公開: - **パブリックカタログ(パーソナライズなし)**:`GET /api/public/services/*` — Cookie/トークンを無視。パブリックキャッシュ可能。 - **アカウントカタログ(認証 + パーソナライズ)**:`GET /api/account/services/*` — 認証が必要。アカウント固有のカタログバリアント返却可能。