# 機能設計書 41-タスクフィルタリング

## 概要

本ドキュメントは、Fat Free CRMのタスクフィルタリング機能（TasksController#filter）の設計仕様を定義するものである。

### 本機能の処理概要

タスクフィルタリング機能は、タスク一覧画面においてカテゴリ（期限別バケット）によるフィルタリングを行い、ユーザーが必要なタスクのみを効率的に閲覧できるようにする機能である。

**業務上の目的・背景**：CRMシステムにおいて、ユーザーは多数のタスクを管理する必要がある。すべてのタスクを一度に表示すると情報過多になるため、期限（今日、明日、今週、来週など）やステータス（未完了、割り当て済み、完了）でフィルタリングし、優先度の高いタスクに集中できる環境を提供する。

**機能の利用シーン**：ユーザーがタスク一覧画面（/tasks）のサイドバーに表示されたフィルターチェックボックスを操作し、特定の期限カテゴリのタスクのみを表示/非表示切り替える場面で利用される。例えば「今日期限」のタスクのみを表示したい場合や、「遅延」タスクを非表示にしたい場合などに使用する。

**主要な処理内容**：
1. クライアントからフィルター操作（チェックボックスのON/OFF）を受信
2. セッションに保存されているフィルター設定を更新
3. 対象バケットのタスク一覧の表示/非表示をJavaScriptで制御

**関連システム・外部連携**：なし（内部処理のみ）

**権限による制御**：認証済みユーザーのみアクセス可能。ユーザーは自分が作成したタスクまたは自分に割り当てられたタスクのみフィルタリング対象となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | タスク一覧画面 | 主画面 | タスクのカテゴリ等によるフィルタリング |

## 機能種別

フィルタリング処理 / セッション状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filter | String | Yes | フィルター対象のバケット名（due_asap, overdue, due_today等） | 有効なバケット名であること |
| checked | String | Yes | チェック状態（"true" or "false"） | "true" または "false" |
| view | String | No | 表示モード（pending, assigned, completed） | ALLOWED_VIEWS に含まれること |

### 入力データソース

- 画面入力：サイドバーのフィルターチェックボックス操作
- セッション：既存のフィルター設定（filter_by_task_{view}）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JavaScript応答 | String | 対象バケットのshow/hideコマンド |

### 出力先

- 画面表示：AJAXレスポンスとしてJavaScriptを返却し、タスク一覧のDOM要素を操作

## 処理フロー

### 処理シーケンス

```
1. フィルターリクエスト受信
   └─ パラメータ（filter, checked, view）を取得

2. ビューモード検証
   └─ viewが許可されたビュー（pending/assigned/completed）か確認

3. セッション更新
   └─ update_sessionメソッドでフィルター設定を更新
      ├─ checked=trueの場合：フィルターリストにバケットを追加
      └─ checked=falseの場合：フィルターリストからバケットを削除

4. JavaScript応答生成
   └─ filter.js.hamlテンプレートをレンダリング
      ├─ checked=trueの場合：$('#list_{filter}').show()
      └─ checked=falseの場合：$('#list_{filter}').hide()
```

### フローチャート

```mermaid
flowchart TD
    A[フィルター操作受信] --> B[viewパラメータ検証]
    B --> C{view有効?}
    C -->|No| D[デフォルトview適用]
    C -->|Yes| E[セッション更新処理]
    D --> E
    E --> F{checked=true?}
    F -->|Yes| G[フィルターリストに追加]
    F -->|No| H[フィルターリストから削除]
    G --> I[セッション保存]
    H --> I
    I --> J[JavaScript応答生成]
    J --> K{checked=true?}
    K -->|Yes| L[show()応答]
    K -->|No| M[hide()応答]
    L --> N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | フィルター永続化 | フィルター設定はセッションに保存され、同一セッション内で維持される | 常時 |
| BR-41-02 | ビュー別フィルター | pending/assigned/completedの各ビューで独立したフィルター設定を持つ | 常時 |
| BR-41-03 | 重複排除 | 同一バケットの重複追加を防止する | フィルター追加時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし（セッションのみ使用） |

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

本機能はデータベース操作を行わず、セッションストレージのみを使用する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータ不正 | 無効なviewパラメータ | デフォルトビュー（pending）を適用 |

### リトライ仕様

リトライ不要（同期処理、エラー時は即座にデフォルト値を適用）

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

データベーストランザクションなし

## パフォーマンス要件

- 即座に応答すること（100ms以内目標）
- セッションアクセスのみのため軽量処理

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

- 認証必須：ApplicationControllerのbefore_actionで認証チェック
- セッション操作：サーバーサイドセッションを使用し、クライアント側での改ざん防止
- パラメータエスケープ：JavaScriptテンプレートでjヘルパーを使用しXSS対策

## 備考

- フィルター設定はログアウト時にクリアされる
- タスク作成・削除・完了時にはupdate_sidebarメソッドで自動的にフィルター設定が調整される

---

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

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

### 推奨読解順序

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

フィルタリングの対象となるタスクのバケット構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | task.rb | `app/models/polymorphic/task.rb` | ALLOWED_VIEWS定数（35行目）、バケット関連スコープ（84-95行目） |

**読解のコツ**: Taskモデルには多数のスコープが定義されている。due_asap, overdue, due_today等のスコープがフィルターのバケットに対応している。

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

フィルターアクションの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tasks_controller.rb | `app/controllers/tasks_controller.rb` | filterアクション（149-159行目） |

**主要処理フロー**:
1. **149行目**: filterアクション開始
2. **150行目**: viewパラメータの検証（viewメソッド呼び出し）
3. **152-158行目**: update_sessionブロックでフィルター設定更新

#### Step 3: セッション管理を理解する

セッションへのフィルター設定保存ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tasks_controller.rb | `app/controllers/tasks_controller.rb` | update_sessionメソッド（188-193行目） |
| 3-2 | tasks_controller.rb | `app/controllers/tasks_controller.rb` | viewメソッド（222-226行目） |

**主要処理フロー**:
- **189行目**: セッションキー名の生成（filter_by_task_{view}形式）
- **190行目**: 既存フィルター設定の読み込み（カンマ区切り文字列から配列へ）
- **191行目**: yieldでブロックにフィルター配列を渡す
- **192行目**: 更新されたフィルター配列をカンマ区切り文字列に変換して保存

#### Step 4: ビューレスポンスを理解する

JavaScript応答の生成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | filter.js.haml | `app/views/tasks/filter.js.haml` | show/hide制御（1-4行目） |

**主要処理フロー**:
- **1行目**: checkedパラメータが'true'かどうか判定
- **2行目**: trueの場合、対象バケットのリストをshow()
- **4行目**: falseの場合、対象バケットのリストをhide()

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

```
TasksController#filter
    │
    ├─ view (private method)
    │      └─ ALLOWED_VIEWS検証
    │
    └─ update_session (private method)
           └─ セッション読み書き
```

### データフロー図

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

チェックボックス操作 ───▶ TasksController#filter ───▶ JavaScript応答
  ├─ filter                    │                           │
  ├─ checked                   ├─ view検証                  ├─ show()
  └─ view                      └─ session更新               └─ hide()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tasks_controller.rb | `app/controllers/tasks_controller.rb` | コントローラー | フィルターアクション、セッション管理 |
| task.rb | `app/models/polymorphic/task.rb` | モデル | タスクモデル、ALLOWED_VIEWS定義 |
| filter.js.haml | `app/views/tasks/filter.js.haml` | ビュー | JavaScript応答テンプレート |
| _sidebar_index.html.haml | `app/views/tasks/_sidebar_index.html.haml` | ビュー | フィルターチェックボックス表示 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング設定（146行目） |
