security(auth): 新增 member/provider 角色 middleware

補上待辦 H1:/api/member/*、/api/provider/* 原本只掛 auth:sanctum,
任何已登入帳號都能跨角色建立課程、預約與評價。

- 新增 EnsureMember、EnsureProvider(結構同 EnsureAdmin),註冊 alias
  member、provider,掛到對應路由群組;角色不符回 403
  { status: false, message: "無權限存取" },未登入仍由 auth:sanctum 回 401
- provider middleware 不檢查審核狀態,未通過審核的教練仍可送審
- 新增 RoleAuthorizationTest:member/provider/admin/未登入跨角色測試,
  並驗證越權請求不產生資料;跨角色共用路由(通知、未讀訊息數)不受影響
- Swagger:member/provider 端點的 403 描述補上角色不符,補齊列表端點 403
- 更新 BookingListTest docblock 的過時描述
- 完成 tasks 1.1–4.3;5.1、5.2 手動驗證尚未執行

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 23:57:16 +08:00
parent 9e4331d4f7
commit 16ccb4c18c
9 changed files with 329 additions and 55 deletions
+4 -4
View File
@@ -16,12 +16,12 @@ use Tests\TestCase;
* 預約列表端點資料隔離(booking-lifecycle 規格)。
*
* 路由對應(routes/api.php 已確認):
* GET /api/member/bookings → MemberBookingController::index(auth:sanctum,無 role check)
* GET /api/provider/bookings → ProviderBookingController::index(auth:sanctum,無 role check)
* GET /api/member/bookings → MemberBookingController::index(auth:sanctum + member middleware)
* GET /api/provider/bookings → ProviderBookingController::index(auth:sanctum + provider middleware)
* GET /api/admin/bookings → AdminBookingController::index(auth:sanctum + admin middleware)
*
* 資料隔離靠 controller query 條件,不靠 middleware role 強制,
* 因此測試需分別以正確角色 actingAs 驗證隔離邊界。
* 角色 middleware 只擋跨角色呼叫(見 RoleAuthorizationTest);同角色之間的資料隔離
* 靠 controller query 條件,因此測試需分別以正確角色 actingAs 驗證隔離邊界。
*/
class BookingListTest extends TestCase
{