📞 はじめに
企業のカスタマーサポートや営業活動において、通話やメッセージの履歴データ(CDR: Call Detail Records)の分析は不可欠です。
本記事では、Vonage Reports APIからVoice(音声)、Messages(メッセージ)、Video(ビデオ)のCDRデータを取得し、日・週・月単位で集計・グラフ化するフルスタックWebアプリケーション「Report CDR Analysis Demo」のアーキテクチャと実装のポイントを紹介します。
👉 ソースコード: masayukimiyazawa/report-api-cdr-analysis-demo
🚀 アプリケーションの概要と主要機能
このアプリケーションは、外部APIからデータを取得し、データベースに保存・集計してダッシュボードに表示する一連のデータパイプラインを実装したデモアプリです。
-
マルチプロダクト対応: Voice (
VOICE-CALL)、Messages (MESSAGES)、Video (VIDEO-API) のデータ取得。 - 柔軟な集計機能: 取得したデータを「日(Day)」「週(Week - ISO基準)」「月(Month)」単位で動的に集計。
- リッチな可視化: KPIサマリーカード、積み上げ棒グラフ、ステータス円グラフ、トレンド折れ線グラフなどを備えたレスポンシブなダッシュボード。
- 方向別・ステータス別分析: 通話の方向(Inbound/Outbound)や詳細なステータス(成功、失敗など)によるドリルダウン。
- データ管理とエクスポート: 絞り込んだデータのCSV/JSONダウンロード、およびデータ保持期間に基づくクリーンアップ(メンテナンス機能)。
-
🌟 モックモード搭載: Vonageの認証情報やDBがなくても、環境変数
USE_MOCK=1だけで決定論的なサンプルデータを用いて全UIの動作確認が可能。
🛠 技術スタック
モダンなTypeScriptベースのフルスタック構成を採用しています。
| レイヤ | 技術 | 役割 |
|---|---|---|
| フロントエンド | React, Vite, Tailwind CSS, Recharts | 高速なビルドとスタイリング、軽量で柔軟なグラフ描画 |
| バックエンド | Node.js, Express, TypeScript | 型安全なREST APIサーバーと外部API連携ロジック |
| データベース | MongoDB Atlas (Mongoose) | 大量データの永続化と、強力なAggregation Pipeline |
🏗 詳細アーキテクチャ
本アプリケーションは、クライアント(フロントエンド)とサーバー(バックエンド)が完全に分離されたアーキテクチャを採用しています。
システム構成・データフロー
ディレクトリ設計(関心の分離)
バックエンド(/server)は、保守性とテスト容易性を高めるため、役割ごとにディレクトリが明確に分割されています。
-
src/routes/: エンドポイントの定義(/api/stats,/api/report/pullなど) -
src/services/: ビジネスロジック。Vonage APIとの通信や、モックデータの生成をカプセル化。 -
src/repositories/: データアクセスの抽象化。MongoDBへの読み書きと、モック時のインメモリ処理を切り替える役割を担う。 -
src/utils/: 日・週・月ごとのタイムバケット(期間集計)を計算する共通ロジック。
✨ 実装の特長・工夫したポイント
1. MongoDBのAggregation Pipelineを活用した高速な集計
フロントエンドから「月ごとの集計」などのリクエストがあった際、大量のレコードをNode.js側でループ処理するのではなく、MongoDBのAggregation機能を利用してデータベース側で計算を完結させています。
これにより、サーバーのメモリ消費を抑え、高速なレスポンス(/api/stats)を実現しています。
2. 環境に依存しない「モックモード」の設計
開発やデモを容易にするため、USE_MOCK=1 を指定すると、以下の挙動に切り替わります。
- 外部APIへの通信をバイパスし、内部のジェネレーターが本物そっくりのCDRを生成する。
- データベース(MongoDB)接続をスキップし、リポジトリ層がインメモリストレージに切り替わる。
- 集計処理も、DBのAggregationと同等の結果を返すJavaScriptのロジックに透過的に切り替わる。
これにより、フロントエンド開発者はAPIキーやDB環境のセットアップなしにUI開発に専念できます。
3. 同期APIとページネーションの制御
Vonage Reports APIからデータを取得する POST /api/report/pull エンドポイントでは、同期API(最大1000件/ページ)を利用しています。データが複数ページにまたがる場合、バックエンド側でカーソル(Next Page)を追従し、全ての期間データを取得・保存する確実なフェッチ機構を備えています。
📝 API仕様(バックエンド設計)
フロントエンドと疎結合を保つため、シンプルなRESTful APIを提供しています。
| HTTPメソッド | エンドポイント | 概要 |
|---|---|---|
POST |
/api/report/pull |
指定期間・プロダクトのCDRをVonageから取得しDBへ保存 |
GET |
/api/stats |
グラフ描画用集計データ(granularity=day/week/month) |
GET |
/api/stats/summary |
ダッシュボード上部の全体KPIサマリー |
GET |
/api/products |
対応プロダクト一覧とデータ保持期間ルールの取得 |
まとめ
本プロジェクトは、外部APIからのデータ取得、DBでの効率的なデータ集計、Reactによるリッチなダッシュボード構築という、データ連携アプリケーションのベストプラクティスのデモアプリです。
サービス層やリポジトリ層を分離した設計や、モックモードの導入などは、実際のプロダクト開発でもそのまま活かせるアーキテクチャとなっています。ぜひリポジトリをクローンして、ローカルで動かしてみてください。PR、Issueレポートなどお気づきの点、サジェスチョンなどあどありましたら遠慮なくお知らせください
🔗 GitHub リポジトリ: masayukimiyazawa/report-api-cdr-analysis-demo