コンテンツにスキップ

管理画面 — ユーザー管理仕様 (FR-012)

項目内容
対象FRFR-012(管理画面 — ユーザー管理)
優先度
ステータス詳細化済み
フェーズPhase 6

概要

運用担当者は管理画面からユーザーの一覧表示・詳細閲覧・アカウント停止・削除を行える。管理者の認証は一般ユーザーと同じワンタイムコード方式(FR-001/002)を使用し、users テーブルの role で権限を判別する。管理者権限は柔軟なRBACモデルで管理し、ロールごとに操作可能な範囲を制御する。

前提条件(依存FR)

依存FR必要な機能用途
FR-001/002(認証)ワンタイムコード認証管理者ログイン

管理者認証

ログインフロー

  1. 管理者は管理画面のログインページからメールアドレスを入力
  2. 一般ユーザーと同じワンタイムコード認証フロー(FR-001/002)で認証
  3. 認証成功後、users.role を確認し管理者権限を持つ場合のみ管理画面へ遷移
  4. 管理者権限がないユーザー → 403 Forbidden

ロール

ロール説明
user一般ユーザー(デフォルト)
admin管理者(管理画面アクセス可能)
  • ロールは DB の users.role カラムで管理する(default: user
  • 初期管理者はシードデータまたは DB 直接操作で設定する

RBAC(ロールベースアクセス制御)

権限モデル

管理者の操作権限はロールに紐づく admin_roles テーブルで管理する。

リソースキー操作
ユーザー管理userslist / view / suspend / delete
マスタデータ管理masterDatalist / create / update / delete
ダッシュボードdashboardview / export
お知らせ管理announcementslist / create / update / delete

デフォルトロール

super_admin(スーパー管理者):

{
"users": ["list", "view", "suspend", "delete"],
"masterData": ["list", "create", "update", "delete"],
"dashboard": ["view", "export"],
"announcements": ["list", "create", "update", "delete"]
}

operator(運用担当):

{
"users": ["list", "view", "suspend"],
"masterData": ["list", "create", "update"],
"dashboard": ["view"],
"announcements": ["list", "create", "update"]
}

viewer(閲覧者):

{
"users": ["list", "view"],
"masterData": ["list"],
"dashboard": ["view"],
"announcements": ["list"]
}

ユーザー一覧・検索

検索条件

パラメータ説明
qvarcharメールアドレスの部分一致検索
statusvarcharactive / suspended(フィルタ)
sortvarcharcreatedAt / email(default: createdAt
ordervarcharasc / desc(default: desc
limitinteger取得件数(default: 20、最大100)
offsetintegerスキップ件数(default: 0)

ユーザー詳細で表示する情報

項目説明
基本情報メールアドレス、ロール、登録日時
ペット情報登録ペット数、ペット一覧(名前・品種)
利用状況最終ログイン日時、アクティブセッション数
停止状態停止中か否か、停止理由、停止日時

アカウント停止

停止フロー

  1. 管理者がユーザー詳細画面で「アカウント停止」を実行
  2. 停止理由を入力(必須、1〜500文字)
  3. users.suspended_at に現在日時、users.suspension_reason に理由を設定
  4. 該当ユーザーの全アクティブセッションを即座に無効化
  5. 停止ユーザーは以降のログインが不可になる

停止解除

  • 管理者が「停止解除」を実行すると suspended_atsuspension_reasonnull に更新
  • 停止解除後、ユーザーは通常通りログイン可能

アカウント削除

  • 管理者が手動でアカウントを削除できる
  • 削除は論理削除(users.deleted_at に日時を設定)
  • 削除されたアカウントのデータ(ペット・健康記録等)はデータ保持期間(90日)後にバッチ処理で物理削除
  • 削除後のログインは不可

APIエンドポイント

全エンドポイントで管理者認証必須。

ユーザー管理

メソッドパス概要必要権限
GET/api/admin/usersユーザー一覧users.list
GET/api/admin/users/:userIdユーザー詳細users.view
POST/api/admin/users/:userId/suspendアカウント停止users.suspend
POST/api/admin/users/:userId/unsuspendアカウント停止解除users.suspend
DELETE/api/admin/users/:userIdアカウント削除users.delete

ロール管理

メソッドパス概要必要権限
GET/api/admin/rolesロール一覧users.list
POST/api/admin/rolesロール作成users.suspend
PATCH/api/admin/roles/:roleIdロール更新users.suspend
DELETE/api/admin/roles/:roleIdロール削除users.delete
PATCH/api/admin/users/:userId/roleユーザーロール変更users.suspend

GET /api/admin/users — ユーザー一覧

{
"data": [
{
"id": 1,
"email": "user@example.com",
"role": "user",
"petCount": 3,
"suspendedAt": null,
"createdAt": "2026-01-01T00:00:00Z"
}
],
"pagination": {
"total": 150,
"limit": 20,
"offset": 0
}
}

GET /api/admin/users/:userId — ユーザー詳細

{
"data": {
"id": 1,
"email": "user@example.com",
"role": "user",
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-02-01T00:00:00Z",
"suspendedAt": null,
"suspensionReason": null,
"lastLoginAt": "2026-02-20T10:00:00Z",
"activeSessionCount": 2,
"pets": [
{
"id": 1,
"name": "そうにゃ",
"breedName": "アメリカンショートヘア",
"createdAt": "2026-01-15T00:00:00Z"
}
]
}
}

POST /api/admin/users/:userId/suspend — アカウント停止

// リクエスト
{
"reason": "利用規約違反のため"
}
フィールド必須バリデーション
reasonvarchar1〜500文字
  • 成功時: 200 OK
  • 既に停止中: 409 Conflict
  • 管理者自身の停止: 422 Unprocessable Entity

POST /api/admin/users/:userId/unsuspend — 停止解除

  • 成功時: 200 OK
  • 停止中でない: 409 Conflict

DELETE /api/admin/users/:userId — アカウント削除

  • 成功時: 204 No Content
  • 管理者自身の削除: 422 Unprocessable Entity

DBテーブル(変更・追加)

users テーブルへの追加カラム

カラム備考
rolevarcharuser / admin(default: user
suspended_attimestamptz停止日時(nullable)
suspension_reasontext停止理由(nullable)
deleted_attimestamptz論理削除日時(nullable)
last_login_attimestamptz最終ログイン日時(nullable)

admin_roles

カラム備考
idserial主キー
namevarcharロール名(一意制約)
descriptionvarchar説明
permissionsjsonb権限セット
created_attimestamptz作成日時
updated_attimestamptz更新日時
  • デフォルトロール(super_admin / operator / viewer)はシードデータとして用意

認可ルール

  • 全エンドポイントで users.role = 'admin' であること
  • 各操作は admin_roles.permissions に基づいてリソース×操作単位で制御
  • 権限がない操作: 403 Forbidden
  • 管理者自身の停止・削除は不可
  • スーパー管理者ロールの削除は不可(保護)

エッジケース

  • 管理者自身を停止しようとした場合 → 422 Unprocessable Entity
  • 管理者自身を削除しようとした場合 → 422 Unprocessable Entity
  • 最後のスーパー管理者を降格しようとした場合 → 422 Unprocessable Entity(最低1人のスーパー管理者が必要)
  • 停止中のユーザーがAPIにアクセスした場合 → 403 Forbidden(「アカウントが停止されています」メッセージ付き)
  • 削除済みユーザーがログインしようとした場合 → 通常の認証コード送信応答を返す(アカウントの存在を漏らさない)が、コード検証時に失敗扱い
  • ロールが削除された場合 → 該当ロールに紐づくユーザーは user ロールにフォールバック

拡張予定(現時点ではスコープ外)

  • 管理者操作の監査ログ
  • 2要素認証(管理者向け強化認証)
  • ユーザーへのメール通知(停止通知等)
  • ユーザーデータのエクスポート機能
  • 一括操作(複数ユーザーの一括停止等)

検証方法

  • 管理者がユーザー一覧を取得でき、検索・フィルタが正しく動作すること
  • ユーザー詳細にペット情報・利用状況が表示されること
  • アカウント停止後に該当ユーザーがログインできないこと
  • アカウント停止後に全セッションが無効化されること
  • 停止解除後にユーザーがログインできること
  • 管理者自身の停止・削除が拒否されること
  • 権限がない操作に 403 が返ること
  • 一般ユーザーが管理画面APIにアクセスした場合に 403 が返ること
  • ロール変更が即座に反映されること
  • 最後のスーパー管理者の降格が拒否されること