# 機能設計書 F080-求人管理

## 概要

本ドキュメントは、AureusERPの採用管理モジュールにおける求人管理機能の詳細設計を記述します。求人管理は、組織の人材採用ニーズを定義し、求人情報を管理するための機能です。

### 本機能の処理概要

求人管理機能は、組織の採用計画に基づく求人ポジションを作成・管理するための機能です。

**業務上の目的・背景**：企業の採用活動において、求人情報の明確な定義と管理は不可欠です。職種、部門、採用目標人数、必要スキル、雇用形態などを定義し、計画的な採用活動を実現します。

**機能の利用シーン**：人事担当者が新規ポジションを作成する際、既存求人の内容を更新する際、または採用進捗を確認する際に利用されます。

**主要な処理内容**：
1. 求人の一覧表示・検索・フィルタリング・グルーピング
2. 新規求人の作成（職種名、部門、会社、リクルーター、面接官）
3. 求人要件の定義（職務内容、応募要件、必要スキル）
4. 採用計画の設定（採用目標人数、募集期間）
5. 求人の有効/無効切り替え
6. 求人の削除（論理削除）・復元

**関連システム・外部連携**：部門管理（Department）、会社管理（Company）、雇用形態管理（EmploymentType）、スキル管理（Skill）、応募者管理（Applicant）と連携します。

**権限による制御**：採用担当者以上の権限を持つユーザーが求人情報の管理が可能です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| SCR-REC-002 | JobPositionResource | 主画面 | 求人のCRUD操作 |
| SCR-EMP-002 | DepartmentResource | 参照画面 | 部門情報の参照 |
| SCR-REC-001 | ApplicantResource | 参照画面 | 応募者情報の参照 |

## 機能種別

CRUD操作 / マスタ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | 職種名 | 最大255文字 |
| department_id | integer | No | 部門ID | 存在する部門IDを参照 |
| company_id | integer | No | 会社ID | 存在する会社IDを参照 |
| manager_id | integer | No | マネージャーID | 存在する従業員IDを参照 |
| recruiter_id | integer | No | リクルーターID | 存在するユーザーIDを参照 |
| address_id | integer | No | 勤務地ID | 存在する住所IDを参照 |
| industry_id | integer | No | 業界ID | 存在する業界IDを参照 |
| employment_type_id | integer | No | 雇用形態ID | 存在する雇用形態IDを参照 |
| no_of_recruitment | integer | No | 採用目標人数 | 0以上 |
| date_from | date | No | 募集開始日 | |
| date_to | date | No | 募集終了日 | |
| description | text | No | 職務内容 | リッチテキスト |
| requirements | text | No | 応募要件 | リッチテキスト |
| is_active | boolean | No | 有効/無効フラグ | |

### 入力データソース

画面フォーム入力（Filament Form）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | integer | 求人ID |
| name | string | 職種名 |
| department | object | 部門情報 |
| company | object | 会社情報 |
| manager | object | マネージャー情報 |
| recruiter | object | リクルーター情報 |
| interviewers | array | 面接官情報（複数） |
| address | object | 勤務地情報 |
| industry | object | 業界情報 |
| employmentType | object | 雇用形態情報 |
| skills | array | 必要スキル |
| no_of_recruitment | integer | 採用目標人数 |
| no_of_employee | integer | 現在従業員数（計算値） |
| no_of_hired_employee | integer | 採用済み人数（計算値） |
| expected_employees | integer | 期待従業員数（計算値） |
| date_from | date | 募集開始日 |
| date_to | date | 募集終了日 |
| description | text | 職務内容 |
| requirements | text | 応募要件 |
| is_active | boolean | 有効/無効状態 |
| createdBy | object | 作成者情報 |
| created_at | datetime | 作成日時 |
| updated_at | datetime | 更新日時 |

### 出力先

画面表示（Filament Table/Infolist）、データベーステーブル（employees_job_positions）

## 処理フロー

### 処理シーケンス

```
1. ユーザー認証確認
   └─ 未認証の場合はログイン画面へリダイレクト
2. 権限チェック
   └─ 求人管理権限の有無を確認
3. 一覧表示処理
   └─ フィルタ・ソート条件に基づきデータ取得
   └─ 従業員数・採用済み人数の計算
4. CRUD操作
   └─ 作成：バリデーション → 保存 → 通知
   └─ 更新：存在確認 → バリデーション → 保存 → キャッシュクリア → 通知
   └─ 削除：存在確認 → 論理削除 → 通知
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{認証済み?}
    B -->|No| C[ログイン画面へ]
    B -->|Yes| D{権限確認}
    D -->|権限なし| E[403エラー]
    D -->|権限あり| F[一覧表示]
    F --> G{操作選択}
    G -->|作成| H[入力フォーム表示]
    G -->|編集| I[編集フォーム表示]
    G -->|削除| J[削除確認]
    G -->|表示| K[詳細表示]
    H --> L{バリデーション}
    I --> L
    L -->|OK| M[DB保存]
    L -->|NG| N[エラー表示]
    M --> O[キャッシュクリア]
    O --> P[成功通知]
    J --> Q[論理削除]
    Q --> P
    P --> F
    K --> F
    N --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-080-01 | 論理削除 | 削除時は論理削除（SoftDeletes） | 削除操作時 |
| BR-080-02 | 部門連携 | 部門選択時、マネージャーと会社を自動設定 | 部門選択時 |
| BR-080-03 | 従業員数計算 | no_of_employee = 該当職種のアクティブ従業員数 | 一覧・詳細表示時 |
| BR-080-04 | 採用済み数計算 | no_of_hired_employee = date_closedが設定されアクティブな応募者数 | 一覧・詳細表示時 |
| BR-080-05 | 期待従業員数計算 | expected_employees = no_of_employee + no_of_recruitment | 一覧・詳細表示時 |
| BR-080-06 | キャッシュ管理 | 更新時に従業員数・採用済み数のキャッシュをクリア | 更新時 |
| BR-080-07 | 並び替え機能 | 表示順序のドラッグ&ドロップ並び替え | 一覧表示時 |

### 計算ロジック

- no_of_employee = employees().where('is_active', true).count()
- no_of_hired_employee = applications().whereNotNull('date_closed').where('is_active', true).count()
- expected_employees = no_of_employee + no_of_recruitment

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧取得 | employees_job_positions | SELECT | 求人一覧の取得 |
| 詳細取得 | employees_job_positions | SELECT | 単一求人の取得 |
| 作成 | employees_job_positions | INSERT | 新規求人の登録 |
| 更新 | employees_job_positions | UPDATE | 求人情報の更新 |
| 削除 | employees_job_positions | UPDATE | 論理削除（deleted_at更新） |
| 復元 | employees_job_positions | UPDATE | 復元（deleted_at = NULL） |

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

#### employees_job_positions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | ユーザー入力値 | 必須 |
| INSERT | department_id | ユーザー選択値 | 任意 |
| INSERT | company_id | ユーザー選択値 | 任意 |
| INSERT | manager_id | ユーザー選択値または部門から継承 | 任意 |
| INSERT | recruiter_id | ユーザー選択値 | 任意 |
| INSERT | address_id | ユーザー選択値 | 任意 |
| INSERT | industry_id | ユーザー選択値 | 任意 |
| INSERT | employment_type_id | ユーザー選択値 | 任意 |
| INSERT | no_of_recruitment | ユーザー入力値（デフォルト: 0） | |
| INSERT | description | ユーザー入力値 | リッチテキスト |
| INSERT | requirements | ユーザー入力値 | リッチテキスト |
| INSERT | is_active | ユーザー選択値 | |
| UPDATE | sort | ドラッグ&ドロップで更新 | 並び替え時 |
| UPDATE | deleted_at | 現在日時 | 削除時 |
| UPDATE | deleted_at | NULL | 復元時 |

#### recruitments_job_position_interviewers（中間テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | job_position_id | 求人ID | |
| INSERT | user_id | ユーザーID | 面接官 |

#### job_position_skills（中間テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | job_position_id | 求人ID | |
| INSERT | skill_id | スキルID | 必要スキル |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-080-01 | バリデーションエラー | 職種名未入力 | エラーメッセージ表示 |
| E-080-02 | 認証エラー | 未ログイン状態 | ログイン画面へリダイレクト |
| E-080-03 | 権限エラー | 操作権限なし | 403エラーページ表示 |
| E-080-04 | 存在エラー | 対象レコード不存在 | 404エラーページ表示 |

### リトライ仕様

データベース接続エラー時は自動リトライ（Laravel標準機能）

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

単一テーブル操作のため、個別操作ごとのトランザクション管理（Laravel Eloquent標準）

## パフォーマンス要件

- 一覧取得：1秒以内
- 単一操作（CRUD）：500ms以内
- ページネーション対応

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

- 認証必須（Filament認証）
- CSRF対策（Laravel標準）
- XSS対策（Blade自動エスケープ）
- 権限制御（Filament Shield）

## 備考

- Filament v3を使用したリソース管理
- SoftDeletesトレイトによる論理削除対応（親クラスBaseJobPosition）
- 員数管理のためのカスタムAttribute（no_of_employee, no_of_hired_employee, expected_employees）
- キャッシュ機能による集計値のパフォーマンス最適化
- boot()メソッドによる更新時キャッシュクリア
- reorderable機能による表示順序の管理
- 面接官・スキルの多対多リレーション
- 削除済み会社は選択肢に表示されるが選択不可
- グローバル検索結果での詳細情報表示（名前、部門、雇用形態、会社、作成者）
