# 画面設計書 31-システム概要画面

## 概要

本ドキュメントはInvenTreeシステムにおけるシステム概要画面（CoreIndex）の設計仕様を記載したものである。本画面はシステム全体のユーザー、グループ、連絡先情報を一元管理するためのコア管理画面である。

### 本画面の処理概要

本画面はシステム管理者およびログイン済みユーザーが、組織内のユーザーアカウント、グループ、連絡先情報を一覧形式で確認・管理するための画面である。

**業務上の目的・背景**：企業における在庫管理システムでは、複数のユーザーが異なる役割と権限を持って運用に携わる。本画面は、ユーザーアカウントの一覧把握、グループによる権限管理、取引先担当者（連絡先）の管理を一箇所で行えるようにすることで、システム運用の効率化を実現する。特に、ユーザーの所属グループ確認やアクティブ状態の把握、連絡先情報の検索などの日常的な管理業務を支援する。

**画面へのアクセス方法**：ログイン後、ナビゲーションメニューから「コア」または「Core」を選択してアクセスする。URLパスは `/core/index/*` である。また、管理センターからユーザー管理を選択した際にも本画面への遷移が行われる。

**主要な操作・処理内容**：
1. ユーザー一覧タブでシステム登録済みの全ユーザーを確認する
2. ユーザー行をクリックまたは編集アイコンでユーザー詳細画面へ遷移する
3. グループ一覧タブでシステム登録済みの全グループを確認する
4. グループ行をクリックでグループ詳細画面へ遷移する
5. 連絡先一覧タブで取引先連絡先情報を確認する
6. 各一覧でフィルタリング、ソート、ページネーションを行う

**画面遷移**：
- 遷移元：ホーム画面、管理センター画面
- 遷移先：ユーザー詳細画面（`/core/user/:id/`）、グループ詳細画面（`/core/group/:id/`）

**権限による表示制御**：本画面はログイン済みユーザーのみアクセス可能。未ログイン状態では「PermissionDenied」コンポーネントが表示される。ユーザーテーブルの編集操作はスタッフ権限かつadminロールの変更権限を持つユーザーのみ可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | ユーザーアカウント管理 | 主機能 | ユーザー一覧の表示 |
| 35 | 権限・ロール管理 | 補助機能 | グループ一覧の表示 |
| 26 | 住所・連絡先管理 | 補助機能 | 連絡先一覧の表示 |

## 画面種別

一覧画面（タブ切り替え式パネルグループ）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/core/` | インデックスへリダイレクト |
| `/core/index/` | システム概要画面（デフォルトパネル） |
| `/core/index/users/` | ユーザータブ表示 |
| `/core/index/groups/` | グループタブ表示 |
| `/core/index/contacts/` | 連絡先タブ表示 |

## 入出力項目

本画面は主に表示専用であり、ユーザー入力は以下のフィルタ項目のみ。

### ユーザーテーブルフィルタ

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| is_active | 入力 | boolean | - | アクティブユーザーのみ表示 |
| is_staff | 入力 | boolean | - | スタッフユーザーのみ表示 |
| is_superuser | 入力 | boolean | - | スーパーユーザーのみ表示 |

## 表示項目

### ユーザー一覧タブ（UserTable）

| 項目名 | データ型 | ソート | 切替 | 説明 |
|--------|----------|--------|------|------|
| username | string | 可 | 不可 | ユーザー名（ログインID） |
| first_name | string | 可 | 可 | 名 |
| last_name | string | 可 | 可 | 姓 |
| email | string | 可 | 可 | メールアドレス |
| groups | number | 可 | 可 | 所属グループ数 |
| is_staff | boolean | - | 可 | スタッフフラグ |
| is_superuser | boolean | - | 可 | スーパーユーザーフラグ |
| is_active | boolean | - | 可 | アクティブフラグ |

### グループ一覧タブ（GroupTable）

| 項目名 | データ型 | ソート | 切替 | 説明 |
|--------|----------|--------|------|------|
| name | string | 可 | 不可 | グループ名 |

### 連絡先一覧タブ（ContactTable）

| 項目名 | データ型 | ソート | 切替 | 説明 |
|--------|----------|--------|------|------|
| company_name | string | - | 可 | 会社名 |
| name | string | 可 | 不可 | 連絡先名 |
| phone | string | - | 可 | 電話番号 |
| email | string | - | 可 | メールアドレス |
| role | string | - | 可 | 役職・役割 |

## イベント仕様

### 1-タブ切り替え

**トリガー**：各タブ（Users/Groups/Contacts）をクリック

**処理内容**：
- PanelGroupコンポーネントがURLパラメータを更新
- 対応するテーブルコンポーネントがレンダリング
- 各テーブルのAPIからデータを取得して表示

### 2-ユーザー行クリック

**トリガー**：ユーザーテーブルの行をクリック

**前提条件**：編集可能モード（`directLink=false`かつスタッフ権限かつadmin変更権限あり）

**処理内容**：
- DetailDrawerが開く
- ユーザー詳細情報とグループ編集UIが表示される

### 3-ユーザー編集アイコンクリック

**トリガー**：ユーザー行の編集アイコンをクリック

**処理内容**：`/core/index/users/user-{pk}/`にナビゲート

### 4-ユーザープロファイル表示

**トリガー**：行アクションメニューの「Open Profile」をクリック

**処理内容**：`/core/user/{pk}/`（ユーザー詳細画面）へ遷移

### 5-グループ行クリック

**トリガー**：グループテーブルの行をクリック

**処理内容**：DetailDrawerが開き、グループ詳細と権限編集UIが表示

### 6-グループプロファイル表示

**トリガー**：行アクションメニューの「Open Profile」をクリック

**処理内容**：`/core/group/{pk}/`（グループ詳細画面）へ遷移

### 7-新規ユーザー追加

**トリガー**：「Add user」ボタンをクリック

**前提条件**：スタッフ権限かつuser追加権限あり

**処理内容**：
- 新規ユーザー作成モーダルが開く
- フォーム送信後、`POST /api/user/`でユーザー作成
- テーブルを再読み込み

### 8-新規グループ追加

**トリガー**：「Add group」ボタンをクリック

**前提条件**：group追加権限あり

**処理内容**：
- 新規グループ作成モーダルが開く
- フォーム送信後、`POST /api/user/group/`でグループ作成
- テーブルを再読み込み

### 9-連絡先追加

**トリガー**：「Add contact」ボタンをクリック

**前提条件**：purchase_orderまたはsales_orderの追加権限あり

**処理内容**：
- 新規連絡先作成モーダルが開く
- フォーム送信後、`POST /api/company/contact/`で連絡先作成
- テーブルを再読み込み

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ユーザー一覧表示 | auth_user | SELECT | 登録済みユーザーの取得 |
| グループ一覧表示 | auth_group | SELECT | 登録済みグループの取得 |
| 連絡先一覧表示 | company_contact | SELECT | 登録済み連絡先の取得 |
| 新規ユーザー追加 | auth_user | INSERT | ユーザーレコード作成 |
| 新規グループ追加 | auth_group | INSERT | グループレコード作成 |
| 新規連絡先追加 | company_contact | INSERT | 連絡先レコード作成 |
| ユーザー編集 | auth_user | UPDATE | ユーザー情報更新 |
| ユーザーグループ更新 | auth_user_groups | UPDATE | ユーザーのグループ所属更新 |
| ユーザー削除 | auth_user | DELETE | ユーザーレコード削除 |
| グループ削除 | auth_group | DELETE | グループレコード削除 |

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

#### auth_user

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全カラム | フィルタ条件に一致するレコード | ページネーション適用 |
| INSERT | username, email, first_name, last_name | フォーム入力値 | is_active=true |
| UPDATE | username, email, first_name, last_name, is_active, is_staff, is_superuser | フォーム入力値 | pk指定 |
| DELETE | - | pk指定 | 物理削除 |

#### auth_group

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | pk, name | 全レコード | ページネーション適用 |
| INSERT | name | フォーム入力値 | - |
| DELETE | - | pk指定 | 物理削除 |

#### company_contact

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | company, name, phone, email, role | フィルタ条件に一致 | company_nameはJOIN取得 |
| INSERT | company, name, phone, email, role | フォーム入力値 | - |
| UPDATE | company, name, phone, email, role | フォーム入力値 | pk指定 |
| DELETE | - | pk指定 | 物理削除 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| 成功 | User deleted | ユーザー削除成功時 |
| 成功 | Group deleted | グループ削除成功時 |
| 成功 | Added user | ユーザー追加成功時 |
| 成功 | User updated successfully | ユーザー更新成功時 |
| 成功 | Groups updated - User groups updated successfully | ユーザーグループ更新成功時 |
| エラー | Error updating user groups | グループ更新API失敗時 |
| エラー | Error updating user | ユーザー更新API失敗時 |
| 確認 | Are you sure you want to delete this user? | ユーザー削除前確認 |
| 確認 | Are you sure you want to delete this group? | グループ削除前確認 |

## 例外処理

| 例外状況 | 表示内容 | 対応処理 |
|---------|---------|---------|
| 未ログイン | PermissionDeniedコンポーネント | ログイン画面へのリンク表示 |
| ユーザーが見つからない (404) | "User with id {id} not found" | DetailDrawer内にメッセージ表示 |
| グループが見つからない (404) | "Group with id {id} not found" | DetailDrawer内にメッセージ表示 |
| API通信エラー | "An error occurred while fetching user details" | DetailDrawer内にメッセージ表示 |
| データロード中 | LoadingOverlay | スケルトン表示 |

## 備考

- UserTableとGroupTableは`directLink`プロパティにより動作が変化する。`directLink=true`の場合、行クリックで直接詳細ページへ遷移し、編集機能は無効となる
- 本画面のユーザーテーブルは`directLink=true`で設定されており、行クリックでユーザー詳細画面へ直接遷移する
- ユーザーの編集は管理センター画面（AdminCenter）のUserManagementPanelで行うことが推奨される
- 連絡先テーブルは会社詳細画面でも同様のテーブルが使用される（companyIdパラメータで絞り込み）

---

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

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

### 推奨読解順序

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

まず、画面で扱うデータの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | UserTable.tsx | `src/frontend/src/tables/settings/UserTable.tsx` | UserDetailI インターフェース（50-60行目）でユーザーデータ構造を確認 |
| 1-2 | GroupTable.tsx | `src/frontend/src/tables/settings/GroupTable.tsx` | GroupDetailI インターフェース（33-36行目）でグループデータ構造を確認 |

**読解のコツ**: TypeScriptのインターフェース定義から、APIレスポンスの構造とテーブル表示項目の対応を把握する

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

処理の起点となるページコンポーネントを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CoreIndex.tsx | `src/frontend/src/pages/core/CoreIndex.tsx` | メインコンポーネント、パネル構成の定義 |

**主要処理フロー**:
1. **14行目**: CoreIndex関数コンポーネント定義
2. **15行目**: useUserState()でユーザー認証状態を取得
3. **17-38行目**: panelsの定義（users, groups, contacts）
4. **40-42行目**: 未ログイン時のPermissionDenied表示
5. **44-49行目**: PageDetailとPanelGroupによるUI構築

#### Step 3: テーブルコンポーネントを理解する

各タブで表示されるテーブルの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | UserTable.tsx | `src/frontend/src/tables/settings/UserTable.tsx` | ユーザー一覧テーブルの実装（237-458行目） |
| 3-2 | GroupTable.tsx | `src/frontend/src/tables/settings/GroupTable.tsx` | グループ一覧テーブルの実装（127-248行目） |
| 3-3 | ContactTable.tsx | `src/frontend/src/tables/company/ContactTable.tsx` | 連絡先一覧テーブルの実装（28-186行目） |

**主要処理フロー**:
- **UserTable.tsx 255-293行目**: カラム定義
- **UserTable.tsx 298-353行目**: 行アクション定義
- **UserTable.tsx 442-456行目**: InvenTreeTableコンポーネントでの描画

#### Step 4: 編集ドロワーを理解する

行クリック時に開くサイドドロワーの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | UserTable.tsx | `src/frontend/src/tables/settings/UserTable.tsx` | UserDrawer関数（62-232行目）でユーザー編集UI |
| 4-2 | GroupTable.tsx | `src/frontend/src/tables/settings/GroupTable.tsx` | GroupDrawer関数（38-122行目）でグループ編集UI |

**主要処理フロー**:
- **UserTable.tsx 70-76行目**: useInstanceフックでユーザー詳細取得
- **UserTable.tsx 112-140行目**: グループ変更時のAPI呼び出し

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

```
CoreIndex
    │
    ├─ useUserState() ─── ユーザー認証状態確認
    │
    ├─ PanelGroup
    │      │
    │      ├─ UserTable (directLink=true)
    │      │      ├─ useTable('users')
    │      │      ├─ InvenTreeTable
    │      │      │      └─ apiUrl(ApiEndpoints.user_list)
    │      │      └─ UserDrawer (directLink=false時のみ)
    │      │             └─ useInstance(user_list)
    │      │
    │      ├─ GroupTable (directLink=true)
    │      │      ├─ useTable('groups')
    │      │      ├─ InvenTreeTable
    │      │      │      └─ apiUrl(ApiEndpoints.group_list)
    │      │      └─ GroupDrawer (directLink=false時のみ)
    │      │             └─ useInstance(group_list)
    │      │
    │      └─ ContactTable
    │             ├─ useTable('contact')
    │             └─ InvenTreeTable
    │                    └─ apiUrl(ApiEndpoints.contact_list)
    │
    └─ PageDetail ─── 画面タイトル表示
```

### データフロー図

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

ログイン状態    ───▶ useUserState()           ───▶ 認証チェック結果
                      └─ 未認証時               ───▶ PermissionDenied

タブ選択       ───▶ PanelGroup               ───▶ 選択タブのテーブル表示

API Response   ───▶ InvenTreeTable           ───▶ テーブル行表示
(user_list)          └─ columns定義           ───▶ カラム構成
                     └─ tableFilters          ───▶ フィルタUI

行クリック     ───▶ navigate(user-{pk}/)     ───▶ DetailDrawer表示
                     └─ UserDrawer
                           └─ useInstance()   ───▶ ユーザー詳細表示

グループ更新   ───▶ api.patch(user/{pk})     ───▶ 成功通知 / エラー通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CoreIndex.tsx | `src/frontend/src/pages/core/CoreIndex.tsx` | ソース | メインページコンポーネント |
| UserTable.tsx | `src/frontend/src/tables/settings/UserTable.tsx` | ソース | ユーザー一覧テーブル |
| GroupTable.tsx | `src/frontend/src/tables/settings/GroupTable.tsx` | ソース | グループ一覧テーブル |
| ContactTable.tsx | `src/frontend/src/tables/company/ContactTable.tsx` | ソース | 連絡先一覧テーブル |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義（199-204行目） |
| PanelGroup.tsx | `src/frontend/src/components/panels/PanelGroup.tsx` | ソース | タブパネル管理コンポーネント |
| PageDetail.tsx | `src/frontend/src/components/nav/PageDetail.tsx` | ソース | ページヘッダーコンポーネント |
| PermissionDenied.tsx | `src/frontend/src/components/errors/PermissionDenied.tsx` | ソース | アクセス拒否表示コンポーネント |
| ApiEndpoints.ts | `src/frontend/lib/enums/ApiEndpoints.ts` | ソース | APIエンドポイント定義 |
| UserState.ts | `src/frontend/src/states/UserState.ts` | ソース | ユーザー状態管理（Zustand） |
