# 機能設計書 55-Tinybird連携

## 概要

本ドキュメントは、GhostのTinybird連携機能に関する設計を記述します。この機能は、Tinybirdリアルタイム分析プラットフォームとの認証・連携を管理し、サイト訪問者統計やページビュー分析のためのトークン管理を行います。

### 本機能の処理概要

**業務上の目的・背景**：Ghostはサイト訪問者のリアルタイム分析にTinybirdを使用しています。Tinybirdは高速な分析クエリを実行するデータプラットフォームで、アクティブ訪問者数、ページビュー、トップソース、位置情報などの統計を提供します。本機能は、フロントエンドからTinybirdに安全にアクセスするためのJWTトークン管理を担当します。

**機能の利用シーン**：管理画面でのリアルタイム訪問者数の表示、ダッシュボードでのトラフィック分析、投稿別アクセス統計の表示などの場面で活用されます。

**主要な処理内容**：
1. JWTトークンの生成と管理
2. トークンの有効期限管理と自動更新
3. パイプ別のアクセススコープ設定
4. ローカル開発環境と本番環境の切り替え

**関連システム・外部連携**：
- Tinybird: リアルタイム分析プラットフォーム
- Admin API: トークン取得エンドポイント

**権限による制御**：Tinybirdトークンへのアクセスは、`members` ドキュメントの `browse` 権限を持つユーザーに限定されます。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | ホーム画面 | 参照画面 | アクティブ訪問者数の表示 |
| 24 | 成長分析画面 | 主画面 | Webトラフィック統計の表示 |
| 28 | 投稿Webトラフィック画面 | 主画面 | 投稿別訪問者統計 |

## 機能種別

認証 / トークン管理 / 外部連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | No | トークン名 | 任意の文字列 |
| expiresInMinutes | number | No | 有効期限（分） | デフォルト180分 |

### 入力データソース

- 設定ファイル: `config.tinybird` - ワークスペースID、管理トークン
- 設定キャッシュ: `site_uuid` - サイト識別子

## 出力仕様

### 出力データ

#### トークンレスポンス

| 項目名 | 型 | 説明 |
|--------|-----|------|
| token | string | JWTトークン文字列 |
| exp | string | 有効期限（ISO 8601形式） |

### 出力先

- Admin API経由でフロントエンド（React Stats App）へJSON形式で返却

## 処理フロー

### 処理シーケンス

```
1. トークンリクエスト受信
   └─ Admin API /tinybird/token

2. サービス初期化
   └─ TinybirdServiceWrapper.init()
   └─ 設定読み込み（workspaceId, adminToken, siteUuid）

3. トークン取得/生成
   └─ JWT有効: キャッシュされたトークンを返却
   └─ JWT無効/期限切れ: 新規トークン生成

4. トークン生成（JWTモード）
   └─ ペイロード構築（workspace_id, scopes）
   └─ adminTokenで署名
   └─ キャッシュに保存

5. レスポンス返却
   └─ {token, exp} 形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[トークンリクエスト] --> B[サービス初期化]
    B --> C{設定有効?}
    C -->|No| D[null返却]
    C -->|Yes| E{JWTモード?}
    E -->|Yes| F{トークン有効?}
    E -->|No| G{ローカルモード?}
    F -->|Yes| H[キャッシュ返却]
    F -->|No| I[新規JWT生成]
    G -->|Yes| J[ローカルトークン]
    G -->|No| K{レガシーモード?}
    K -->|Yes| L[statsトークン]
    K -->|No| D
    I --> M[レスポンス返却]
    H --> M
    J --> M
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-55-001 | JWTモード優先 | workspaceIdとadminTokenがある場合はJWTモードを使用 | 設定存在時 |
| BR-55-002 | トークン自動更新 | 有効期限の5分前で自動更新 | JWTモード時 |
| BR-55-003 | サイトUUID制限 | トークンはsite_uuidでスコープを制限 | 全パイプアクセス時 |
| BR-55-004 | パイプアクセス許可 | PIPES:READスコープで特定パイプのみアクセス許可 | トークン生成時 |

### 計算ロジック

**トークン有効期限判定**:
```javascript
timeRemaining = decoded.exp - now;
isExpired = timeRemaining < bufferSeconds; // bufferSeconds = 300 (5分)
```

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースへの直接アクセスを行いません。設定はファイルおよびsettings_cacheから読み取ります。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Warn | Tinybird設定なし | ログ出力後null返却 |
| 403 | PermissionError | 権限不足 | 適切な権限を持つユーザーでの操作を要求 |

## トランザクション仕様

トランザクション管理は不要です（データベース操作なし）。

## パフォーマンス要件

- トークン取得: 10ms以内
- トークン生成: 50ms以内
- トークンキャッシュ有効期間: 180分

## セキュリティ考慮事項

- adminTokenはサーバーサイドのみで使用（クライアントに公開しない）
- JWTトークンにはsite_uuidでスコープを制限
- トークンの有効期限は最大180分

## 備考

- Tinybirdパイプ一覧（24パイプ）:
  - api_kpis, api_active_visitors, api_post_visitor_counts
  - api_top_locations, api_top_pages, api_top_sources
  - api_top_utm_sources, api_top_utm_mediums, api_top_utm_campaigns
  - api_top_utm_contents, api_top_utm_terms, api_top_devices
  - v2バージョンも含む（マテリアライズドビュー最適化版）

---

## コードリーディングガイド

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tinybird-service.js | `ghost/core/core/server/services/tinybird/tinybird-service.js` | TinybirdConfig, TinybirdJWTPayload型定義（3-45行目） |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tinybird.js | `ghost/core/core/server/api/endpoints/tinybird.js` | token API エンドポイント |

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tinybird-service-wrapper.js | `ghost/core/core/server/services/tinybird/tinybird-service-wrapper.js` | サービス初期化 |
| 3-2 | tinybird-service.js | `ghost/core/core/server/services/tinybird/tinybird-service.js` | トークン生成ロジック |

**主要処理フロー**:
- **78-94行目**: コンストラクタ - 設定読み込みとモード判定
- **102-130行目**: `getToken()` - トークン取得（モード別分岐）
- **138-163行目**: `_generateToken()` - JWT生成
- **172-184行目**: `_isJWTExpired()` - 有効期限チェック

### プログラム呼び出し階層図

```
Admin API Request (/tinybird/token)
    │
    └─ tinybird.js (API Controller)
           │
           └─ token.query()
                  │
                  ├─ TinybirdServiceWrapper.init()
                  │      ├─ config.get('tinybird')
                  │      └─ settingsCache.get('site_uuid')
                  │
                  └─ TinybirdService.getToken()
                         │
                         ├─ [JWT Mode] _generateToken()
                         │      └─ jwt.sign(payload, adminToken)
                         │
                         ├─ [Local Mode] localToken返却
                         │
                         └─ [Legacy Mode] statsToken返却
```

### データフロー図

```
┌─────────────────┐     ┌──────────────────┐     ┌───────────────────┐
│  Admin API      │────>│ TinybirdService  │────>│  JWT Library      │
│  (tinybird.js)  │     │  (getToken)      │     │  (jsonwebtoken)   │
└─────────────────┘     └──────────────────┘     └───────────────────┘
         │                       │                        │
         │                       ▼                        │
         │              ┌──────────────────┐             │
         │              │   Config/Cache   │<────────────┘
         │              │   (settings)     │
         │              └──────────────────┘
         │                       │
         ▼                       ▼
┌─────────────────┐     ┌──────────────────┐
│  Stats App      │<────│  JWT Token       │
│  (React)        │     │  (scoped)        │
└─────────────────┘     └──────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tinybird.js | `ghost/core/core/server/api/endpoints/tinybird.js` | ソース | API エンドポイント |
| tinybird-service.js | `ghost/core/core/server/services/tinybird/tinybird-service.js` | ソース | トークン生成サービス |
| tinybird-service-wrapper.js | `ghost/core/core/server/services/tinybird/tinybird-service-wrapper.js` | ソース | サービス初期化ラッパー |
| index.js | `ghost/core/core/server/services/tinybird/index.js` | ソース | モジュールエクスポート |
| tinybird.js | `ghost/core/core/server/api/endpoints/utils/serializers/output/tinybird.js` | ソース | 出力シリアライザ |
