# 非機能要件定義書

## 概要

本ドキュメントは、Fat Free CRM（バージョン0.25.0）の非機能要件を定義するものです。Fat Free CRMは、Ruby on Rails 7.x系で構築されたオープンソースのCRM（顧客関係管理）システムであり、本書ではコードベースの解析に基づいて、性能、可用性、セキュリティ、拡張性、保守性、運用・監視の各観点から要件を記載しています。

## 性能要件

### レスポンスタイム

| 処理種別 | 目標値 | 備考 |
| --- | --- | --- |
| 画面表示 | 3秒以内 | 標準的なCRUD操作（Account/Contact/Lead/Opportunity/Campaign） |
| API応答 | 1秒以内 | JSON/XML形式のレスポンス |
| オートコンプリート検索 | 500ms以内 | `limit(10)`による結果制限あり（`app/controllers/application_controller.rb:41`） |

### スループット

| 項目 | 目標値 | 備考 |
| --- | --- | --- |
| 同時接続数 | 設定依存 | Puma/Passengerなどのアプリケーションサーバー設定に依存 |
| 秒間リクエスト数 | 設定依存 | データベースプール数、アプリケーションサーバー設定に依存 |

### キャッシュ設定

| 環境 | キャッシュ方式 | 設定ファイル |
| --- | --- | --- |
| 開発環境 | `:memory_store`（トグル方式） | `config/environments/development.rb:32` |
| テスト環境 | `:null_store` | `config/environments/test.rb:31` |
| 本番環境 | 未設定（`mem_cache_store`推奨） | `config/environments/production.rb:52`（コメントアウト） |

- 本番環境ではアクションキャッシュが有効化されている（`config.action_controller.perform_caching = true`）
- アセットは圧縮・ダイジェスト化される（`config/environments/production.rb:29,35`）
- Cache-Controlヘッダー: テスト環境で`max-age=3600`、開発環境で`max-age=172800`（2日間）

### WebSocket/Action Cable

| 環境 | アダプター | 備考 |
| --- | --- | --- |
| 開発環境 | async | `config/cable.yml:2` |
| テスト環境 | test | `config/cable.yml:5` |
| 本番環境 | Redis | `config/cable.yml:8`、`REDIS_URL`環境変数または`redis://localhost:6379/1` |

## 可用性要件

| 項目 | 目標値 | 備考 |
| --- | --- | --- |
| 稼働率 | 設定依存 | インフラストラクチャ構成に依存（明示的な設定なし） |
| 計画停止時間 | 設定依存 | Capistranoによるデプロイ時の再起動（`config/deploy.example.rb`） |
| 障害復旧時間（RTO） | 設定依存 | バックアップ・リストア戦略に依存 |
| 目標復旧時点（RPO） | 設定依存 | データベースバックアップ頻度に依存 |

### データベースサポート

- PostgreSQL（推奨、デフォルト）: `config/database.postgres.yml`
- MySQL: `config/database.mysql.yml`
- SQLite: `config/database.sqlite.yml`（開発・テスト用）

### ストレージ

| 環境 | ストレージサービス | 備考 |
| --- | --- | --- |
| ローカル | Disk | `config/storage.yml:5-7` |
| クラウド（オプション） | S3/GCS/Azure | `config/storage.yml`（コメントアウト、設定可能） |

## セキュリティ要件

### 認証・認可

| 機能 | 実装 | 設定ファイル/コード |
| --- | --- | --- |
| 認証フレームワーク | Devise 4.6+ | `config/initializers/devise.rb` |
| パスワード暗号化 | Authlogic SHA512（stretches: 20） | `config/initializers/devise.rb:232-233` |
| パスワード長 | 8〜128文字 | `config/initializers/devise.rb:170` |
| パスワードリセット有効期限 | 6時間 | `config/initializers/devise.rb:216` |
| Remember Me無効化 | サインアウト時に全トークン無効化 | `config/initializers/devise.rb:159` |
| HTTP認証スキップ | セッションストレージ | `config/initializers/devise.rb:95` |
| メール変更確認 | 再確認必須 | `config/initializers/devise.rb:149` |
| 認可フレームワーク | CanCanCan 3.3+ | `app/models/users/ability.rb` |

### 認可ルール

| 対象 | ルール | コード参照 |
| --- | --- | --- |
| ユーザー | 自身のプロファイルを管理可能 | `app/models/users/ability.rb:21` |
| タスク | 作成者/担当者/完了者が管理可能 | `app/models/users/ability.rb:24-27` |
| エンティティ（Account等） | Public/作成者/担当者が管理可能 | `app/models/users/ability.rb:30-32` |
| 管理者 | 全リソースを管理可能 | `app/models/users/ability.rb:39` |
| グループ権限 | Permission テーブルによる制御 | `app/models/users/ability.rb:43-53` |

### CSRF対策

| 対策 | 実装 | コード参照 |
| --- | --- | --- |
| CSRF保護 | `protect_from_forgery with: :exception` | `app/controllers/application_controller.rb:9` |
| 不正リクエスト処理 | `InvalidAuthenticityToken`例外発生 | `app/controllers/application_controller.rb:81-83` |

### セッション管理

| 項目 | 設定値 | 設定ファイル |
| --- | --- | --- |
| セッションストア | Cookie Store | `config/initializers/session_store.rb:10` |
| セッションキー | `_fat_free_crm_session` | `config/initializers/session_store.rb:10` |
| シークレットキー | 動的生成 | `config/initializers/secret_token.rb` |

### ログフィルタリング

| フィルタ対象 | 設定ファイル |
| --- | --- |
| `password`, `encrypted_password`, `password_salt`, `password_confirmation` | `config/application.rb:79` |
| `passw`, `secret`, `token`, `_key`, `crypt`, `salt`, `certificate`, `otp`, `ssn` | `config/initializers/filter_parameter_logging.rb:8-10` |

### CORS設定

| ヘッダー | 値 | コード参照 |
| --- | --- | --- |
| Access-Control-Allow-Origin | `*` | `app/controllers/application_controller.rb:238` |
| Access-Control-Allow-Methods | POST, GET, PUT, DELETE, OPTIONS | `app/controllers/application_controller.rb:239` |
| Access-Control-Allow-Headers | Origin, Content-Type, Accept, Authorization, Token | `app/controllers/application_controller.rb:240` |
| Access-Control-Max-Age | 1728000秒（20日） | `app/controllers/application_controller.rb:241` |

### コンテンツセキュリティポリシー

- CSP設定は`config/initializers/content_security_policy.rb`に定義されているが、現在はコメントアウト状態
- Permissions Policyも`config/initializers/permissions_policy.rb`にテンプレートがあるが未設定

### ユーザーサインアップ制御

| 設定値 | 動作 | 設定ファイル |
| --- | --- | --- |
| `:not_allowed`（デフォルト） | 管理者のみユーザー追加可能 | `config/settings.default.yml:137` |
| `:allowed` | 自由登録可能 | - |
| `:needs_approval` | 登録後承認必要 | - |

## 拡張性要件

### プラグインアーキテクチャ

- Railsエンジン形式でのプラグイン拡張をサポート
- `config/autoload_paths`によるモデル/コントローラーの自動読み込み
- Hook機構によるコントローラー拡張（`app/controllers/application_controller.rb:17-18`）
- ActiveSupport Load Hooks: `fat_free_crm_application_controller`, `fat_free_crm_user`, `fat_free_crm_ability`

### カスタムフィールド

- 動的なカスタムフィールド追加機能（`app/models/fields/`）
- フィールドグループによる整理

### 国際化（i18n）

| 項目 | 設定 | 備考 |
| --- | --- | --- |
| デフォルトロケール | `en-US` | `config/settings.default.yml:62` |
| ユーザー別ロケール | 設定可能（デフォルト無効） | `config/settings.default.yml:117` |
| フォールバック | 有効（本番環境） | `config/environments/production.rb:62` |

### データベース対応

- 複数データベースエンジンサポート（PostgreSQL、MySQL、SQLite）
- マイグレーションによるスキーマ管理

## 保守性要件

### バージョン管理・監査証跡

| 機能 | 実装 | 備考 |
| --- | --- | --- |
| 変更履歴追跡 | PaperTrail 15.1.0 | 全エンティティで有効化 |
| 追跡対象 | Account, Campaign, Contact, Lead, Opportunity, Task, User等 | `app/models/`配下 |
| 除外フィールド | `last_sign_in_at`（User） | `app/models/users/user.rb:67` |

### オブザーバー

| オブザーバー | 監視対象 | ファイル |
| --- | --- | --- |
| LeadObserver | Lead | `app/models/observers/lead_observer.rb` |
| OpportunityObserver | Opportunity | `app/models/observers/opportunity_observer.rb` |
| TaskObserver | Task | `app/models/observers/task_observer.rb` |
| EntityObserver | 全エンティティ | `app/models/observers/entity_observer.rb` |

### コード品質

| ツール | 用途 | 設定 |
| --- | --- | --- |
| RuboCop | 静的解析 | `Gemfile:69-74` |
| Brakeman | セキュリティスキャン | `Gemfile:57` |
| RSpec | テストフレームワーク | `Gemfile:63` |
| FactoryBot | テストデータ生成 | `Gemfile:68` |

### Ruby/Rails要件

| 項目 | バージョン | 設定ファイル |
| --- | --- | --- |
| Ruby | 3.1以上 | `fat_free_crm.gemspec:15` |
| Rails | 7.1.0〜7.3.0 | `fat_free_crm.gemspec:18` |
| Rails設定デフォルト | 7.0 | `config/application.rb:33` |

## 運用・監視要件

### ログ設定

| 環境 | ログレベル | 追加設定 |
| --- | --- | --- |
| 開発環境 | debug（デフォルト） | `verbose_query_logs: true`（`development.rb:61`） |
| テスト環境 | debug（デフォルト） | - |
| 本番環境 | `:info` | `config/environments/production.rb:46` |

### デプロイ

| 項目 | ツール/設定 | 備考 |
| --- | --- | --- |
| デプロイツール | Capistrano | `Gemfile:47-50`, `config/deploy.example.rb` |
| アプリケーションサーバー | Puma | `Gemfile:76,94` |
| アセットプリコンパイル | Sprockets | `config/environments/production.rb:32` |

### メール設定

| 項目 | 設定 | 備考 |
| --- | --- | --- |
| SMTP設定 | `config/settings.default.yml:68-75` | 環境変数/設定ファイルで指定 |
| IMAPドロップボックス | `config/settings.default.yml:80-93` | メール取り込み機能用 |
| Mailerクラス | DeviseMailer | `config/initializers/devise.rb:28` |

### 設定管理

| 優先度 | 設定ソース | 備考 |
| --- | --- | --- |
| 1（低） | `config/settings.default.yml` | デフォルト設定 |
| 2 | `config/settings.yml` | カスタム設定（オーバーライド） |
| 3（高） | `settings`テーブル | データベース設定 |

### Herokuサポート

- `rails_12factor` gem による Heroku対応（`Gemfile:92-94`）
- 環境変数による設定（`REDIS_URL`等）

## 備考

### 未設定/推奨設定項目

以下の項目はコードベースでコメントアウトまたは未設定となっており、本番環境での適切な設定を推奨します：

1. **SSL強制**: `config.force_ssl = true`（`production.rb:42`、コメントアウト）
2. **セッションタイムアウト**: `config.timeout_in = 30.minutes`（`devise.rb:180`、コメントアウト）
3. **アカウントロック**: `config.lock_strategy = :failed_attempts`（`devise.rb:186`、コメントアウト）
4. **Content Security Policy**: `content_security_policy.rb`（全体がコメントアウト）
5. **Permissions Policy**: `permissions_policy.rb`（全体がコメントアウト）
6. **本番キャッシュストア**: `config.cache_store = :mem_cache_store`（`production.rb:52`、コメントアウト）
7. **レートリミット**: 実装なし（追加を推奨）

### 対応フォーマット

| フォーマット | 対応アクション | コード参照 |
| --- | --- | --- |
| HTML | index, show, auto_complete | `app/controllers/application_controller.rb:24` |
| JS | 全アクション | `app/controllers/application_controller.rb:25` |
| JSON/XML | edit以外 | `app/controllers/application_controller.rb:26` |
| ATOM/CSV/RSS/XLS | index | `app/controllers/application_controller.rb:27` |
