# 画面設計書 311-タイムログ一覧

## 概要

本ドキュメントは、GitLabにおけるタイムログ一覧画面の設計仕様を定義するものである。

### 本画面の処理概要

タイムログ一覧画面は、GitLabにおける時間追跡（タイムトラッキング）機能のレポート画面であり、ユーザーが記録した作業時間を一覧形式で表示・分析するための機能を提供する。

**業務上の目的・背景**：プロジェクト管理においては、各タスクにかかった作業時間を正確に把握することが重要である。この画面は、グループやプロジェクト単位での作業時間の集計、ユーザー別の作業時間分析、期間を指定したレポート生成など、チームの生産性分析やプロジェクトの進捗管理に必要な情報を提供する。特に、工数管理や請求業務において、実績ベースのデータを取得するために活用される。

**画面へのアクセス方法**：メインナビゲーションから「Timelogs」または直接URL `/timelogs` にアクセスすることで表示される。ただし、`global_time_tracking_report` フィーチャーフラグが有効なユーザーのみアクセス可能である。

**主要な操作・処理内容**：
1. グループ選択によるフィルタリング - 特定のグループに属するプロジェクトのタイムログのみを表示
2. ユーザー名によるフィルタリング - 特定ユーザーのタイムログを検索
3. 期間指定（開始日・終了日）によるフィルタリング - 指定期間内のタイムログを絞り込み
4. レポート実行 - フィルタ条件に基づいてタイムログデータを取得・表示
5. ページネーション - 大量のデータをページ単位で表示

**画面遷移**：
- ダッシュボードからのアクセス
- 各タイムログエントリから、関連するIssueまたはMerge Requestの詳細画面への遷移

**権限による表示制御**：
- フィーチャーフラグ `global_time_tracking_report` が有効なユーザーのみアクセス可能
- グループフィルタでは、Reporter以上のアクセス権限を持つグループのみ選択可能（min_access_level: 20）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 43 | タイムトラッキング | 主機能 | タイムログ一覧表示 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/timelogs`
- コントローラ: `TimeTracking::TimelogsController#index`
- ルート定義: `config/routes.rb` (261行目)

## 入出力項目

| 項目名 | 項目種別 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| グループ | 入力 | String (GraphQL ID) | いいえ | フィルタ対象のグループ |
| ユーザー名 | 入力 | String | いいえ | フィルタ対象のユーザー名 |
| 開始日 | 入力 | Date | いいえ | 検索期間の開始日（デフォルト: 30日前） |
| 終了日 | 入力 | Date | いいえ | 検索期間の終了日（デフォルト: 当日） |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 作業時間 | Duration | 記録された作業時間（時間制限設定により表示形式が変わる） |
| 記録日 | Date | 作業が行われた日 |
| ソース | Link | 関連するIssueまたはMerge Request |
| ユーザー | String | 作業を記録したユーザー |
| 合計時間 | Duration | フィルタ条件に合致するすべてのタイムログの合計時間 |

## イベント仕様

### 1-レポート実行

フィルタ条件を指定して「Run report」ボタンを押下すると、GraphQL APIを通じてタイムログデータを取得する。

**処理フロー**：
1. フィルタ条件（グループ、ユーザー名、期間）を収集
2. URLパラメータを更新（ブラウザ履歴に反映）
3. GraphQL `getTimelogsQuery` を実行
4. 取得したデータをテーブルに表示
5. 合計時間を計算・表示

### 2-ページネーション

次ページ/前ページボタン押下時に、カーソルベースのページネーションでデータを取得する。

**処理フロー**：
1. 現在のページ情報（pageInfo）からカーソルを取得
2. 次ページの場合は `after` カーソル、前ページの場合は `before` カーソルを設定
3. GraphQL クエリを再実行
4. 表示データを更新

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| レポート表示 | timelogs | SELECT | 条件に合致するタイムログを取得 |

### テーブル別更新項目詳細

#### timelogs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | time_spent | - | 作業時間（秒） |
| SELECT | spent_at | - | 作業日 |
| SELECT | user_id | - | 作業者 |
| SELECT | issue_id | - | 関連Issue |
| SELECT | merge_request_id | - | 関連MR |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| エラー | Something went wrong. Please try again. | GraphQL クエリ実行時にエラーが発生した場合 |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| フィーチャーフラグ無効 | 404エラーを返す |
| 認証されていない | ログイン画面へリダイレクト |
| APIエラー | アラートメッセージを表示し、Sentryにエラーを送信 |

## 備考

- `time_tracking_limit_to_hours` 設定により、時間の表示形式が制御される
- 1ページあたり20件のエントリを表示
- URLパラメータにフィルタ条件が保存されるため、ブックマークやリンク共有が可能

---

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

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

### 推奨読解順序

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

まず、タイムログのデータモデルを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | timelog.rb | `app/models/timelog.rb` | Timelogモデルの構造、バリデーション、スコープを理解する |

**読解のコツ**: Timelogモデルは `issue` または `merge_request` のいずれかに紐付く。`issuable` メソッドで抽象化されている点に注目。

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

処理の起点となるコントローラを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | timelogs_controller.rb | `app/controllers/time_tracking/timelogs_controller.rb` | フィーチャーフラグによるアクセス制御を理解する |

**主要処理フロー**:
1. **8-10行目**: `index` アクションでフィーチャーフラグを確認し、無効な場合は404を返す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/time_tracking/timelogs/index.html.haml` | Vue.jsコンポーネントのマウント設定を理解する |

**主要処理フロー**:
- **7行目**: `#js-timelogs-app` 要素にVueアプリをマウント。`limit_to_hours` 設定をdata属性として渡す

#### Step 4: フロントエンドコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | timelogs_app.vue | `app/assets/javascripts/time_tracking/components/timelogs_app.vue` | 主要なVueコンポーネント、フィルタ処理、GraphQLクエリを理解する |
| 4-2 | timelogs_table.vue | `app/assets/javascripts/time_tracking/components/timelogs_table.vue` | タイムログ一覧テーブルの表示を理解する |

**主要処理フロー**:
- **79-98行目**: Apollo Clientを使用したGraphQLクエリの定義
- **192-214行目**: `runReport` メソッドでフィルタ条件を設定しクエリを実行
- **114-151行目**: URLパラメータからの初期値設定

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

```
TimelogsController#index
    │
    ├─ Feature.enabled?(:global_time_tracking_report)
    │      └─ フィーチャーフラグ確認
    │
    └─ index.html.haml (View)
           │
           └─ #js-timelogs-app (Vue mount point)
                  │
                  └─ timelogs_app.vue
                         │
                         ├─ Apollo Client
                         │      └─ getTimelogsQuery (GraphQL)
                         │
                         ├─ GroupSelect
                         │
                         └─ TimelogsTable
                                └─ TimelogSourceCell
```

### データフロー図

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

フィルタ条件        ───▶  timelogs_app.vue          ───▶  一覧テーブル表示
(グループ/ユーザー/期間)   │                               │
                          │                               └─ 合計時間表示
                          ▼
                    GraphQL API
                          │
                          ▼
                    Timelog Model
                          │
                          ▼
                    timelogs テーブル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| timelogs_controller.rb | `app/controllers/time_tracking/timelogs_controller.rb` | コントローラ | リクエスト処理、フィーチャーフラグ確認 |
| index.html.haml | `app/views/time_tracking/timelogs/index.html.haml` | ビュー | 画面テンプレート |
| timelog.rb | `app/models/timelog.rb` | モデル | タイムログデータモデル |
| timelogs_app.vue | `app/assets/javascripts/time_tracking/components/timelogs_app.vue` | Vue | メインコンポーネント |
| timelogs_table.vue | `app/assets/javascripts/time_tracking/components/timelogs_table.vue` | Vue | テーブル表示コンポーネント |
| timelog_source_cell.vue | `app/assets/javascripts/time_tracking/components/timelog_source_cell.vue` | Vue | ソースリンクセル |
| index.js | `app/assets/javascripts/pages/time_tracking/timelogs/index.js` | JavaScript | エントリポイント |
| routes.rb | `config/routes.rb` | ルーティング | URLルート定義 |
