feat(verification): 教練審核流程完整版——狀態機/證照送審/Admin 裁決/通知
Run Tests / test (pull_request) Successful in 2m3s
Run Tests / test (pull_request) Successful in 2m3s
實作 openspec change provider-verification-workflow(25/25 tasks): - is_verified 升級為 verification_status 四狀態機(unsubmitted/pending/ approved/rejected),migration 自動轉換既有資料,API 以 accessor 保留 is_verified 相容輸出 - 教練端:證照上傳(≤3 張、複用 CompressesImages)、送審、駁回原因 顯示與重送(/coach/verification 新頁面) - Admin 端:審核佇列、通過/駁回(原因必填)、撤銷 approved;移除 toggle-verified 端點(防繞過狀態機);裁決後 flush 課程快取 - 通知:審核通過/駁回(站內+Email,駁回含原因) - 可見性與預約入口改判 approved(行為等價) - 測試 +18(ProviderVerificationTest 10、AdminVerificationTest 8), 既有 4 個測試檔 helper 遷移;Swagger 同步 - 規格同步:provider-verification 全面改寫、admin-user-management toggle 段落改為移除聲明 容器內全套件 173 passed / 439 assertions。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 教練驗證狀態機
|
||||
`provider_profiles.verification_status` SHALL 為四狀態字串:`unsubmitted`(註冊預設)、`pending`、`approved`、`rejected`。合法轉移僅限:`unsubmitted→pending`(送審)、`pending→approved`(通過)、`pending→rejected`(駁回)、`rejected→pending`(重新送審,同時清空 `rejection_reason`)、`approved→rejected`(撤銷,原因必填)。原 boolean `is_verified` 欄位移除,API 輸出以 accessor 保留 `is_verified`(= status 為 approved)。
|
||||
|
||||
#### Scenario: 新教練註冊預設未送審
|
||||
- **WHEN** 教練完成註冊
|
||||
- **THEN** `verification_status = unsubmitted`,不出現在 Admin 待審佇列
|
||||
|
||||
#### Scenario: 非法轉移被拒絕
|
||||
- **WHEN** 嘗試對 `unsubmitted` 教練執行 approve,或對 `approved` 教練執行 approve
|
||||
- **THEN** 回傳 HTTP 422,狀態不變
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 教練上傳證照與送審
|
||||
教練 SHALL 能於後台上傳 1~3 張證照圖片(jpeg/png/webp、≤10MB,伺服器端壓縮為 `.jpg`,存 `providers/{user_id}/certifications/`)並送出審核。證照僅於 `unsubmitted` / `rejected` 狀態可增刪;`pending` / `approved` 狀態鎖定。送審需至少 1 張證照。
|
||||
|
||||
#### Scenario: 上傳證照
|
||||
- **WHEN** `unsubmitted` 教練 `POST /api/provider/verification/certifications` 上傳合法圖片且現有 < 3 張
|
||||
- **THEN** 壓縮儲存並建立 `provider_certifications` 紀錄,回傳圖片資訊
|
||||
|
||||
#### Scenario: 超過 3 張上限
|
||||
- **WHEN** 教練已有 3 張證照再上傳
|
||||
- **THEN** 回傳 HTTP 422
|
||||
|
||||
#### Scenario: 送審成功
|
||||
- **WHEN** 教練至少有 1 張證照,`POST /api/provider/verification/submit`
|
||||
- **THEN** 狀態轉為 `pending`,`rejection_reason` 清空
|
||||
|
||||
#### Scenario: 無證照不可送審
|
||||
- **WHEN** 教練無任何證照即送審
|
||||
- **THEN** 回傳 HTTP 422,狀態不變
|
||||
|
||||
#### Scenario: pending 期間證照鎖定
|
||||
- **WHEN** `pending` 或 `approved` 教練嘗試上傳或刪除證照
|
||||
- **THEN** 回傳 HTTP 422
|
||||
|
||||
#### Scenario: 查詢自身驗證狀態
|
||||
- **WHEN** 教練 `GET /api/provider/verification`
|
||||
- **THEN** 回傳 `status`、`rejection_reason`、`certifications[]`(id、url)
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Admin 審核佇列與裁決
|
||||
Admin SHALL 能查詢審核佇列(`GET /api/admin/verifications?status=pending`,預設 pending,含教練資料與證照 URL),並對 `pending` 教練執行通過(`PUT /api/admin/verifications/{userId}/approve`)或駁回(`PUT /api/admin/verifications/{userId}/reject`,`reason` 必填、max 500)。Admin SHALL 能駁回 `approved` 教練(撤銷驗證,原因必填)。裁決後 SHALL flush `diving_offers` 快取(可見性立即生效)。原 `PUT /api/admin/providers/{id}/toggle-verified` 端點 SHALL 移除。
|
||||
|
||||
#### Scenario: 通過審核
|
||||
- **WHEN** Admin 對 pending 教練執行 approve
|
||||
- **THEN** 狀態轉 `approved`,教練課程立即恢復公開可見性
|
||||
|
||||
#### Scenario: 駁回需附原因
|
||||
- **WHEN** Admin 執行 reject 未帶 `reason`
|
||||
- **THEN** 回傳 HTTP 422,狀態不變
|
||||
|
||||
#### Scenario: 撤銷已通過教練
|
||||
- **WHEN** Admin 對 approved 教練執行 reject 並附原因
|
||||
- **THEN** 狀態轉 `rejected`,課程立即從公開列表消失;既有預約照常(沿用既定政策)
|
||||
|
||||
#### Scenario: 舊 toggle 端點已移除
|
||||
- **WHEN** 任何人請求 `PUT /api/admin/providers/{id}/toggle-verified`
|
||||
- **THEN** 回傳 HTTP 404
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 審核結果通知
|
||||
系統 SHALL 於 approve / reject 後通知該教練(站內 + Email):通過通知告知課程已可公開曝光;駁回通知包含駁回原因。通知失敗不阻斷審核主流程。
|
||||
|
||||
#### Scenario: 通過通知
|
||||
- **WHEN** Admin approve
|
||||
- **THEN** 教練收到站內通知與 Email,內容含審核通過訊息
|
||||
|
||||
#### Scenario: 駁回通知含原因
|
||||
- **WHEN** Admin reject 並附原因
|
||||
- **THEN** 教練收到的通知內容包含該原因
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 未驗證教練的課程不對公開端點曝光
|
||||
公開課程端點(列表、詳情、schedules、reviews)SHALL 僅曝光 `provider_id` 為 null 或教練 `verification_status = 'approved'` 的課程(原以 `is_verified = true` 判定,語意等價)。`POST /api/member/bookings` 的可預約檢查同步改以 `approved` 判定。其餘行為(404、422、既有預約不受影響)不變。
|
||||
|
||||
#### Scenario: 非 approved 狀態一律不曝光
|
||||
- **WHEN** 課程教練的狀態為 unsubmitted / pending / rejected
|
||||
- **THEN** 公開端點不回傳該課程,新預約被拒
|
||||
Reference in New Issue
Block a user