LESSON 40分

ストーリー

佐藤CTO
要件分析が完了した。いよいよアーキテクチャ設計のフェーズだ

佐藤CTOがホワイトボードの中央に大きな四角形を描きました。

佐藤CTO
まずはC4モデルのLevel 1 — System Context Diagramから始める。NexPayのシステムが、外部の世界とどのように関わるかを鳥瞰図で描く
あなた
外部の世界…ですか?
佐藤CTO
銀行ネットワーク、カードネットワーク、証券取引所、監督官庁のシステム。フィンテックは多くの外部システムと連携する。この連携の全体像を把握しないと、信頼境界もセキュリティ設計も始まらない

C4 Level 1: System Context Diagram

NexPayのシステムコンテキスト

graph TD
    USER["エンドユーザー<br/>(1,000万人)"] -->|"HTTPS/TLS 1.3"| NEXPAY["NexPay<br/>Super App Platform<br/>(設計対象)"]
    MERCHANT["加盟店<br/>(200万店舗)<br/>POS/SDK"] --> NEXPAY
    ADMIN["加盟店管理者"] --> NEXPAY
    OPS["社内運用者<br/>(CS/運用)"] --> NEXPAY
    NEXPAY <-->|"全銀プロトコル"| BANK["銀行API<br/>(全銀ネット)"]
    NEXPAY --> CARD["カードネットワーク<br/>(VISA/MC/JCB)"]
    NEXPAY --> STOCK["証券取引所API<br/>(東証/SBI等)"]
    NEXPAY --> GOV["監督官庁<br/>報告システム<br/>(金融庁等)"]

    classDef actor fill:#3498db,stroke:#2980b9,color:#fff
    classDef system fill:#27ae60,stroke:#1e8449,color:#fff
    classDef external fill:#e67e22,stroke:#d35400,color:#fff
    class USER,MERCHANT,ADMIN,OPS actor
    class NEXPAY system
    class BANK,CARD,STOCK,GOV external

外部システム一覧

外部システム通信方式データ形式SLAセキュリティ
カードネットワークISO 8583 over TCPバイナリ99.99%HSM暗号化
全銀ネット全銀プロトコル固定長99.95%専用線
証券取引所APIREST/FIXJSON/FIX99.9%mTLS
KYC外部サービスREST APIJSON99.9%API Key + TLS
プッシュ通知FCM/APNsJSONBest EffortTLS
SMS配信REST APIJSON99.5%API Key
金融庁報告SFTP/APICSV/XML-暗号化ファイル
信用情報機関専用APIXML99.9%専用線

信頼境界の定義

// 信頼境界の定義
interface TrustBoundary {
  name: string;
  level: "HIGH" | "MEDIUM" | "LOW";
  description: string;
  controls: string[];
}

const trustBoundaries: TrustBoundary[] = [
  {
    name: "外部ユーザー境界",
    level: "LOW",
    description: "エンドユーザー・加盟店からのリクエスト",
    controls: [
      "WAF(Web Application Firewall)",
      "DDoS防御(AWS Shield)",
      "レート制限",
      "OAuth 2.0 / OpenID Connect認証",
      "入力バリデーション",
    ],
  },
  {
    name: "外部パートナー境界",
    level: "MEDIUM",
    description: "銀行API、証券API等の外部金融システム",
    controls: [
      "mTLS(相互TLS認証)",
      "IP制限(ホワイトリスト)",
      "API署名検証",
      "リクエスト/レスポンスの暗号化",
    ],
  },
  {
    name: "CDE境界",
    level: "HIGH",
    description: "カード会員データ環境の内部境界",
    controls: [
      "ネットワークセグメンテーション(専用VPC)",
      "すべての通信をmTLS",
      "アクセスログの完全記録",
      "HSMによる暗号鍵管理",
      "特権アクセス管理(PAM)",
    ],
  },
  {
    name: "内部サービス境界",
    level: "MEDIUM",
    description: "マイクロサービス間の通信",
    controls: [
      "サービスメッシュ(mTLS)",
      "JWTトークンによるサービス間認証",
      "ネットワークポリシー(K8s NetworkPolicy)",
    ],
  },
];

外部システム連携の設計パターン

Anti-Corruption Layer(防腐層)

外部システムのデータモデルやプロトコルが内部設計を汚染しないよう、防腐層を設けます。

// 外部銀行APIとの連携に防腐層を適用
// 外部の全銀プロトコルのデータ構造
interface ZenginTransferRequest {
  kinyuKikanCode: string;  // 金融機関コード(4桁)
  shitenCode: string;       // 支店コード(3桁)
  yokinShubetsu: string;    // 預金種別コード
  kozaBango: string;        // 口座番号(7桁)
  jukyuninshaName: string;  // 受取人名(カタカナ)
  kingaku: number;          // 金額
}

// 内部ドメインモデル(防腐層で変換)
interface TransferRequest {
  recipientAccount: BankAccount;
  amount: Money;
  memo?: string;
  requestedAt: Date;
}

// Anti-Corruption Layer
class BankApiAdapter implements BankTransferPort {
  async transfer(request: TransferRequest): Promise<TransferResult> {
    // 内部モデル → 外部プロトコルに変換
    const zenginRequest: ZenginTransferRequest = {
      kinyuKikanCode: request.recipientAccount.bankCode,
      shitenCode: request.recipientAccount.branchCode,
      yokinShubetsu: this.mapAccountType(request.recipientAccount.type),
      kozaBango: request.recipientAccount.number,
      jukyuninshaName: this.toKatakana(request.recipientAccount.holderName),
      kingaku: request.amount.value,
    };

    const response = await this.zenginClient.send(zenginRequest);

    // 外部レスポンス → 内部モデルに変換
    return this.mapToTransferResult(response);
  }
}

外部システム障害への対策

外部システム障害パターン対策フォールバック
カードネットワークタイムアウトサーキットブレーカー(5秒)オフライン承認(上限設定)
全銀ネットメンテナンス停止スケジュール認識 + キュー送金予約として受付、稼働時に実行
証券取引所API障害リトライ(指数バックオフ)注文をキューに保留、復旧後に執行
KYCサービスレスポンス遅延タイムアウト(30秒)手動審査フローに切り替え

「外部システムはこちらが制御できない。だからこそ、障害を前提とした設計が必要だ。サーキットブレーカー、リトライ、キューイング — これらを組み合わせて、外部障害がシステム全体に波及しないようにする」 — 佐藤CTO


コンテキストマップ(DDD)

境界づけられたコンテキスト

C4のSystem Contextに加え、DDDのコンテキストマップでドメイン間の関係を明確にします。

graph TD
    subgraph Platform["NexPay Platform"]
        PAY["Payment<br/>Context"] <-->|"SC"| ACC["Account<br/>Context"]
        ACC <-->|"SC"| TRF["Transfer<br/>Context"]
        PAY -->|"ACL"| CARD["Card Network<br/>(外部)"]
        TRF -->|"ACL"| BANK["Bank Network<br/>(外部)"]
        INV["Investment<br/>Context"] <-->|"SC"| BANK
        INV -->|"ACL"| EX["Exchange<br/>(外部)"]
        KYC["KYC/AML<br/>Context"]
    end

    NOTE["SC = Shared Kernel / Customer-Supplier<br/>ACL = Anti-Corruption Layer"]

    classDef internal fill:#3498db,stroke:#2980b9,color:#fff
    classDef external fill:#e67e22,stroke:#d35400,color:#fff
    classDef note fill:#ecf0f1,stroke:#bdc3c7,color:#2c3e50
    class PAY,ACC,TRF,INV,KYC internal
    class CARD,BANK,EX external
    class NOTE note

コンテキスト間の関係

上流コンテキスト下流コンテキスト関係パターン説明
AccountPaymentCustomer-SupplierAccountが残高情報を提供
AccountTransferCustomer-SupplierAccountが口座情報を提供
PaymentInvestmentShared Kernelポイント・残高の共有モデル
Card Network(外部)PaymentACL外部プロトコルを内部モデルに変換
Bank Network(外部)TransferACL全銀プロトコルを内部モデルに変換
Exchange(外部)InvestmentACLFIXプロトコルを内部モデルに変換
Shared Kernelの注意点

PaymentとInvestmentの間のShared Kernel(ポイントモデル)は、変更の影響が両コンテキストに及ぶため、慎重な管理が必要です。

  • Shared Kernelの変更には両チームの合意が必要
  • バージョニングとバックワードコンパティビリティを確保
  • 変更頻度が高くなる場合は、Customer-Supplierに移行を検討

まとめ

ポイント内容
System ContextC4 Level 1でシステムと外部の関係を鳥瞰
外部システムカードネットワーク、銀行API、証券APIとの連携設計
信頼境界4層の信頼境界(外部ユーザー/パートナー/CDE/内部サービス)
ACL外部プロトコルからの内部モデル保護
コンテキストマップDDDの境界づけられたコンテキストで関係を明確化

チェックリスト

  • C4 Level 1のSystem Context Diagramを理解した
  • 外部システム一覧と連携方式を把握した
  • 4層の信頼境界とそのセキュリティ制御を理解した
  • Anti-Corruption Layerの役割と適用箇所を把握した
  • DDDコンテキストマップでドメイン間の関係を理解した

次のステップへ

次は「サービス分解設計」に進みます。System Context内部をDDDに基づいて分解し、決済・送金・投資・共通基盤の各サービスの境界と責務を定義しましょう。


推定読了時間: 40分