# 帳票設計書 7-アクティビティ一覧

## 概要

本ドキュメントは、Fat Free CRMシステムにおけるアクティビティ（変更履歴）データのエクスポート帳票に関する設計仕様書です。ダッシュボードに表示されるアクティビティログ（エンティティの作成・更新・削除履歴）をXLS形式で出力する機能について記述します。

### 本帳票の処理概要

アクティビティ一覧エクスポート機能は、システムに記録された変更履歴データを一括でダウンロードし、監査証跡の確認やユーザー活動の分析を可能にする帳票出力機能です。

**業務上の目的・背景**：CRMシステムにおけるデータ変更の追跡は、コンプライアンス・監査対応、業務改善のためのユーザー行動分析に重要です。本帳票により、「いつ」「誰が」「何を」「どのように」変更したかの履歴を一括取得し、監査対応資料の作成、不正操作の検出、ユーザー活動量の分析、データ変更のトレンド把握など、ガバナンス・分析ニーズに対応します。PaperTrail gemを基盤とした変更追跡により、詳細な変更内容（object_changes）も含まれます。

**帳票の利用シーン**：内部監査・外部監査対応時、セキュリティインシデント調査時、ユーザー活動レポート作成時、データ変更のデバッグ時に利用されます。

**主要な出力内容**：
1. アクティビティ基本情報（ID、アイテムタイプ、アイテムID、イベント種別）
2. 操作者情報（whodunnit：操作を行ったユーザー）
3. 変更内容（object：変更後の状態、object_changes：変更差分）
4. 関連情報（related_id、related_type：関連エンティティ）
5. トランザクション情報（transaction_id）

**帳票の出力タイミング**：ダッシュボード（ホーム画面）において、ユーザーがエクスポートボタンをクリックした際にリアルタイムで生成・ダウンロードされます。

**帳票の利用者**：システム管理者、監査担当者、コンプライアンス担当者、セキュリティ担当者

## 帳票種別

一覧表（監査ログエクスポート帳票）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | ダッシュボード | / | XLSエクスポートリンク |
| - | ダッシュボード | /home.xls | XLS形式でダウンロード |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | XLS（Excel XML Spreadsheet） |
| 用紙サイズ | 該当なし（データエクスポート） |
| 向き | 該当なし |
| ファイル名 | home.xls（activities） |
| 出力方法 | ダウンロード |
| 文字コード | UTF-8 |

### Excel固有設定

| 項目 | 内容 |
|-----|------|
| シート名 | Dashboard（I18n.t(:tab_dashboard)による国際化対応） |
| 保護設定 | 無 |

## 帳票レイアウト

### レイアウト概要

XLS形式のスプレッドシートとして、1行目にヘッダー、2行目以降にデータ行が続く標準的な表形式レイアウトです。

```
┌─────────────────────────────────────┐
│         ヘッダー行（項目名）          │
├─────────────────────────────────────┤
│         データ行1                    │
│         データ行2                    │
│         ...                         │
│         データ行N                    │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Id | バージョンID | versions.id | Number |
| 2 | Item type | アイテムタイプ | versions.item_type | String |
| 3 | Item | アイテムID | versions.item_id | Number |
| 4 | Event | イベント種別 | versions.event | String |
| 5 | Whodunnit | 操作者ID | versions.whodunnit | String |
| 6 | Object | 変更後オブジェクト | versions.object | String |
| 7 | Created at | 作成日時 | versions.created_at | String |
| 8 | Object changes | 変更差分 | versions.object_changes | String |
| 9 | Related | 関連ID | versions.related_id | Number |
| 10 | Related type | 関連タイプ | versions.related_type | String |
| 11 | Transaction | トランザクションID | versions.transaction_id | String |

### 明細部

各アクティビティレコードについて、ヘッダー部と同じ順序で値を出力します。

### フッター部

なし（データ一覧のみ）

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| アセットタイプ | activity_asset設定による対象エンティティフィルタ | No |
| イベントタイプ | activity_event設定によるイベントフィルタ（create/update/destroy） | No |
| ユーザー | activity_user設定による操作者フィルタ | No |
| 期間 | activity_duration設定による期間フィルタ（デフォルト2日間） | No |
| 最大件数 | 500件 | Yes |
| アクセス権限 | visible_to(current_user)によるアクセス制御 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | created_at | 降順（最新順） |

### 改ページ条件

該当なし（全データを単一シートに出力）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| versions | アクティビティ（変更履歴）情報 | メインテーブル |
| users | ユーザー情報 | versions.whodunnit = users.id |

### テーブル別参照項目詳細

#### versions（PaperTrail）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | Id | - | 主キー |
| item_type | Item type | - | 変更対象のモデル名 |
| item_id | Item | - | 変更対象のレコードID |
| event | Event | - | create/update/destroy/view |
| whodunnit | Whodunnit | - | 操作者のユーザーID（文字列） |
| object | Object | - | 変更後のシリアライズされたオブジェクト |
| object_changes | Object changes | - | 変更差分（YAML形式） |
| created_at | Created at | - | 変更日時 |
| related_id | Related | - | 関連エンティティID |
| related_type | Related type | - | 関連エンティティタイプ |
| transaction_id | Transaction | - | トランザクションID |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| データ型判定 | value.respond_to?(:abs) ? 'Number' : 'String' | - | セルのデータ型を動的に判定 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[XLSエクスポート要求] --> B[HomeController#index]
    B --> C[get_activities]
    C --> D[Version.latest]
    D --> E[visible_to フィルタ]
    E --> F[index.xls.builder実行]
    F --> G[XMLWorkbook生成]
    G --> H[ファイルダウンロード]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | @activities.empty? | 空のワークシートが出力される | ヘッダー・データ行とも出力されない |
| 認証エラー | 未ログイン | ログイン画面へリダイレクト | ログイン後に再実行 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 最大500件（上限設定） |
| 目標出力時間 | 3秒以内 |
| 同時出力数上限 | 明示的な制限なし |

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

- visible_toメソッドによりユーザーがアクセス権を持つエンティティの変更履歴のみ表示
- 認証が必要（authenticate_user!）
- objectフィールドには変更後のデータ全体が含まれる可能性があるため、取り扱い注意
- object_changesにはパスワード等の機密情報が含まれる可能性があるため、取り扱い注意
- whodunnitには操作者のユーザーIDが記録され、監査証跡として機能

## 備考

- 国際化対応：ヘッダーラベルは固定英語（シート名のみI18n対応）
- PaperTrail gemによる変更追跡機能を基盤としている
- event種別：create（作成）、update（更新）、destroy（削除）、view（閲覧）
- デフォルトの期間フィルタは2日間（activity_duration）
- 最大取得件数は500件に制限
- CSV出力は未対応（XLSのみ）

---

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

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

### 推奨読解順序

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

まず、バージョン（アクティビティ）エンティティの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | version.rb | `app/models/polymorphic/version.rb` | Versionモデルの定義、PaperTrail::Versionの継承、latestスコープ、visible_toメソッドを確認 |

**読解のコツ**: ASSETS/EVENTS/DURATION定数、latestクラスメソッド（46-54行目）のフィルタリングロジック、visible_toメソッド（65-82行目）のアクセス制御に注目

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

処理の起点となるコントローラーを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | home_controller.rb | `app/controllers/home_controller.rb` | indexアクション（13-21行目）、get_activitiesメソッド（101-109行目）を確認 |
| 2-2 | application_controller.rb | `app/controllers/application_controller.rb` | 認証フィルタを確認 |

**主要処理フロー**:
1. **14行目**: get_activitiesでアクティビティ取得
2. **19行目**: XLS出力時はheaderレイアウトを使用
3. **101-109行目**: get_activitiesでフィルタ条件を設定しVersion.latest呼び出し

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

XLS出力の実際の処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.xls.builder | `app/views/home/index.xls.builder` | ヘッダー定義（8-18行目）、アクティビティデータ出力（28-50行目） |
| 3-2 | header.xls.builder | `app/views/layouts/header.xls.builder` | XMLワークブック構造の定義 |

**主要処理フロー**:
- **7-26行目**: ヘッダー行の生成（固定英語ラベル）
- **28-50行目**: データ行の生成
- **30-40行目**: activity（Version）の各属性を出力

#### Step 4: フィルタリングロジックを理解する

アクティビティの取得・フィルタリング処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | home_controller.rb | `app/controllers/home_controller.rb` | activity_asset/activity_event/activity_user/activity_durationメソッド（112-167行目） |
| 4-2 | version.rb | `app/models/polymorphic/version.rb` | latestスコープ、visible_toメソッド |

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

```
HTTP Request (GET /home.xls)
    │
    ├─ ApplicationController (認証チェック)
    │      └─ authenticate_user!
    │
    ├─ HomeController#index
    │      └─ get_activities
    │             │
    │             ├─ activity_asset (アセットフィルタ)
    │             ├─ activity_event (イベントフィルタ)
    │             ├─ activity_user (ユーザーフィルタ)
    │             └─ activity_duration (期間フィルタ)
    │
    └─ Version.latest(options)
           │
           ├─ includes(:item, :related, :user)
           ├─ where(item_type: options[:asset])
           ├─ where(event: options[:event])
           ├─ where(whodunnit: options[:user])
           ├─ where('created_at >= ?', Time.zone.now - duration)
           └─ limit(500)
                  │
                  └─ .visible_to(current_user)
                         │
                         └─ アクセス権フィルタリング
    │
    └─ home/index.xls.builder (ビュー)
           ├─ header.xls.builder (レイアウト)
           │
           ├─ @activities.each (データイテレーション)
           │      ├─ activity.id
           │      ├─ activity.item_type
           │      ├─ activity.event
           │      ├─ activity.whodunnit
           │      ├─ activity.object
           │      └─ activity.object_changes
           │
           └─ XMLセル出力
```

### データフロー図

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

Request             HomeController            Response
/home.xls      ───▶ #index                ───▶ home.xls
                         │
                         ▼
                    get_activities
                         │
                         ├─ options設定
                         │    ├─ asset: activity_asset
                         │    ├─ event: activity_event
                         │    ├─ user: activity_user
                         │    ├─ duration: activity_duration
                         │    └─ max: 500
                         │
                         ▼
                    Version.latest(options)
                         │
                         ├─ フィルタリング
                         │
                         ▼
                    .visible_to(current_user)
                         │
                         ├─ アクセス権チェック
                         │
                         ▼
                    @activities (Array)
                         │
                         ▼
                    index.xls.builder
                         │
                         ▼
                    XML生成 (Builder)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| version.rb | `app/models/polymorphic/version.rb` | ソース | Versionモデル定義（PaperTrail拡張） |
| home_controller.rb | `app/controllers/home_controller.rb` | ソース | ホームコントローラー |
| application_controller.rb | `app/controllers/application_controller.rb` | ソース | 基底コントローラー |
| index.xls.builder | `app/views/home/index.xls.builder` | テンプレート | XLS出力ビュー |
| header.xls.builder | `app/views/layouts/header.xls.builder` | テンプレート | XLSレイアウト |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（11行目：root） |
