# 機能設計書 174-自動オフライン設定

## 概要

本ドキュメントは、Chatwootにおける自動オフライン設定機能の設計仕様を定義する。この機能は、エージェントがアカウント毎に自動オフライン機能の有効/無効を設定するためのAPIを提供する。

### 本機能の処理概要

**業務上の目的・背景**：
カスタマーサポートチームにおいて、エージェントのオンラインプレゼンスを正確に反映することは、顧客対応の品質と効率に直接影響する。自動オフライン機能により、エージェントがブラウザを閉じたり、ネットワーク接続が切れた場合に、システムが自動的にオフライン状態として扱う。これにより、不在のエージェントへの会話割り当てを防止できる。

**機能の利用シーン**：
- エージェントが自動オフライン機能を有効にし、離席時に自動でオフラインになるようにする場合
- エージェントが自動オフライン機能を無効にし、常にオンライン状態を維持したい場合
- 管理者がシフト制のエージェントに対して自動オフラインを推奨する場合

**主要な処理内容**：
1. 認証済みユーザーの確認
2. 指定されたアカウントのAccountUser取得
3. auto_offlineフラグの更新
4. 更新後のユーザー情報を返却

**関連システム・外部連携**：
- OnlineStatusTracker: プレゼンス管理サービス
- availability_statusの算出ロジックに影響

**権限による制御**：
認証済みユーザーのみが自身の自動オフライン設定を変更可能。自分が所属するアカウントに対してのみ設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 89 | プロフィール設定画面 | 主画面 | 自動オフライン設定の切り替え |

## 機能種別

CRUD操作（Update）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| profile[account_id] | Integer | Yes | 対象アカウントID | 所属アカウントであること |
| profile[auto_offline] | Boolean | No | 自動オフラインフラグ | true/false（省略時はfalse） |

### 入力データソース

- フロントエンド画面からのJSON形式リクエスト
- 認証トークンからのユーザー識別

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | ユーザーID |
| accounts | Array | 所属アカウント一覧 |
| accounts[].auto_offline | Boolean | 自動オフラインフラグ |
| accounts[].availability_status | String | プレゼンスを考慮した実際の可用性状態 |

### 出力先

- JSON形式でHTTPレスポンスとして返却

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ POST /api/v1/profile/auto_offline
2. 認証検証
   └─ current_userから@userを設定
3. AccountUser取得
   └─ account_idで対象のAccountUserを検索
4. auto_offline更新
   └─ auto_offlineカラムを更新（デフォルトfalse）
5. レスポンス生成
   └─ 更新後のユーザー情報をJSON返却
```

### フローチャート

```mermaid
flowchart TD
    A[POST /api/v1/profile/auto_offline] --> B{認証済み?}
    B -->|No| C[401 Unauthorized]
    B -->|Yes| D[AccountUser検索]
    D --> E{存在する?}
    E -->|No| F[404 Not Found]
    E -->|Yes| G[auto_offline更新]
    G --> H{更新成功?}
    H -->|No| I[422 Unprocessable Entity]
    H -->|Yes| J[JSON レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-174-01 | アカウント所属確認 | ユーザーが所属するアカウントに対してのみ設定可能 | account_id指定時 |
| BR-174-02 | デフォルト値 | auto_offlineが省略された場合はfalseとして扱う | パラメータ未指定時 |
| BR-174-03 | 可用性状態への影響 | auto_offline=trueの場合、プレゼンスがないとofflineとして扱われる | availability_status算出時 |

### 計算ロジック

**availability_statusの算出（auto_offlineがtrueの場合）**:
```
if auto_offline && !online_presence?
  return 'offline'
else
  return OnlineStatusTracker.get_status(account_id, user_id) || availability
end
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| AccountUser検索 | account_users | SELECT | account_idでユーザーのAccountUserを取得 |
| auto_offline更新 | account_users | UPDATE | auto_offlineカラムの更新 |

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

#### account_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | user_id = current_user.id AND account_id = params[:account_id] | AccountUser取得 |
| UPDATE | auto_offline | true/false | ブール値として保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | 認証トークンが無効 | 再ログイン |
| 404 | Not Found | 指定されたaccount_idに対応するAccountUserが存在しない | 正しいaccount_idを指定 |

### リトライ仕様

特になし

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

AccountUserの更新は暗黙のトランザクション内で実行される。

## パフォーマンス要件

- レスポンス時間: 300ms以内

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

- 認証トークンによるアクセス制御
- 自分が所属するアカウントのみ更新可能

## 備考

- auto_offlineのデフォルト値はtrue（スキーマ定義）
- auto_offline=falseの場合、プレゼンスに関係なく設定されたavailabilityが使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | account_user.rb | `app/models/account_user.rb` | AccountUserモデルのスキーマ、auto_offlineカラム |
| 1-2 | availability_statusable.rb | `app/models/concerns/availability_statusable.rb` | auto_offlineを考慮した可用性状態の算出ロジック |

**読解のコツ**: account_usersテーブルの`auto_offline`カラムは`default: TRUE`であり、新規作成時は自動オフラインが有効になっている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | profiles_controller.rb | `app/controllers/api/v1/profiles_controller.rb` | auto_offlineアクションの実装 |

**主要処理フロー**:
1. **23行目**: `auto_offline`アクション定義
2. **24行目**: `@user.account_users.find_by!(account_id: ...)` - 対象AccountUserを検索
3. **24行目**: `.update!(auto_offline: params[:auto_offline] || false)` - フラグを更新
4. **56-58行目**: `auto_offline_params` - 許可されるパラメータの定義

#### Step 3: availability_statusへの影響を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | availability_statusable.rb | `app/models/concerns/availability_statusable.rb` | auto_offlineの影響を受けるロジック |

**主要処理フロー**:
- **23-28行目**: `user_availability_status`メソッド
- **25行目**: `return availability unless auto_offline` - auto_offline=falseなら設定値をそのまま返却
- **28行目**: プレゼンスがない場合は'offline'を返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | auto_offline.jbuilder | `app/views/api/v1/profiles/auto_offline.jbuilder` | レスポンスJSON構造 |

**主要処理フロー**:
- **1行目**: `_user.json.jbuilder`のpartialを呼び出し

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

```
Api::V1::ProfilesController#auto_offline
    │
    ├─ @user.account_users.find_by!(account_id: ...)
    │      └─ AccountUser検索
    │
    └─ AccountUser#update!(auto_offline: ...)
           └─ ActiveRecord::Base#save!
                  └─ account_users UPDATE
```

### データフロー図

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

POST リクエスト ───────▶ ProfilesController#auto_offline ───────▶ JSON Response
(account_id,               │
 auto_offline)             │
                           ▼
                     AccountUser
                           │
                           └─▶ account_users UPDATE

                           ...後続処理...

[availability_status算出時]
auto_offline ─────▶ AvailabilityStatusable#user_availability_status
                           │
                           ├─ online_presence? (Redis)
                           │
                           └─▶ availability_status (算出結果)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| profiles_controller.rb | `app/controllers/api/v1/profiles_controller.rb` | コントローラー | auto_offlineアクションの定義（23-25行目） |
| account_user.rb | `app/models/account_user.rb` | モデル | AccountUserモデル、auto_offlineカラム定義 |
| availability_statusable.rb | `app/models/concerns/availability_statusable.rb` | concern | auto_offlineを考慮した可用性状態の算出 |
| auto_offline.jbuilder | `app/views/api/v1/profiles/auto_offline.jbuilder` | ビュー | レスポンステンプレート |
| _user.json.jbuilder | `app/views/api/v1/models/_user.json.jbuilder` | ビュー | ユーザー情報のpartialテンプレート |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（372行目） |
