# 機能設計書 90-ピン留め一覧表示

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「ピン留め一覧表示」機能の設計仕様を定義する。ユーザーがピン留めしたカードの一覧を表示する機能である。

### 本機能の処理概要

ピン留め一覧表示機能は、現在のユーザーがピン留めしたカードの一覧を表示する機能である。ピン留めは個人的なブックマーク機能であり、重要なカードや頻繁に参照するカードを素早くアクセスできるようにする。

**業務上の目的・背景**：ユーザーが多数のボードやカードを扱う場合、特に重要なカードや注目しているカードを素早く参照できる必要がある。ピン留め機能により、ボードを跨いで自分にとって重要なカードをまとめて確認できる。

**機能の利用シーン**：マイメニューや専用の「Pinned」ページからピン留めしたカードの一覧を確認する。例えば、担当中の重要タスク、監視中の課題、近日中の締め切りがあるカードなどをピン留めして管理する。

**主要な処理内容**：
1. 現在のユーザーのピン留め一覧を取得
2. 関連するカード情報をプリロード
3. 作成日時の降順でソート
4. 件数制限（HTML: 20件、JSON: 100件）
5. ETagによるキャッシュ制御

**関連システム・外部連携**：なし

**権限による制御**：ログインユーザーが自身のピン留め一覧のみ閲覧可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | マイメニュー画面 | 参照画面 | ピン留めトレイ表示 |
| 49 | ピン一覧画面 | 主画面 | ピン留めしたカードの一覧を表示 |

## 機能種別

参照・表示 / 一覧表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | ユーザーは認証情報から特定 | - |

### 入力データソース

認証情報（Current.user）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pins | Array | ピン留めの配列 |
| pins[].id | UUID | ピンID |
| pins[].card | Card | 関連カード |
| pins[].created_at | DateTime | ピン留め日時 |

### 出力先

HTML画面表示またはJSON API

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ GET /my/pins
2. 認証チェック
   └─ ログインユーザーであることを確認
3. ピン一覧取得
   └─ Current.user.pins.includes(:card).ordered.limit(件数)
4. ETagチェック
   └─ fresh_when etag: [ @pins, @pins.collect(&:card) ]
5. レスポンス返却
   └─ HTML（20件）またはJSON（100件）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ログイン済み?}
    B -->|No| C[ログイン画面へ]
    B -->|Yes| D[ピン一覧取得]
    D --> E[カード情報プリロード]
    E --> F[件数制限適用]
    F --> G{ETag一致?}
    G -->|Yes| H[304 Not Modified]
    G -->|No| I[レスポンス生成]
    I --> J{リクエスト形式?}
    J -->|HTML| K[HTML画面表示]
    J -->|JSON| L[JSONレスポンス]
    K --> M[終了]
    L --> M
    H --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-90-01 | 自己ピンのみ | 自分がピン留めしたカードのみ表示 | 常時 |
| BR-90-02 | ソート順序 | ピン留め日時の降順（最新が先頭） | 常時 |
| BR-90-03 | HTML件数制限 | HTML表示は20件まで | HTML形式時 |
| BR-90-04 | JSON件数制限 | JSONレスポンスは100件まで | JSON形式時 |
| BR-90-05 | ETagキャッシュ | ピンとカードの変更でETagが更新される | 常時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ピン取得 | pins | SELECT | ユーザーのピン一覧を取得 |
| カード取得 | cards | SELECT | 関連カードをEagerLoad |

### テーブル別操作詳細

#### pins

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全カラム | user_id = Current.user.id ORDER BY created_at DESC | 件数制限あり |

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全カラム | id IN (pins.card_id) | includes(:card)でEagerLoad |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | 未ログイン | ログイン画面へリダイレクト |

### リトライ仕様

該当なし

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

参照のみのためトランザクション制御なし

## パフォーマンス要件

- レスポンス時間: 300ms以内
- ETagによるキャッシュで304レスポンスを活用

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

- Current.userを使用して自身のピン留めのみ取得
- 他ユーザーのピン留めは一切表示されない

## 備考

ピン留めの追加・削除機能は別機能（No.33, No.34）で定義されている。本機能は一覧表示のみを担当する。

---

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

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

### 推奨読解順序

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

Pinモデルとその関連を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pin.rb | `app/models/pin.rb` | Pinモデルの構造と関連 |
| 1-2 | user.rb | `app/models/user.rb` | has_many :pinsの定義 |
| 1-3 | schema.rb | `db/schema.rb` | pinsテーブルの構造 |

**読解のコツ**:
- `belongs_to :card`でカードとの関連付け
- `scope :ordered`で作成日時降順のソートが定義

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

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

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

**主要処理フロー**:
1. **2-5行目**: `index`アクション - ピン一覧取得とETag設定
2. **3行目**: `@pins = user_pins` - ピン一覧の取得
3. **4行目**: `fresh_when` - ETagによるキャッシュ制御
4. **8-10行目**: `user_pins` - 取得ロジック（includes, ordered, limit）
5. **12-14行目**: `pins_limit` - 形式による件数制限

#### Step 3: ビューテンプレートを理解する

ピン一覧画面の表示内容を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.erb | `app/views/my/pins/index.html.erb` | メイン画面の構造 |
| 3-2 | _pin.html.erb | `app/views/my/pins/_pin.html.erb` | 個別ピンの表示 |

**主要処理フロー**:
- **11-14行目**: turbo_frameによるピン一覧の表示
- **13行目**: pinパーシャルの呼び出し

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

```
My::PinsController#index
    │
    ├─ ApplicationController (認証チェック)
    │
    ├─ user_pins
    │      └─ Current.user.pins.includes(:card).ordered.limit(pins_limit)
    │             │
    │             ├─ Pin.ordered (scope)
    │             │      └─ order(created_at: :desc)
    │             │
    │             └─ includes(:card) (EagerLoad)
    │
    └─ fresh_when etag: [ @pins, @pins.collect(&:card) ]
           └─ ETagによるキャッシュ制御
```

### データフロー図

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

認証情報 ───▶ My::PinsController ───▶ HTML/JSON
(Current.user)       │
                     ▼
               pinsテーブル ───▶ ピン一覧取得
                     │           (user_id = Current.user.id)
                     │
                     ├─▶ cardsテーブル ───▶ カード情報EagerLoad
                     │
                     ▼
               件数制限 ───▶ HTML: 20件 / JSON: 100件
                     │
                     ▼
               ETagチェック ───▶ 304 or 200
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pins_controller.rb | `app/controllers/my/pins_controller.rb` | ソース | ピン一覧コントローラー |
| pin.rb | `app/models/pin.rb` | ソース | Pinモデル |
| user.rb | `app/models/user.rb` | ソース | Userモデル（has_many :pins） |
| index.html.erb | `app/views/my/pins/index.html.erb` | テンプレート | ピン一覧画面 |
| _pin.html.erb | `app/views/my/pins/_pin.html.erb` | テンプレート | ピンパーシャル |
| index.json.jbuilder | `app/views/my/pins/index.json.jbuilder` | テンプレート | JSON形式レスポンス |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（177行目） |
| schema.rb | `db/schema.rb` | 設定 | pinsテーブル定義（406-416行目） |
