Files
CFDivePlatform/openspec/specs/admin-user-management/spec.md
T
a620906209 ad2c05779d feat:實作 Admin Panel — 平台管理後台
後端:
- AdminStatsController:總會員/教練/課程數統計 API
- AdminUserController:會員與教練列表、詳情、啟用/停用、教練驗證(toggle 反轉語意)
- AdminOfferController:全平台課程列表與刪除
- routes/api.php:新增 /api/admin/stats、members、providers、offers 等路由

前端(frontend/):
- adminAuth store、adminAxios(第三套獨立認證)
- /admin/* 路由群組 + requiresAdmin guard
- AdminNavBar、AdminLayout
- App.vue:isCoachPage → isBackofficePage(/coach/* 和 /admin/* 皆隱藏會員 NavBar)
- LoginView、DashboardView(統計卡片)
- MembersView、ProvidersView(含驗證操作)、OffersView(含刪除確認)

OpenSpec:
- 新增 specs:admin-auth / admin-user-management / admin-offer-management / admin-stats / admin-panel-ui
- 歸檔:openspec/changes/archive/2026-05-10-admin-panel

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-10 04:07:13 +08:00

70 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## ADDED Requirements
### Requirement: 管理員查看會員列表
後端 SHALL 提供 `GET /api/admin/members`(需 Bearer tokenrole=admin),回傳所有 role=member 的用戶,支援關鍵字搜尋與分頁。
#### Scenario: 取得全部會員列表
- **WHEN** 管理員送出 GET 請求不帶參數
- **THEN** 回傳 HTTP 200`{ status: true, data: [...members with memberProfile], meta: { total, per_page, current_page, last_page } }`,預設每頁 15 筆
#### Scenario: 搜尋會員
- **WHEN** 管理員送出 `?q=王小明`
- **THEN** 只回傳 name 或 email 包含「王小明」的會員
---
### Requirement: 管理員查看會員詳情
後端 SHALL 提供 `GET /api/admin/members/{id}`,回傳指定會員的完整資料。
#### Scenario: 取得存在的會員詳情
- **WHEN** 管理員送出有效 id 的 GET 請求
- **THEN** 回傳 HTTP 200,包含 user 資料與 memberProfile
#### Scenario: 會員不存在
- **WHEN** 指定 id 的用戶不存在或 role 非 member
- **THEN** 回傳 HTTP 404`{ status: false, message: "用戶不存在" }`
---
### Requirement: 管理員啟用/停用會員帳號
後端 SHALL 提供 `PUT /api/admin/members/{id}/toggle-active`,反轉指定會員的 `is_active` 狀態。
#### Scenario: 停用啟用中的帳號
- **WHEN** 管理員對 is_active=true 的會員發送請求
- **THEN** 將 is_active 設為 false,回傳 HTTP 200`{ status: true, message: "帳號已停用", data: { is_active: false } }`
#### Scenario: 啟用停用中的帳號
- **WHEN** 管理員對 is_active=false 的會員發送請求
- **THEN** 將 is_active 設為 true,回傳 HTTP 200`{ status: true, message: "帳號已啟用", data: { is_active: true } }`
---
### Requirement: 管理員查看教練列表
後端 SHALL 提供 `GET /api/admin/providers`(需 Bearer tokenrole=admin),回傳所有 role=provider 的用戶,支援搜尋與分頁,含 providerProfile。
#### Scenario: 取得全部教練列表
- **WHEN** 管理員送出 GET 請求
- **THEN** 回傳 HTTP 200,含 providerProfile(包括 is_verified、business_name 等)與分頁 meta
---
### Requirement: 管理員啟用/停用教練帳號
後端 SHALL 提供 `PUT /api/admin/providers/{id}/toggle-active`,行為同會員版本。
#### Scenario: 停用/啟用教練帳號
- **WHEN** 管理員對教練帳號發送 toggle-active 請求
- **THEN** 反轉 is_active,回傳對應訊息
---
### Requirement: 管理員驗證教練
後端 SHALL 提供 `PUT /api/admin/providers/{id}/toggle-verified`,反轉 ProviderProfile.is_verified 狀態。
#### Scenario: 驗證教練
- **WHEN** 管理員對 is_verified=false 的教練發送請求
- **THEN** 將 is_verified 設為 true,回傳 HTTP 200`{ status: true, message: "教練已驗證", data: { is_verified: true } }`
#### Scenario: 取消驗證教練
- **WHEN** 管理員對 is_verified=true 的教練發送請求
- **THEN** 將 is_verified 設為 false,回傳 HTTP 200`{ status: true, message: "已取消驗證", data: { is_verified: false } }`