# 機能設計書 88-QRコード生成

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「QRコード生成」機能の設計仕様を定義する。指定されたURLのQRコードをSVG形式で生成する機能である。

### 本機能の処理概要

QRコード生成機能は、署名付きURLパラメータからURLを復元し、そのURLを表すQRコードをSVG形式で生成して返す機能である。主に参加コードの共有など、URLを視覚的に共有する場面で使用される。

**業務上の目的・背景**：モバイルデバイスでURLを簡単に読み取れるようにするため、QRコードを生成する機能が必要である。特に、アカウントへの参加コードを共有する際に、QRコードをスキャンするだけで参加URLにアクセスできるようにすることで、ユーザー体験を向上させる。

**機能の利用シーン**：参加コード表示画面でQRコードを表示する際に使用される。管理者がチームメンバーを招待する際、QRコードを印刷または画面に表示し、参加者がスマートフォンで読み取ってアカウントに参加する。

**主要な処理内容**：
1. 署名付きIDからURLを復元（セキュリティ検証）
2. RQRCodeライブラリを使用してQRコードを生成
3. SVG形式でレスポンスを返却
4. 1年間のパブリックキャッシュを設定

**関連システム・外部連携**：RQRCode gemによるQRコード生成

**権限による制御**：認証不要（ただし、署名付きIDが必要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 57 | 参加コード表示画面 | 主画面 | QRコードを表示 |

## 機能種別

画像生成 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | String | Yes | 署名付きURL（MessageVerifierで生成） | URLパラメータ |

### 入力データソース

URLパラメータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| QRコードSVG | String | SVG形式のQRコード画像 |

### 出力先

HTTPレスポンス（Content-Type: image/svg+xml）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ GET /qr_codes/:id
2. 署名検証とURL復元
   └─ QrCodeLink.from_signed(params[:id])
3. 検証失敗時
   └─ ActiveSupport::MessageVerifier::InvalidSignature例外
4. QRコード生成
   └─ RQRCode::QRCode.new(url).as_svg(...)
5. キャッシュ設定
   └─ 1年間のパブリックキャッシュを設定
6. SVGレスポンス返却
   └─ render svg: qr_code_svg
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[署名付きIDから URL復元]
    B --> C{署名有効?}
    C -->|No| D[422 Unprocessable Entity]
    C -->|Yes| E[URL取得]
    E --> F[QRコード生成]
    F --> G[キャッシュ設定]
    G --> H[SVGレスポンス返却]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-88-01 | 署名検証 | 署名が無効な場合はエラーを返す | 常時 |
| BR-88-02 | キャッシュ期間 | 1年間のパブリックキャッシュを設定 | 常時 |
| BR-88-03 | SVG形式 | QRコードはSVG形式で返却される | 常時 |
| BR-88-04 | カラー設定 | 白背景に黒のQRコード、オフセット16px | 常時 |

### 計算ロジック

QRコード生成はRQRCodeライブラリに委譲。viewboxオプションでレスポンシブ対応。

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

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

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 422 | UnprocessableEntity | 署名が無効 | エラーページ表示 |

### リトライ仕様

該当なし

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

データベース操作なし

## パフォーマンス要件

- レスポンス時間: 200ms以内
- キャッシュ: 1年間のパブリックキャッシュ（CDN等で利用可能）

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

- MessageVerifierによる署名検証でURLの改ざんを防止
- 署名に使用するシークレットはRailsのkey_generatorから生成
- 認証不要だが、署名なしでは任意のURLのQRコードは生成できない

## 備考

QrCodeLinkクラスは、URLを署名付きでエンコード/デコードするためのユーティリティクラス。署名にはRailsのActiveSupport::MessageVerifierを使用し、目的（purpose）として`:qr_code`を指定している。

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

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

QrCodeLinkクラスの署名・検証ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | qr_code_link.rb | `app/models/qr_code_link.rb` | 署名・検証ロジック |

**読解のコツ**:
- `from_signed`クラスメソッドで署名付きIDからURLを復元
- `signed`インスタンスメソッドでURLを署名付きIDにエンコード
- MessageVerifierの`purpose: :qr_code`で目的を限定

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

コントローラーのshowアクションが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | qr_codes_controller.rb | `app/controllers/qr_codes_controller.rb` | showアクションの処理フロー |

**主要処理フロー**:
1. **2行目**: `allow_unauthenticated_access` - 認証不要の宣言
2. **5行目**: `expires_in 1.year, public: true` - 1年間のキャッシュ設定
3. **7-9行目**: QRコード生成処理
4. **11行目**: `render svg: qr_code_svg` - SVGレスポンス返却

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

```
QrCodesController#show
    │
    ├─ allow_unauthenticated_access (認証スキップ)
    │
    ├─ expires_in 1.year, public: true (キャッシュ設定)
    │
    └─ RQRCode::QRCode.new(url)
           │
           ├─ QrCodeLink.from_signed(params[:id])
           │      │
           │      └─ MessageVerifier.verify(signed, purpose: :qr_code)
           │
           └─ .as_svg(viewbox: true, fill: :white, color: :black, offset: 16)
```

### データフロー図

```
[入力]               [処理]                    [出力]

URLパラメータ ───▶ QrCodesController ───▶ SVGレスポンス
  - id (署名付き)        │
                         ▼
                   QrCodeLink.from_signed
                         │
                         ├─ MessageVerifier.verify
                         │      (署名検証)
                         │
                         ▼
                   RQRCode::QRCode.new
                         │
                         └─ .as_svg() ───▶ QRコード画像
                                             (image/svg+xml)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| qr_codes_controller.rb | `app/controllers/qr_codes_controller.rb` | ソース | QRコードコントローラー |
| qr_code_link.rb | `app/models/qr_code_link.rb` | ソース | 署名付きURLエンコード/デコード |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（144行目） |
