# 機能設計書 89-タイムゾーン設定

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「タイムゾーン設定」機能の設計仕様を定義する。ユーザーのタイムゾーンを設定し、日時表示に反映する機能である。

### 本機能の処理概要

タイムゾーン設定機能は、ユーザーが自身のタイムゾーンを設定することで、アプリケーション内の日時表示を現地時間で表示できるようにする機能である。設定されたタイムゾーンは、イベント履歴やカードの作成日時などの表示に適用される。

**業務上の目的・背景**：グローバルなチームでFizzyを使用する場合、各メンバーは異なるタイムゾーンで作業している可能性がある。タイムゾーン設定により、各ユーザーが自分の現地時間で日時を確認でき、時差による混乱を防ぐことができる。

**機能の利用シーン**：ユーザープロフィール画面からタイムゾーンを選択・設定する。初回ログイン時にブラウザのタイムゾーンを自動検出して設定することも可能。

**主要な処理内容**：
1. ユーザーがタイムゾーンを選択
2. User::Settingsモデルのtimezone_nameを更新
3. 以降の日時表示に反映

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

**権限による制御**：ログインユーザーが自身のタイムゾーンのみ変更可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 38 | ユーザープロフィール画面 | 主画面 | タイムゾーン設定UI |

## 機能種別

CRUD操作（Update）/ 設定変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| timezone_name | String | Yes | タイムゾーン名（IANA形式） | ActiveSupport::TimeZoneで有効な値 |

### 入力データソース

画面フォームからの入力（またはJavaScriptによる自動検出）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| timezone_name | String | 設定されたタイムゾーン名 |

### 出力先

- データベース（user_settingsテーブル）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ PATCH /my/timezone
2. 認証チェック
   └─ ログインユーザーであることを確認
3. パラメータ取得
   └─ params[:timezone_name]
4. 設定更新
   └─ Current.user.settings.update!(timezone_name: timezone_param)
5. レスポンス返却
   └─ 成功ステータス（または画面更新）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ログイン済み?}
    B -->|No| C[ログイン画面へ]
    B -->|Yes| D[タイムゾーン名取得]
    D --> E[User::Settings更新]
    E --> F{更新成功?}
    F -->|No| G[エラーレスポンス]
    F -->|Yes| H[成功レスポンス]
    G --> I[終了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-89-01 | 有効なタイムゾーン | ActiveSupport::TimeZoneで認識されるタイムゾーン名のみ有効 | 常時 |
| BR-89-02 | デフォルトタイムゾーン | 未設定の場合はUTCがデフォルト | 未設定時 |
| BR-89-03 | 自己設定のみ | ユーザーは自身のタイムゾーンのみ変更可能 | 常時 |

### 計算ロジック

タイムゾーンの適用は`User::Settings#timezone`メソッドで行われ、`timezone_name`が設定されていればそのタイムゾーンを、未設定の場合はUTCを返す。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定更新 | user_settings | UPDATE | timezone_nameを更新 |

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

#### user_settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | timezone_name | ユーザー入力 | IANA形式のタイムゾーン名 |
| UPDATE | updated_at | 現在時刻 | 自動設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | 未ログイン | ログイン画面へリダイレクト |
| 422 | UnprocessableEntity | 無効なタイムゾーン名 | エラーメッセージ表示 |

### リトライ仕様

該当なし

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

単一レコードの更新のため、ActiveRecordのデフォルトトランザクション制御に従う。

## パフォーマンス要件

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

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

- Current.userを使用して自身の設定のみ更新可能
- CSRF対策（Railsデフォルト）

## 備考

タイムゾーン設定は、メール通知のバンドル処理にも影響する。ユーザーの現地時間を基準に通知のタイミングが計算される。

---

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

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

### 推奨読解順序

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

User::Settingsモデルのtimezone関連の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | settings.rb | `app/models/user/settings.rb` | タイムゾーン取得ロジック |
| 1-2 | schema.rb | `db/schema.rb` | user_settingsテーブルの構造 |

**読解のコツ**:
- `timezone`メソッドで、`timezone_name`が設定されていれば対応するタイムゾーンを返す
- 未設定または無効な場合は`default_timezone`（UTC）を返す

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

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

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

**主要処理フロー**:
1. **2-4行目**: `update`アクション - 設定更新処理
2. **3行目**: `Current.user.settings.update!` - 設定の更新
3. **6-8行目**: `timezone_param` - パラメータの取得

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

```
My::TimezonesController#update
    │
    ├─ ApplicationController (認証チェック)
    │
    └─ Current.user.settings.update!(timezone_name: timezone_param)
           │
           ├─ User::Settings#timezone_name= (setter)
           │
           └─ User::Settings#timezone (getter)
                  └─ ActiveSupport::TimeZone[timezone_name]
```

### データフロー図

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

フォーム/JS ───▶ TimezonesController ───▶ user_settingsテーブル
  - timezone_name       │                      UPDATE timezone_name
                        │
                        ▼
                  User::Settings
                    - validate timezone_name
                    - update record
                        │
                        ▼
                  日時表示に反映 ───▶ 現地時間表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| timezones_controller.rb | `app/controllers/my/timezones_controller.rb` | ソース | タイムゾーンコントローラー |
| settings.rb | `app/models/user/settings.rb` | ソース | ユーザー設定モデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（178行目） |
| schema.rb | `db/schema.rb` | 設定 | user_settingsテーブル定義（765-775行目） |
