ユーザー管理

概要説明

ユーザー管理機能により、管理者はシステム内のすべてのユーザーアカウントを監視できます。管理者はページ分けされたユーザーリストを表示し、様々な条件でフィルタリングやソートを行い、新しい管理者ユーザーの作成、既存のユーザー情報の更新、ユーザーステータスの変更、必要に応じたユーザーの削除などの操作を実行できます。この機能にはロールベースのアクセス制御が含まれており、特定の操作はスーパー管理者権限を持つユーザーに制限されています。

アクティビティ図

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Main components
    AdminUser[管理者ユーザー]
    AdminInterface[ユーザー管理インターフェース]
    
    %% Action components
    ActionSelect{アクション選択}
    
    %% Flow connections with numbered steps
    AdminUser --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>インターフェースにアクセス</p>
        </div>
    ]
    Step1 --> AdminInterface
    
    AdminInterface --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>アクション選択</p>
        </div>
    ]
    Step2 --> ActionSelect
    
    ActionSelect --- Step3A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3A</span>
            <p style='margin-top: 8px'>ユーザー表示</p>
        </div>
    ]
    Step3A --> ViewUsers[ユーザーリスト]
    
    ActionSelect --- Step3B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3B</span>
            <p style='margin-top: 8px'>ユーザー作成</p>
        </div>
    ]
    Step3B --> CreateForm[ユーザー作成フォーム]
    
    ActionSelect --- Step3C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3C</span>
            <p style='margin-top: 8px'>ユーザー更新</p>
        </div>
    ]
    Step3C --> EditForm[ユーザー編集フォーム]
    
    ActionSelect --- Step3D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3D</span>
            <p style='margin-top: 8px'>ステータス変更</p>
        </div>
    ]
    Step3D --> ToggleStatus[ユーザーステータス切替]
    
    ActionSelect --- Step3E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3E</span>
            <p style='margin-top: 8px'>ユーザー削除</p>
        </div>
    ]
    Step3E --> DeleteConfirm{削除確認}
    
    ViewUsers --- Step4A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4A</span>
            <p style='margin-top: 8px'>フィルター/並べ替え</p>
        </div>
    ]
    Step4A --> FilterSort[フィルター/並べ替え適用]
    
    CreateForm --- Step4B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4B</span>
            <p style='margin-top: 8px'>検証</p>
        </div>
    ]
    Step4B --> ValidateCreate{入力検証}
    
    EditForm --- Step4C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4C</span>
            <p style='margin-top: 8px'>検証</p>
        </div>
    ]
    Step4C --> ValidateEdit{入力検証}
    
    ToggleStatus --- Step4D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4D</span>
            <p style='margin-top: 8px'>DB更新</p>
        </div>
    ]
    Step4D --> UpdateStatusDB[データベースでステータス更新]
    
    DeleteConfirm --- Step4E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4E</span>
            <p style='margin-top: 8px'>レコード削除</p>
        </div>
    ]
    Step4E --> DeleteUserDB[データベースからユーザー削除]
    
    ValidateCreate --- Step5B1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5B</span>
            <p style='margin-top: 8px'>レコード作成</p>
        </div>
    ]
    Step5B1 --> CreateUserDB[データベースにユーザー作成]
    
    ValidateEdit --- Step5C1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5C</span>
            <p style='margin-top: 8px'>レコード更新</p>
        </div>
    ]
    Step5C1 --> UpdateUserDB[データベースでユーザー更新]
    
    FilterSort --- Step5A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5A</span>
            <p style='margin-top: 8px'>インターフェースに戻る</p>
        </div>
    ]
    Step5A --> AdminInterface
    
    CreateUserDB --- Step6B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6B</span>
            <p style='margin-top: 8px'>インターフェースに戻る</p>
        </div>
    ]
    Step6B --> AdminInterface
    
    UpdateUserDB --- Step6C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6C</span>
            <p style='margin-top: 8px'>インターフェースに戻る</p>
        </div>
    ]
    Step6C --> AdminInterface
    
    UpdateStatusDB --- Step5D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5D</span>
            <p style='margin-top: 8px'>インターフェースに戻る</p>
        </div>
    ]
    Step5D --> AdminInterface
    
    DeleteUserDB --- Step5E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5E</span>
            <p style='margin-top: 8px'>インターフェースに戻る</p>
        </div>
    ]
    Step5E --> AdminInterface
    
    ValidateCreate -.->|無効| CreateForm
    ValidateEdit -.->|無効| EditForm
    DeleteConfirm -.->|キャンセル| AdminInterface
    
    %% Styling
    style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style AdminInterface fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style ActionSelect fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ViewUsers fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style CreateForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style EditForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ToggleStatus fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style DeleteConfirm fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style FilterSort fill:#fff0f5,stroke:#cc6699,stroke-width:2px
    style ValidateCreate fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ValidateEdit fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style UpdateStatusDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style DeleteUserDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style CreateUserDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style UpdateUserDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3A fill:transparent,stroke:transparent,stroke-width:1px
    style Step3B fill:transparent,stroke:transparent,stroke-width:1px
    style Step3C fill:transparent,stroke:transparent,stroke-width:1px
    style Step3D fill:transparent,stroke:transparent,stroke-width:1px
    style Step3E fill:transparent,stroke:transparent,stroke-width:1px
    style Step4A fill:transparent,stroke:transparent,stroke-width:1px
    style Step4B fill:transparent,stroke:transparent,stroke-width:1px
    style Step4C fill:transparent,stroke:transparent,stroke-width:1px
    style Step4D fill:transparent,stroke:transparent,stroke-width:1px
    style Step4E fill:transparent,stroke:transparent,stroke-width:1px
    style Step5A fill:transparent,stroke:transparent,stroke-width:1px
    style Step5B1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step5C1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step5D fill:transparent,stroke:transparent,stroke-width:1px
    style Step5E fill:transparent,stroke:transparent,stroke-width:1px
    style Step6B fill:transparent,stroke:transparent,stroke-width:1px
    style Step6C fill:transparent,stroke:transparent,stroke-width:1px

API: ユーザー管理API

ケースドキュメント

ケース1: ユーザー一覧の取得

説明

管理者はオプションのフィルタリングとソートを使用して、ページ分けされたユーザーリストを取得します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Auth as 認証サービス
    participant UserService as ユーザーサービス
    participant UserRepository as ユーザーリポジトリ
    participant DB as データベース

    Note over Admin,DB: ユーザー一覧取得フロー

    rect rgb(200, 255, 200)
    Note right of Admin: 正常フロー

    Admin->>API: GET /api/admin/users (クエリパラメータ付き)
    
    rect rgb(255, 255, 200)
    Note right of API: 認証と認可
    API->>Auth: verifyAdminAccess()
    Auth-->>API: 確認結果を返す
    end
    
    rect rgb(200, 230, 255)
    Note right of API: 入力検証
    API->>API: validateRequest()
    end
    
    rect rgb(200, 255, 255)
    Note right of API: ビジネスロジック処理
    API->>UserService: getUsers(params)
    UserService->>UserRepository: list(params)
    UserRepository->>DB: SELECT * FROM users WHERE status = ? AND name LIKE ? ORDER BY ? LIMIT ? OFFSET ?
    DB-->>UserRepository: 該当ユーザーを返す
    UserRepository-->>UserService: 結果を返す
    UserService-->>API: ページ分けされた結果を返す
    end
    
    API-->>Admin: 200 OK とユーザーコレクション
    end

    rect rgb(255, 200, 200)
    Note right of Admin: エラー処理
    rect rgb(255, 230, 230)
    alt 認証エラー
        Auth-->>API: 401 Unauthorized
        API-->>Admin: 401 Unauthorized
    else 認可エラー
        Auth-->>API: 403 Forbidden
        API-->>Admin: 403 Forbidden
    else 検証エラー
        API-->>Admin: 422 Unprocessable Entity
    else データベースエラー
        DB-->>UserRepository: データベースエラー
        UserRepository-->>UserService: エラー結果
        UserService-->>API: エラー結果
        API-->>Admin: 500 Internal Server Error
    end
    end
    end

ステップ

ステップ1: ユーザーリストのリクエスト

  • 説明: 管理者はオプションのフィルタを使用してユーザーのリストをリクエスト
  • リクエスト: GET /api/admin/users
  • クエリパラメータ:
    • perpage: ページあたりのアイテム数
    • page: ページ番号
    • name: 名前でユーザーをフィルタリング
    • orderBy: 並べ替えのフィールド
    • sortBy: 並べ替えの方向(ascまたはdesc)
    • status: ステータスでユーザーをフィルタリング

ステップ2: 管理者権限の確認

  • 説明: システムはユーザーが管理者権限を持っているか確認
  • アクション: 現在のユーザーが管理者ロールを持っているか確認
  • 発生しうるエラー: 権限不足

ステップ3: ユーザーデータの取得

  • 説明: システムはフィルタに基づいてデータベースからユーザーを取得
  • アクション:
    • クエリパラメータからフィルタを適用
    • 管理者ロールレベルに基づいて結果を制限
    • 結果をページ分け

ステップ4: ユーザーリストの返却

  • 説明: ページ分けされたユーザーリストを返す
  • レスポンス:
    • 成功: 200 OKとユーザーコレクションおよびページネーションメタデータ
    • エラー: 適切なエラーメッセージ

エラー処理

  • ログ
    • ユーザーリスト取得失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    403 "ユーザーリストの取得に失敗しました。" ユーザーに管理者権限がない場合
    400 例外メッセージを含む一般的なエラー 予期しないエラーが発生した場合

ケース2: 新しい管理者ユーザーの作成

説明

スーパー管理者が新しい管理者ユーザーアカウントを作成します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Validator as フォームリクエスト
    participant Service as ユーザーサービス
    participant DB as データベース

    Note over Admin,DB: ステップ1: ユーザー作成を送信
    Admin->>API: POST /api/admin/users (user_data)
    
    Note over API,Service: ステップ2: 管理者権限の確認
    API->>API: スーパー管理者かどうか確認
    
    Note over API,Validator: ステップ3: 入力検証
    API->>Validator: StoreAdminUserRequest::validate()
    Validator-->>API: 検証済みデータを返す
    
    Note over Service,DB: ステップ4: ユーザー作成
    API->>Service: create(validated_data)
    Service->>DB: ユーザーレコードを挿入
    Service->>DB: 管理者ロールを割り当て
    DB-->>Service: 作成されたユーザーを返す
    
    Note over API,Admin: ステップ5: レスポンス返却
    Service-->>API: ユーザーデータを返す
    API-->>Admin: 200 OK (ユーザーリソース)

ステップ

ステップ1: ユーザー作成の送信

  • 説明: 管理者が新しいユーザーを作成するフォームを送信
  • リクエスト: POST /api/admin/users
  • 必須フィールド:
    • name: ユーザーのフルネーム
    • email: ユーザーのメールアドレス
    • password: ユーザーのパスワード
    • role_id: 管理者ロールID
    • status: ユーザーステータス(オプション)

ステップ2: 管理者権限の確認

  • 説明: システムはユーザーがスーパー管理者権限を持っているか確認
  • アクション: 現在のユーザーがスーパー管理者かどうか確認
  • 発生しうるエラー: 権限不足(403)

ステップ3: 入力検証

  • 説明: システムがすべての入力データを検証
  • アクション: StoreAdminUserRequestから検証ルールを実行
  • 検証ルール:
    • name: 必須
    • email: 必須、有効なメールフォーマット、usersテーブルで一意
    • password: 必須、最低8文字
    • role_id: 必須、rolesテーブルに存在する必要あり
    • status: オプション、事前定義された値のいずれかであること

ステップ4: ユーザー作成

  • 説明: システムが新しいユーザーアカウントを作成
  • アクション:
    • パスワードをハッシュ化
    • ユーザーレコードを作成
    • 管理者ロールを割り当て

ステップ5: レスポンス返却

  • 説明: 作成されたユーザーデータを返す
  • レスポンス:
    • 成功: 200 OKとユーザーデータ
    • エラー: 検証エラーを含む適切なエラーメッセージ

エラー処理

  • ログ
    • ユーザー作成失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    403 "このリソースにアクセスする権限がありません。" ユーザーがスーパー管理者でない場合
    400 "ユーザーの作成に失敗しました。" ユーザー作成が失敗した場合
    422 検証エラーメッセージ 検証ルール違反の場合
    400 "メールアドレスはすでに使用されています。" 一意のメール制約違反の場合

ケース3: 既存ユーザーの更新

説明

スーパー管理者が既存ユーザーの情報を更新します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Validator as フォームリクエスト
    participant Service as ユーザーサービス
    participant DB as データベース

    Note over Admin,DB: ステップ1: ユーザー更新を送信
    Admin->>API: PUT /api/admin/users/{id} (updated_data)
    
    Note over API,Service: ステップ2: 管理者権限の確認
    API->>API: スーパー管理者かどうか確認
    
    Note over API,Validator: ステップ3: 入力検証
    API->>Validator: UpdateAdminUserRequest::validate()
    Validator-->>API: 検証済みデータを返す
    
    Note over Service,DB: ステップ4: ユーザー更新
    API->>Service: update(id, validated_data)
    Service->>DB: ユーザーレコードを更新
    Service->>DB: ユーザーロールを更新
    DB-->>Service: 更新されたユーザーを返す
    
    Note over API,Admin: ステップ5: レスポンス返却
    Service-->>API: ユーザーデータを返す
    API-->>Admin: 200 OK (ユーザーリソース)

ステップ

ステップ1: ユーザー更新の送信

  • 説明: 管理者がユーザー情報を更新するフォームを送信
  • リクエスト: PUT /api/admin/users/{id}
  • 更新可能フィールド:
    • name: ユーザーのフルネーム
    • email: ユーザーのメールアドレス
    • role_id: 管理者ロールID
    • status: ユーザーステータス

ステップ2: 管理者権限の確認

  • 説明: システムはユーザーがスーパー管理者権限を持っているか確認
  • アクション: 現在のユーザーがスーパー管理者かどうか確認
  • 発生しうるエラー: 権限不足(403)

ステップ3: 入力検証

  • 説明: システムがすべての入力データを検証
  • アクション: UpdateAdminUserRequestから検証ルールを実行
  • 検証ルール:
    • name: 必須
    • email: 必須、有効なメールフォーマット、現在のユーザーを除いてusersテーブルで一意
    • role_id: 必須、rolesテーブルに存在する必要あり
    • status: オプション、事前定義された値のいずれかであること

ステップ4: ユーザー更新

  • 説明: システムがユーザー情報を更新
  • アクション:
    • 新しいデータでユーザーレコードを更新
    • role_idが変更された場合、ロール割り当てを更新

ステップ5: レスポンス返却

  • 説明: 更新されたユーザーデータを返す
  • レスポンス:
    • 成功: 200 OKと更新されたユーザーデータ
    • エラー: 検証エラーを含む適切なエラーメッセージ

エラー処理

  • ログ
    • ユーザー更新失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    403 "このリソースにアクセスする権限がありません。" ユーザーがスーパー管理者でない場合
    400 "ユーザーデータの更新に失敗しました。" ユーザー更新が失敗した場合
    422 検証エラーメッセージ 検証ルール違反の場合
    404 "指定されたユーザーが見つかりません。" ユーザーIDが存在しない場合

ケース4: ユーザーステータスの変更

説明

スーパー管理者がユーザーアカウントをアクティブ化または非アクティブ化します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Service as ユーザーサービス
    participant DB as データベース

    Note over Admin,DB: ステップ1: ステータス変更リクエスト
    Admin->>API: POST /api/admin/users/{id}/change-status
    
    Note over API,Service: ステップ2: 管理者権限の確認
    API->>API: スーパー管理者かどうか確認
    
    Note over Service,DB: ステップ3: ユーザーステータス切替
    API->>Service: updateStatusById(id)
    Service->>DB: 現在のステータスを取得
    DB-->>Service: ユーザーを返す
    Service->>DB: 切替後のステータスで更新
    DB-->>Service: 更新されたユーザーを返す
    
    Note over API,Admin: ステップ4: レスポンス返却
    Service-->>API: ユーザーデータを返す
    API-->>Admin: 200 OK (ユーザーリソース)

ステップ

ステップ1: ステータス変更リクエスト

  • 説明: 管理者がユーザーのアクティブステータスを変更するリクエスト
  • リクエスト: POST /api/admin/users/{id}/change-status

ステップ2: 管理者権限の確認

  • 説明: システムはユーザーがスーパー管理者権限を持っているか確認
  • アクション: 現在のユーザーがスーパー管理者かどうか確認
  • 発生しうるエラー: 権限不足(403)

ステップ3: ユーザーステータス切替

  • 説明: システムがユーザーのアクティブステータスを切り替え
  • アクション:
    • 現在のステータスを取得
    • 反対のステータスに更新(アクティブ→非アクティブ、または逆)
    • ステータス変更のタイムスタンプを記録

ステップ4: レスポンス返却

  • 説明: 更新されたユーザーデータを返す
  • レスポンス:
    • 成功: 200 OKと新しいステータスを含む更新されたユーザーデータ
    • エラー: 適切なエラーメッセージ

エラー処理

  • ログ
    • ステータス変更失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    403 "このリソースにアクセスする権限がありません。" ユーザーがスーパー管理者でない場合
    400 "ユーザーデータの更新に失敗しました。" ステータス更新が失敗した場合
    404 "指定されたユーザーが見つかりません。" ユーザーIDが存在しない場合

ケース5: ユーザーの削除

説明

スーパー管理者がシステムからユーザーを削除します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Service as ユーザーサービス
    participant DB as データベース

    Note over Admin,DB: ステップ1: ユーザー削除リクエスト
    Admin->>API: DELETE /api/admin/users/{id}
    
    Note over API,Service: ステップ2: 管理者権限の確認
    API->>API: スーパー管理者かどうか確認
    
    Note over API,Service: ステップ3: 自己削除でないことを確認
    API->>API: 自分自身を削除していないか確認
    
    Note over Service,DB: ステップ4: ユーザー削除
    API->>Service: delete(id)
    Service->>DB: トランザクション開始
    Service->>DB: ロール関連付けを削除
    Service->>DB: ユーザーレコードを削除
    Service->>DB: トランザクション確定
    DB-->>Service: 削除確認
    
    Note over API,Admin: ステップ5: レスポンス返却
    Service-->>API: 削除ステータス
    API-->>Admin: 200 OK (削除成功メッセージ)

ステップ

ステップ1: ユーザー削除リクエスト

  • 説明: 管理者がユーザーを削除するリクエスト
  • リクエスト: DELETE /api/admin/users/{id}

ステップ2: 管理者権限の確認

  • 説明: システムはユーザーがスーパー管理者権限を持っているか確認
  • アクション: 現在のユーザーがスーパー管理者かどうか確認
  • 発生しうるエラー: 権限不足(403)

ステップ3: 自己削除でないことを確認

  • 説明: システムは管理者が自分自身のアカウントを削除することを防止
  • アクション: リクエストされたIDと現在のユーザーIDを比較
  • 発生しうるエラー: 自分自身のアカウントを削除できない(403)

ステップ4: ユーザー削除

  • 説明: システムがデータベースからユーザーを削除
  • アクション:
    • データベーストランザクションを開始
    • ユーザーのロールと関連付けを削除
    • ユーザーレコードを削除
    • トランザクションを確定

ステップ5: レスポンス返却

  • 説明: 削除成功を確認
  • レスポンス:
    • 成功: 200 OKと成功メッセージ
    • エラー: 適切なエラーメッセージ

エラー処理

  • ログ
    • ユーザー削除失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    403 "このリソースにアクセスする権限がありません。" ユーザーがスーパー管理者でない場合
    403 "自分自身のアカウントを削除することはできません。" 自分自身のアカウントを削除しようとした場合
    400 "ユーザーデータの削除に失敗しました。" 他の理由で削除が失敗した場合
    404 "指定されたユーザーが見つかりません。" ユーザーIDが存在しない場合

ケース6: 現在のユーザープロフィールの取得

説明

管理者ユーザーが自分自身のプロフィール情報を取得します。

シーケンス図

sequenceDiagram
    participant Admin as 管理者
    participant API as ユーザーコントローラー
    participant Service as 認証サービス
    participant DB as データベース

    Note over Admin,DB: ステップ1: プロフィールリクエスト
    Admin->>API: GET /api/admin/profile
    
    Note over API,Service: ステップ2: 認証済みユーザーを取得
    API->>Service: getProfile()
    Service->>DB: ユーザーデータを取得
    Service->>DB: ユーザーロールを取得
    DB-->>Service: ロール付きユーザーデータを返す
    
    Note over API,Admin: ステップ3: プロフィールを返却
    Service-->>API: ユーザープロフィールを返す
    API-->>Admin: 200 OK (ユーザーリソース)

ステップ

ステップ1: プロフィールリクエスト

  • 説明: 管理者が自分自身のプロフィール情報をリクエスト
  • リクエスト: GET /api/admin/profile

ステップ2: 認証済みユーザーを取得

  • 説明: システムが認証済みユーザーの情報を取得
  • アクション:
    • 認証済みセッションのユーザーデータを取得
    • ロール情報を含める
    • 必要な関連データをロード

ステップ3: プロフィールを返却

  • 説明: ユーザーのプロフィール情報を返す
  • レスポンス:
    • 成功: 200 OKとロールを含むユーザープロフィールデータ
    • エラー: プロフィール取得が失敗した場合は適切なエラーメッセージ

エラー処理

  • ログ
    • プロフィール取得失敗はアプリケーションログに記録
  • エラー詳細:
    ステータスコード エラーメッセージ 説明
    401 "認証に失敗しました。" ユーザーが認証されていない場合
    400 "プロフィールの取得に失敗しました。" プロフィール取得が失敗した場合

追加メモ

  • ユーザー管理モジュールには、ロールベースのアクセス制御が含まれており、特定のアクション(作成、更新、削除、ステータス変更)はスーパー管理者ユーザーのみに制限されています。
  • システムは管理者が自分自身のアカウントを削除することを防止し、アクセス権限の偶発的な喪失を防ぎます。
  • 大規模なユーザーリストを効果的に管理するために、ユーザーのフィルタリングと並べ替え機能が提供されています。
  • すべての重要な操作(ユーザーの作成、更新、削除)は監査証跡を維持するためにログに記録されます。
  • パスワード管理は適切なハッシュ化と検証によるセキュリティのベストプラクティスに従います。
  • メールの一意性はアプリケーションとデータベースの両方のレベルで強制されます。

関連データベーステーブルとフィールド

erDiagram
    groups {
        bigint id PK "主キー"
        string name "グループ名"
        bigint created_by FK "usersテーブルへの参照"
        integer status "0: 非アクティブ, 1: アクティブ"
        timestamp created_at "レコード作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }

    users {
        bigint id PK "主キー"
        string name "ユーザーのフルネーム"
        string email "ユーザーのメールアドレス(一意)"
        string uid "一意の識別子(50文字)"
        string payment_provider_customer_id "Stripe顧客ID(nullable)"
        integer status "0: 非アクティブ, 1: アクティブ"
        integer is_first_login "1: ログイン済み, 0: まだログインしていない"
        string remember_token "Remember meトークン"
        timestamp created_at "アカウント作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
        timestamp deleted_at "ソフト削除タイムスタンプ"
    }

    group_members {
        bigint id PK "主キー"
        bigint group_id FK "groupsテーブルへの参照"
        bigint user_id FK "usersテーブルへの参照"
        bigint group_role_id FK "group_rolesテーブルへの参照"
        boolean is_creator "ユーザーがグループ作成者かどうか"
        timestamp joined_at "ユーザーがグループに参加した時期"
        timestamp created_at "レコード作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }

    group_roles {
        bigint id PK "主キー"
        string name "ロール名(50文字)"
        string slug "ロールスラッグ(50文字、一意)"
        timestamp created_at "レコード作成タイムスタンプ"
        timestamp updated_at "最終更新タイムスタンプ"
    }

    admin_roles {
        bigint id PK
        string name "ロール表示名"
        string slug "権限のためのロール識別子(一意)"
        timestamp created_at
        timestamp updated_at
    }

    admin_role_user {
        bigint user_id FK "usersテーブルへの参照"
        bigint role_id FK "rolesテーブルへの参照"
        timestamp created_at
        timestamp updated_at
    }

    groups }|--|| users : created_by
    groups ||--o{ group_members : has
    users ||--o{ group_members : has
    group_roles ||--o{ group_members : has
    users ||--o{ admin_role_user : has
    admin_roles ||--o{ admin_role_user : has