AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

Mandate Ledger for Trusted Agentic Commerce on MongoDB

MongoDB Atlas で不可変の Mandate Ledger をビルドして、エージェントの商取引のトラストレイヤーを作成し、説明責任を保証する方法を学びます。

ユースケース: 人工知能決済

業種: 小売

製品: MongoDB Atlas

パートナー: Google Cloud

AI エージェントは、製品の検索から最終的なチェックアウトまでのタスクを自律的に管理することで、デジタルコマースを変革します。しかし、AI エージェントがカスタマーに代わって支払いを開始すると、従来のコマースの核心的な前提が崩れ、信頼の危機が生じます。

既存の支払いシステムでは、エージェントの権限を確認したり、カスタマーの本当の意図を認証したり、明確なトランザクションの説明責任を定義したりすることはできません。これにより、次のような重要な挑戦が生じます。

  • 承認: カスタマーが特定の購入に対してエージェントを承認したことを確認します。

  • 信頼性: エージェントのリクエストが、エラーやハルシネーションなどなく、カスタマーの真の意図を正確に反映していることを確認します。

  • 責任: トランザクションが失敗した場合の責任者を判定します。カスタマー、エージェントの開発者、マーチャント、または発行者のいずれか。

これらの挑戦に対処するには、カスタマー、販売業者、金融機関を含むすべての参加者が信頼できる共通の標準が必要となります。

Google の エージェント支払いプロトコル (AP2) は、オープンでセキュアで相互運用可能なプロトコルを提供します。これにより、マーチャント、金融機関、および一般のカスタマーのための信頼できるエコシステムがビルドされます。

トラストレイヤー

図 1トラストレイヤー

AP2 は、エージェントが作成して交換する改ざん防止の暗号化された JSON ペイロードである検証可能なデジタル認証情報 (VDC) を使用してトランザクションのセキュリティを確保します。AP2 は、これらの VDC を 3 つのコアマンデートに分類します。

  • 意図の委任: カスタマーが必要とするものを概要し、AIエージェントがカスタマーに代わって購入できる条件を定義します。

  • カートの委任: マーチャントとカスタマーの両方が署名したデジタル受領書を提供し、実在する人間による購入を認可します。

  • 支払いマンデート: 支払いネットワークと直接共有される可視化レイヤーを作成し、AI エージェントの関与を安全に通知します。

VDC は恒久的なデジタル契約として機能します。エージェントは、カスタマーの意図を捕捉するために、これらのペイロードを暗号化して署名します。このプロセスにより、ショッピング体験のすべてのステップについて否認不可能な監査記録が作成されます。

あらゆる手順で検証可能な証明を伴う契約上の会話

図 2あらゆる手順で検証可能な証明を伴う契約上の会話

ユーザー インターフェースでのインテントの可視化。各インテントが会話内でどのように表現されるかを示します

図 3ユーザーインターフェースでのインテントの可視化。各インテントが会話内でどのように表示されるかを示しています。

これらの暗号化VDCの信頼性を維持するには、システムでこれらをセキュアで検証可能な環境に保存する必要があります。Mandate Ledger Serviceは、AIエージェントとデータベースの間の保護ミッドルウェアとして機能します。このミッドルウェアの裏にはMongoDB Atlasがあります。

Atlas は、改ざんのない監査記録をサポートするように設計されたエンタープライズグレードのセキュリティを提供します。このアーキテクチャをビルドして、安全なエージェント商取引を増やすのに必要な不変のトラストレイヤーである Mandate Ledger Service を作成します。

AI アシスタントに新しいスマートフォンの購入を依頼するカスタマーを想像してください。ショッピング エージェントは、完璧な取引を見つけるために、販売業者と自律的に交渉します。Mandate Ledger Service は、すべてのリクエスト、承認、お支払いステップを暗号化された JSON マンデートにパッケージすることで、この全体の流れをレコードします。MongoDB Atlas は、各マンデートを不可変のドキュメントとして保存します。このプロセスにより、単純なチャットが永久的で否認不可能な意図の証明に変換されます。

このソリューションでは、AP2 プロトコルを使用するアーキテクチャの上に Mandate Ledger Service をビルドする方法を示します。

AP2 は、セキュリティと明確なトランザクションの責任を提供するように設計されたロールベースのアーキテクチャを使用します。このエコシステムの各アクターは、統合を簡素化し、カスタマーのプライバシーを保護するために、個別の責任を負っています。

MongoDB Mandate Ledger Service アーキテクチャ

図 4MongoDB Mandate Ledger Service アーキテクチャ

このアーキテクチャで定義されている主要なロールを検討します。

  • カスタマー: ショッピングエージェントと直接交流し、製品の検索と購入リクエストを開始します。

  • ショッピングエージェント:カスタマーと直接交流して製品を検索し、カートの交渉を行い、委任に署名します。

  • マーチャントエージェント: 販売者を代表して在庫を表示し、提案を交渉し、注文の実行を保証するための委任を結びます。

  • 認証情報プロバイダー: カスタマーの支払い方法を安全に管理し、トランザクションに適切な支払いトークンを選択します。

  • マーチャント支払いプロセッサー: トランザクション承認メッセージを構築し、支払いネットワークと発行者に直接ルーティングします。

  • 監査エージェント: トランザクション後の不可変の監査記録を検査し、読み取り専用アクセスを使用して支払いと署名を確認します。

  • マンデートレジャーサービス: AI エージェントと MongoDB Atlas の間の保護ミッドルウェアとして機能し、暗号化された署名のマンデートを JSON ドキュメントとしてネイティブに保存します。MongoDB Atlas は中央の不可変の台帳として機能します。

このソリューションでは、エージェントが Agent-to-Agent (A2A) プロトコル を使用して通信するマルチエージェントアーキテクチャが使用されています。AP2 は、トランザクションを実行するために ユニバーサル Commerce プロトコル (UCP) もサポートしています。

Mandate Ledger Service は、マーチャントエージェントをデータベースに接続する保護ミッドルウェアとして機能します。FastAPI または gRPC を使用してこのサービスをビルドします。

Mandate Ledger Service の詳細アーキテクチャ

図 5Mandate Ledger Service の詳細アーキテクチャ

3 つの個別のセキュアなレイヤーを介して、すべてのエージェント リクエストを処理します。

  • 認証レイヤー: API キーを検証してエージェントを安全に識別します。エージェントの種類に応じてロールベースのアクセス制御 (RBAC) を適用し、エージェントの厳密な許可を強制します。

  • ビジネスロジックレイヤー: コアリクエスト検証と同時実行制御を実行します。安全なネットワーク再試行のために共存性を強制し、厳格な命令の不変性をサポートします。

  • データアクセスレイヤー:MongoDB クライアントと最適化されたインデックスの作成を使用してデータベース操作を実行します。このレイヤーは、_id フィールドを不可変として定義します。また、スキーマ検証により、すべての更新および削除操作をブロックします。

すべての AP2 トランザクションは、暗号署名されたマンデートの構造化されたシーケンスを通じて進行します。各ステップでは MongoDB Atlas に不可変レコードが生成され、これにより、意図から支払いまでの完全な監査記録が作成されます。

データフロー

図6。データフロー

トランザクションを意図から支払いに移行するには、AP2 エージェントが次のトランザクションシーケンスを完了します。

  1. カスタマーの意図を捕捉します。Shopping エージェント は、カスタマーのリクエスト(たとえば、「ランニングシューズ」の自然言語での説明など)を構造化された Intent Mandate に翻訳します。Intent Mandate には、ターゲットの販売業者、返金要件、カート確認設定、および有効期限ウィンドウが記載されています。Shopping エージェント は、カスタマーに代わって EdDSA を使用して委任状に署名し、ステータスを signed、コンテンツをロックするバージョンハッシュとともに販売業者エージェントに送信します。

  2. インテント マンデートを保存します。マーチャント エージェントは、マンデート レッジャー サービスを介してインテント マンデートを Atlas に書き込み (write)ます。レッジャー サービスは、リクエストを検証し、RBAC を適用し、レコードを不可変に追加します。

  3. カートの委任を作成します。マーチャント エージェントは、商品名、価格、通貨、受け入れ可能な支払い方法、有効期限などの完全な商品詳細を含むカート オファーを作成します。マーチャント エージェントは、その後、レコードの整合性を確保するために、レコードに proposed のステータスとバージョン ハッシュが付与される Mandate Ledger Service を通じて Atlas に保存します。

  4. カスタマーにカートを提供します。マーチャント エージェントは提案されたカート マンデートをショッピング エージェントに返します。ショッピング エージェントは、利用可能な製品オプションをカスタマーに提示します。

  5. カート マンデートを承認します。カスタマーはオプションを選択します。ショッピング エージェントは、ハードウェアによってバックアップされたデバイス キーを使用してカスタマーに代わってカート マンデートに連署し、承認されたマンデートを販売業者 エージェントに送り返します。

  6. カートマンデートに連署し、最終処理を行います。マーチャント エージェントは、受け入れられたカートに暗号化シグネチャを追加し、完全に両方が署名したカートマンデートを Atlas に保存し、合意した期間を signed ステータスでロックします。

  7. 支払い委任を作成します。ショッピング エージェントは、該当な支払いトークンを検索するために、認証情報プロバイダーにクエリを実行します。ショッピング エージェントは、その後、カスタマーに代わって支払い委任を作成して署名し、マーチャント エージェントに送信します。認証情報プロバイダーは、クレジットカードの完全な番号を返すことはありません。これにより、ショッピング エージェントが生データにアクセスすることはありません。

  8. 支払い委任を保存する。マーチャント エージェントは、署名された支払い委任を委任公開台帳サービスを介して Atlas に書き込み (write)ます。公開台帳サービスは、AI エージェントの関与をフラグするため、この委任を金融機関と直接共有します。また、支払いプロセッサーはこの委任を使用して、支払いネットワークへの承認をルーティングします。

エージェントは既存のレコードを変更または削除できません。MongoDB Atlas は追加のみの書き込み (write)を強制するため、インテント、カート、支払いの完全なマンデート チェーンはそのまま維持され、いつでも監査エージェントによって独立して検証できます。

5 つのコア コレクションを使用して MongoDB データベースを構築し、eコマースを増やすことをサポートします。

  • mandate_ledger: 委任状の不可変バージョンを安全に保存します。

  • payments: 超スリムな支払い完了レコードを保存します。

  • api_keys: API キーを管理してエージェントを安全に識別します。

  • audit_log: 完全な操作監査記録を維持します。

  • idempotency_records: 操作の重複を防止するためにリクエスト データをキャッシュします。

mandate_ledger コレクションには、3 つの委任タイプがすべて 1 つのコレクションに保存されます。entity_type フィールドを使用してクエリ時に区別することで、委任タイプごとのジョインや分離されたコレクションの必要がなくなります。

すべてのドキュメントは共通のエンベロープ構造を共有します。

{
"entity_id": "IntentMandate_955181ea-11c3-4379-92c4-3e27c5f278d3",
"entity_type": "IntentMandate",
"version": 1,
"status": "signed",
"transaction_id": "txn_fca7db66-c769-4206-b891-7140af37f8f4",
"user_id": "hunter-d53910cf-b9e2-4876-8668-8251c990e203",
"created_by_agent": "merchant_agent_dev",
"created_by_agent_type": "merchant-agent",
"current_version_hash": "4a822a01468a27dfd...",
"signatures": [...],
"mandate_data": { ... }
}

mandate_data フィールドにはタイプ固有のペイロードが含まれ、各マンデートタイプには異なるデータ構造が保存されます。

IntentMandate ドキュメントには、構造化されたデータとしてカスタマーの購入意図が記述されています。このデータには、自然言語の説明、対象となる販売業者、特定の SKU、払い戻し要件、有効期限ウィンドウが含まれます。

IntentMandate document
"mandate_data": {
"natural_language_description": "cheapest french press coffee maker",
"merchants": [],
"skus": [],
"requires_refundability": true,
"user_cart_confirmation_required": true,
"intent_expiry": "2026-04-18T20:00:03.651746+00:00"
}

ショッピング エージェントは、EdDSA を使用してこのドキュメントに署名します、その後マーチャント エージェントに送信します。ドキュメントはレッジャーに入ります。"status": "signed" ペイロードと current_version_hash 値を使用して、そのコンテンツをロックします。

CartMandate ドキュメントには、価格と通貨を含む品目、配送コスト、税金、受け入れ可能な支払方法、およびカートの有効期限ウィンドウを含む完全な商業供給が記載されています。

CartMandate ドキュメント
"mandate_data": {
"contents": {
"payment_request": {
"method_data": [{ "supported_methods": "CARD", "data": { "network": ["mastercard", "paypal", "amex"] }}],
"details": {
"display_items": [
{ "label": "Standard Laptop", "amount": { "currency": "USD", "value": 1203.50 }, "refund_period": 30 },
{ "label": "Shipping", "amount": { "currency": "USD", "value": 2.00 }},
{ "label": "Tax", "amount": { "currency": "USD", "value": 1.50 }}
],
"total": { "label": "Total", "amount": { "currency": "USD", "value": 1203.50 }}
}
},
"shipping_address": { "recipient": "Bugs Bunny", "address_line": ["123 Main St"], "city": "Sample City", "country": "US" },
"cart_expiry": "2026-04-17T20:29:05.197984+00:00"
},
"merchant_authorization": "eyJhbGciOiJSUzI1NiIs..."
}

このドキュメントは、"status": "proposed" の指定で公開台帳に登録されます。カスタマーがオファーを承諾すると、ショッピングエージェントが共同で署名します。その後、販売業者エージェントは、同じ transaction_id、増分された version"status": "signed" フィールドを持つ、公開台帳に新しいドキュメントを書き込み (write)ます。両方の署名を配列に含めることで、合意された期間が双方に綁束力を持つようになります。

"signatures": [
{ "signer_type": "shopping-agent", "algorithm": "EdDSA", "signed_at": "2026-04-17T19:59:49Z" },
{ "signer_type": "merchant-agent", "algorithm": "JWT", "signed_at": "2026-04-17T19:59:50Z" }
]

PaymentMandate ドキュメントは、合意したカートを認証情報プロバイダーから検索した特定の支払いトークンにバインドし、支払者の配送先と問い合わせの詳細を含みます。

PaymentMandate ドキュメント
"mandate_data": {
"payment_mandate_contents": {
"payment_details_total": { "label": "Total", "amount": { "currency": "USD", "value": 1203.50 }},
"payment_response": {
"method_name": "CARD",
"details": { "token": { "value": "fake_payment_credential_token_5" }},
"shipping_address": { "recipient": "Bugs Bunny", "address_line": ["123 Main St"], "city": "Sample City" },
"payer_email": "bugsbunny@gmail.com"
},
"merchant_agent": "Generic Merchant",
"timestamp": "2026-04-17T20:00:22.603453+00:00"
},
"user_authorization": "fake_cart_mandate_hash_cart_fb1b4c86..._fake_payment_mandate_hash_812843b2..."
}

user_authorization ハッシュは、この PaymentMandate を受け入れられた CartMandate に暗号化してリンクし、これによって支払いトークンが別のトランザクションに対して再生されるのを防止します。

transaction_idフィールドとentity_typeフィールドにインデックスを作成して、1つのクエリですべてのトランザクションの完全なマンデートチェーンを検索します。

payments コレクションには、完了したトランザクションごとに 1 つのドキュメントが保存されます。このコレクションには、拡張参照パスワードなしが適用されます。

各ドキュメントには、全体の委任内容を埋め込むのではなく、3 つの委任の各々の委任 ID と承認書名のみが保存されます。このデザインにより、支払いレコードは小さくて読み取りが速くなります。また、完全な監査トレースが必要な場合は、mandate_ledger コレクションの完全なデータへの直接ポインタが保持されます。

{
"payment_id": "pay_123c25ac-7b56-4e45-8dd1-30cdcda944c7",
"transaction_id": "txn_6fbab918-2b5d-4ddd-89d8-fdb96e5648d9",
"user_id": "hunter-263b752e-92be-4001-ab9d-38847811c663",
"intent_mandate": { "mandate_id": "IntentMandate_41bbeacf-...", "signature": "0x_shopping_agent_sig_...", "timestamp": "2026-04-15T19:50:57Z" },
"cart_mandate": { "mandate_id": "CartMandate_c0e8f369-...", "signature": "eyJhbGciOiJSUzI1NiIs...", "timestamp": "2026-04-15T19:52:07Z" },
"payment_mandate": { "mandate_id": "PaymentMandate_33c39b8c-...", "signature": "fake_cart_mandate_hash_...", "timestamp": "2026-04-15T19:53:53Z" },
"amount": 28,
"currency": "USD",
"status": "SUCCESS",
"payment_method_type": "CARD",
"merchant_agent": "merchant_agent_dev",
"payment_processor_agent": "payment_processor",
"processed_at": "2026-04-15T19:54:14Z"
}

この設計では、ドキュメントを意図的に小さく保ちます。完全な期間、明細項目、および暗号化証明は、 mandate_ledgerコレクションに存在します。支払いレコードは、トランザクションが完了したことを確認するためだけに存在し、完全な監査するチェーンを再構築するために必要な 3 つのポインターを提供します。完全なトレースが必要な場合は、 transaction_idフィールドを使用して両方のコレクションを結合します。

api_keys コレクションは、API キーを管理してエージェントを安全に識別します。このコレクションを使用して、サービスを呼び出す各エージェントに関連付けられたキーを保存します。

audit_log コレクションには、コンプライアンスとデバッグのためのすべての API 操作が保存されます。このコレクションを使用して、委任の作成、アクセスの試行、検証結果などのサービスレベル イベントをレコードします。このアプローチにより、不可変の委任台帳自体が拡張されることを防止できます。TTL インデックスを追加して、90 日後にレコードを自動的に削除します。これにより、コレクションの範囲を維持しながら、有用な操作記録を保存できます。

コレクションには、次の主要フィールドが含まれています。

  • event_type: mandate.created などの操作タイプを識別します。

  • entity_id: 関連する委任を参照します。

  • actor_agent_id: アクションを実行したエージェントをキャプチャします。

  • event_timestamp: イベントが発生した時間を記録し、TTL ポリシーをサポートします。

  • expires_at: MongoDB がレコードを自動的に削除するタイミングを定義します。

idempotency_records コレクションには、重複操作を防止するためのアイデンポテンシーキーが保存されます。このコレクションを使用して、クライアントから提供されたキー、リクエストを行ったエージェント、およびその操作で作成された入出金管理台帳エントリを保持します。TTL インデックスを追加して、24 時間後にレコードを自動的に削除します。

コレクションには、次の主要フィールドが含まれています。

  • idempotency_key: クライアントから提供された一意のキーを保存し、インデックスを必要とします。

  • agent_id: リクエストを行ったエージェントを識別します。

  • ledger_entry_id: 元のリクエストのために作成されたマンデートを参照します。

  • expires_at: MongoDB がレコードを自動的に削除するタイミングを定義します。

開始する前に、次のものがインストールされて構成されていることを確認してください。

  • MongoDB Atlas または自己管理型 MongoDB 7.0 以降

  • Python 3.13 (バージョン 3.13.x)

  • 依存関係マネジメントのuv

  • Google API キーまたは Vertex AI へのアクセス

  • Dockerを使用してサービスをコンテナとして実行する

  • Node.js と npm (フロントエンド アプリケーション用)

1
  1. リポジトリ をクローンし、Mandate Ledger Service をインストールします。

    git clone https://github.com/mongodb-industry-solutions/retail-agent-shopping-ap2-ucp.git
    cd retail-agent-shopping-ap2-ucp/mandate_ledger_service
    python3.13 -m venv .venv
    source .venv/bin/activate
    pip install -e .
  2. mandate_ledger_service/ディレクトリに.envファイルを作成します。

    MONGODB_URI= # Your connection string
    MONGODB_DATABASE=mandate_ledger
    SERVICE_NAME=mandate-ledger-service
    ENVIRONMENT=development
    # Bootstrap Auth (dev only — set to false after Step 2)
    BOOTSTRAP_ADMIN_KEY=**** # Generate: openssl rand -hex 32
    ENABLE_BOOTSTRAP_AUTH=true
    ALLOWED_CORS_ORIGINS=*
    DEFAULT_RATE_LIMIT_PER_MINUTE=60
  3. サービスを開始します。

    uvicorn src.main:app --reload --port 5000
  4. サービスを Docker で実行する場合:

    docker build -t mandate-ledger .
    docker run --rm \
    -p 5000:5000 \
    --env-file .env \
    mandate-ledger
2
  1. 新しいターミナルを開き、次のコマンドを実行します。

    cd mandate_ledger_service
    source .venv/bin/activate
    PYTHONPATH=. python3 scripts/setup_agent_keys.py
  2. 出力から Merchant エージェント API キー をコピーします。ENABLE_BOOTSTRAP_AUTH=false.env ファイルに設定し、サービスを再起動します。

製品の注意事項: Google Secret Manager や Amazon Web Services Secrets Manager などのシークレット マネージャーを使用し、キーローテーションを実装します。

3

/backend サービスは、Mandate Ledger Service と交流し、新しい委任を公開台帳にプッシュします。このサービスは、AP2 + A2A サンプルを使用して、Googleの AP2 リポジトリ から適応されています。

  1. /backend.env ファイルを作成します。ステップ 2 で生成された mlsk_merchant_key 値に MANDATE_LEDGER_API_KEY を設定します。

    GOOGLE_API_KEY=
    MANDATE_LEDGER_SERVICE_URL=http://localhost:5000
    MANDATE_LEDGER_API_KEY=
  2. Vertex AI の場合は、最初の行を次のように置き換えます。

    GOOGLE_GENAI_USE_VERTEXAI=true
    GOOGLE_CLOUD_PROJECT=your-project-id
    GOOGLE_CLOUD_LOCATION=us-central1
  3. バックエンド コンテナをビルドして実行します:

    docker build -f backend/Dockerfile -t retail-backend ./backend
    docker run --rm \
    -p 8000:8000 \
    -p 8001:8001 \
    -p 8002:8002 \
    -p 8003:8003 \
    -p 8004:8004 \
    --env-file backend/.env \
    retail-backend
  4. バックエンド API は http://localhost:8000 で起動し、次の AP2 エージェントを自動的に起動します。

    エージェント
    ポート

    ショッピングエージェント (メインバックエンドに統合)

    8000

    マーチャント エージェント

    8001

    認証情報プロバイダー エージェント

    8002

    マーチャント支払いプロセッサー エージェント

    8003

    Auditor エージェント

    8004

4

フロントエンドは、/backend サービスと交流する Next.js アプリケーションです。

  1. 例の .env ファイルをコピーし、バックエンドとアシスタントのエンドポイントとなる接続されたデバイスを設定します。

    cd frontend
    cp EXAMPLE.env .env.local
  2. frontend/.env.local を値で更新します。

    MONGODB_URI=<your-mongodb-string>
    MONGODB_DATABASE=<your-database-name>
    NEXT_PUBLIC_BACKEND_ENDPOINT=http://localhost:8000
    ASSISTANT_ENDPOINT=http://localhost:3333
  3. 依存関係をインストールし、フロントエンドを実行します。

    npm install
    npm run dev
  4. フロントエンドをコンテナとして実行するには、ルート Dockerfile を使用します。

チャット UI で提案された返信を有効にする

チャットインターフェースは、外部アシスタントマイクロサービスを通じて提案された返信を生成します。この機能を有効にするには、デモを開始する前に、アシスタントマイクロサービスを設定して実行してください。このサービスがない場合、アプリは読み込まれますが、提案された返信は生成されません。

5
  1. 3 つのサービスを別々のターミナルで起動し、http://localhost:8080 でアプリを開きます。

  2. バックエンド API は、以下の場所で引き続き利用できます。 http://localhost:8000.

  3. アプリケーションの操作に関する詳細な手順については、ユーザー ガイドを参照してください。

エージェントによる商取引で信頼を確立する。AI トランザクションをカスタマーの意図の確定的で否認不可能な証明に固定することで、信頼の危機を克服する:

  • トランザクションの不可変性を確保します:Mandate Ledger Service で追加のみのルールを強制して、改ざんのない監査する記録を作成します。

  • 暗号化された署名を保持する: MongoDB document modelを使用して、エージェントが生成したとおり、深くネストされた JSON マンデートをネイティブに保存します。

  • エージェントのアクセスを制御する: ロールベースのアクセス制御を実行し、AI エージェントが特定のロールに基づいてのみ正規のアクションを実行するようにします。

  • 重複請求の防止:サービスレイヤーで共存キーを強制して、カスタマーに重複請求することなくネットワーク再試行を安全に取り扱います。

  • Angelica Guemes, MongoDB

  • Florencia Arin, MongoDB

  • Sakshi Garg、MongoDB

  • Genevive Broadhead, MongoDB

  • Antonio Membrides, MongoDB

  • MongoDB、 MongoDB