Files
CFDivePlatform/storage/api-docs/api-docs.json
T
a620906209 43720482c4
Run Tests / test (pull_request) Successful in 2m3s
feat(verification): 教練審核流程完整版——狀態機/證照送審/Admin 裁決/通知
實作 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>
2026-06-12 00:26:12 +08:00

7255 lines
320 KiB
JSON
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.
{
"openapi": "3.0.0",
"info": {
"title": "CFDive Platform API",
"description": "CFDive Platform API 文檔",
"version": "1.0.0"
},
"servers": [
{
"url": "/api",
"description": "API 伺服器"
}
],
"paths": {
"/admin/stats": {
"get": {
"tags": [
"Admin 統計"
],
"summary": "取得平台統計數據",
"description": "回傳會員總數、服務提供者總數、課程總數;非 admin 角色回傳 403",
"operationId": "getAdminStats",
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"properties": {
"total_members": {
"type": "integer",
"example": 128
},
"total_providers": {
"type": "integer",
"example": 34
},
"total_offers": {
"type": "integer",
"example": 87
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/members": {
"get": {
"tags": [
"Admin 會員管理"
],
"summary": "取得會員列表",
"description": "分頁回傳所有會員帳號,含 member_profile",
"operationId": "listAdminMembers",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王小明"
},
"email": {
"type": "string",
"example": "member@example.com"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
},
"member_profile": {
"type": "object",
"nullable": true
}
},
"type": "object"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/members/{id}": {
"get": {
"tags": [
"Admin 會員管理"
],
"summary": "取得單一會員",
"description": "取得單一會員",
"operationId": "getAdminMember",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "會員不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/members/{id}/toggle-active": {
"put": {
"tags": [
"Admin 會員管理"
],
"summary": "切換會員啟用狀態",
"description": "啟用或停用指定會員帳號",
"operationId": "toggleMemberActive",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "切換成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "帳號已停用"
},
"is_active": {
"type": "boolean",
"example": false
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "會員不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/check-member/{id}": {
"get": {
"tags": [
"Admin 會員管理"
],
"summary": "確認會員存在",
"description": "快速確認指定 ID 的會員是否存在(角色為 member)",
"operationId": "checkMember",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "會員存在",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"exists": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/providers": {
"get": {
"tags": [
"Admin 教練管理"
],
"summary": "取得教練列表",
"description": "分頁回傳所有服務提供者,含 provider_profile",
"operationId": "listAdminProviders",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 2
},
"name": {
"type": "string",
"example": "林教練"
},
"email": {
"type": "string",
"example": "coach@example.com"
},
"role": {
"type": "string",
"example": "provider"
},
"is_active": {
"type": "boolean",
"example": true
},
"is_verified": {
"type": "boolean",
"example": false
},
"provider_profile": {
"type": "object",
"nullable": true
}
},
"type": "object"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/providers/{id}": {
"get": {
"tags": [
"Admin 教練管理"
],
"summary": "取得單一教練",
"description": "取得單一教練",
"operationId": "getAdminProvider",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "教練不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/providers/{id}/toggle-active": {
"put": {
"tags": [
"Admin 教練管理"
],
"summary": "切換教練啟用狀態",
"description": "切換教練啟用狀態",
"operationId": "toggleProviderActive",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "切換成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "帳號已停用"
},
"is_active": {
"type": "boolean",
"example": false
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "教練不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/verifications": {
"get": {
"tags": [
"Admin 教練管理"
],
"summary": "教練審核佇列",
"description": "查詢教練驗證申請(預設僅 pending;status=all 可查全部),含證照圖片 URL",
"operationId": "adminVerificationIndex",
"parameters": [
{
"name": "status",
"in": "query",
"description": "unsubmitted / pending / approved / rejected / all",
"required": false,
"schema": {
"type": "string",
"default": "pending"
}
}
],
"responses": {
"200": {
"description": "查詢成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"properties": {
"user_id": {
"type": "integer",
"example": 5
},
"name": {
"type": "string",
"example": "王教練"
},
"email": {
"type": "string",
"example": "coach@example.com"
},
"business_name": {
"type": "string",
"example": "藍海潛水"
},
"verification_status": {
"type": "string",
"example": "pending"
},
"rejection_reason": {
"type": "string",
"example": null,
"nullable": true
},
"certifications": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"url": {
"type": "string",
"example": "http://localhost:8080/storage/providers/5/certifications/uuid.jpg"
}
},
"type": "object"
}
}
},
"type": "object"
}
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/verifications/{userId}/approve": {
"put": {
"tags": [
"Admin 教練管理"
],
"summary": "通過教練審核",
"description": "將 pending 教練轉為 approved,課程恢復公開曝光並通知教練",
"operationId": "adminVerificationApprove",
"parameters": [
{
"name": "userId",
"in": "path",
"description": "教練使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "已通過審核"
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "教練不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "當前狀態無法通過審核",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/verifications/{userId}/reject": {
"put": {
"tags": [
"Admin 教練管理"
],
"summary": "駁回教練審核",
"description": "駁回 pending 教練或撤銷 approved 教練,原因必填並通知教練",
"operationId": "adminVerificationReject",
"parameters": [
{
"name": "userId",
"in": "path",
"description": "教練使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"reason"
],
"properties": {
"reason": {
"type": "string",
"maxLength": 500,
"example": "證照影像不清晰,請重新拍攝上傳"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "已駁回"
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "教練不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "原因未填或狀態不可駁回",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/check-provider/{id}": {
"get": {
"tags": [
"Admin 教練管理"
],
"summary": "確認教練存在",
"description": "確認教練存在",
"operationId": "checkProvider",
"parameters": [
{
"name": "id",
"in": "path",
"description": "使用者 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "查詢成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"exists": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/offers": {
"get": {
"tags": [
"Admin 課程管理"
],
"summary": "取得所有課程(Admin",
"description": "分頁回傳全平台課程列表",
"operationId": "listAdminOffers",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/offers/{id}": {
"delete": {
"tags": [
"Admin 課程管理"
],
"summary": "刪除課程(Admin",
"description": "刪除課程(Admin",
"operationId": "deleteAdminOffer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "課程已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/bookings": {
"get": {
"tags": [
"Admin 課程管理"
],
"summary": "取得所有預約(Admin",
"description": "分頁回傳全平台預約列表",
"operationId": "listAdminBookings",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Booking"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/bookings/{id}/complete": {
"put": {
"tags": [
"Admin 課程管理"
],
"summary": "標記預約完成(Admin",
"description": "標記預約完成(Admin",
"operationId": "completeBookingByAdmin",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "標記成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已完成"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "狀態不允許完成",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/reviews": {
"get": {
"tags": [
"Admin 課程管理"
],
"summary": "取得所有評價(Admin",
"description": "分頁回傳全平台評價列表,per_page 最大 100",
"operationId": "listAdminReviews",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數(最大 100",
"schema": {
"type": "integer",
"default": 20,
"maximum": 100
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Review"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/reviews/{id}": {
"delete": {
"tags": [
"Admin 課程管理"
],
"summary": "刪除評價(Admin",
"description": "刪除評價(Admin",
"operationId": "deleteAdminReview",
"parameters": [
{
"name": "id",
"in": "path",
"description": "評價 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "評價已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非 admin 角色",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "評價不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/register": {
"post": {
"tags": [
"會員"
],
"summary": "會員註冊",
"description": "建立新的會員帳號",
"operationId": "registerMember",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"name",
"email",
"password",
"password_confirmation"
],
"properties": {
"name": {
"description": "使用者姓名",
"type": "string",
"example": "王小明"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "member@example.com"
},
"password": {
"description": "密碼",
"type": "string",
"format": "password",
"example": "password123"
},
"password_confirmation": {
"description": "確認密碼",
"type": "string",
"format": "password",
"example": "password123"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0912345678"
},
"birthday": {
"description": "生日",
"type": "string",
"format": "date",
"example": "1990-01-01"
},
"gender": {
"description": "性別",
"type": "string",
"enum": [
"male",
"female",
"other"
],
"example": "male"
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "會員註冊成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "會員註冊成功"
},
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王小明"
},
"email": {
"type": "string",
"example": "user@example.com"
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
},
"email_verified_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"memberProfile": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"user_id": {
"type": "integer",
"example": 1
},
"birthday": {
"type": "string",
"example": "1990-01-01"
},
"gender": {
"type": "string",
"example": "male"
},
"address": {
"type": "string",
"example": "台北市信義區某街123號"
},
"emergency_contact": {
"type": "string",
"example": "王大明"
},
"emergency_phone": {
"type": "string",
"example": "0987654321"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"type": "object"
},
"token": {
"type": "string",
"example": "1|abcdef1234567890"
},
"token_type": {
"type": "string",
"example": "Bearer"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
}
}
},
"/member/login": {
"post": {
"tags": [
"會員"
],
"summary": "會員登入",
"description": "會員帳號登入系統",
"operationId": "loginMember",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "member@example.com"
},
"password": {
"description": "密碼",
"type": "string",
"format": "password",
"example": "password123"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "登入成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "登入成功"
},
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 11
},
"name": {
"type": "string",
"example": "測試會員"
},
"email": {
"type": "string",
"example": "test_member@example.com"
},
"email_verified_at": {
"type": "string",
"example": null,
"nullable": true
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "integer",
"example": 1
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"member_profile": {
"properties": {
"id": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "integer",
"example": 11
},
"birthday": {
"type": "string",
"example": "1990-01-01T00:00:00.000000Z"
},
"gender": {
"type": "string",
"example": "male"
},
"address": {
"type": "string",
"example": null,
"nullable": true
},
"emergency_contact": {
"type": "string",
"example": null,
"nullable": true
},
"emergency_phone": {
"type": "string",
"example": null,
"nullable": true
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
}
},
"type": "object"
}
},
"type": "object"
},
"token": {
"type": "string",
"example": "23|ZuJ6m0Ls4FSJITsOoqWtFtacazXyXwUtZtkcTb960e5a08"
},
"token_type": {
"type": "string",
"example": "Bearer"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "身份驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "電子郵件或密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "帳號已被停用",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "帳號已被停用"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
}
}
},
"/member/logout": {
"post": {
"tags": [
"會員"
],
"summary": "會員登出",
"description": "會員登出系統並撤銷當前令牌",
"operationId": "logoutMember",
"responses": {
"200": {
"description": "登出成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "會員登出成功"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/profile": {
"get": {
"tags": [
"會員"
],
"summary": "取得會員個人資料",
"description": "取得當前登入會員的個人資料",
"operationId": "memberProfile",
"responses": {
"200": {
"description": "取得資料成功",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王小明"
},
"email": {
"type": "string",
"example": "user@example.com"
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
},
"email_verified_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"memberProfile": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"user_id": {
"type": "integer",
"example": 1
},
"birthday": {
"type": "string",
"example": "1990-01-01"
},
"gender": {
"type": "string",
"example": "male"
},
"address": {
"type": "string",
"example": "台北市信義區某街123號"
},
"emergency_contact": {
"type": "string",
"example": "王大明"
},
"emergency_phone": {
"type": "string",
"example": "0987654321"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"put": {
"tags": [
"會員"
],
"summary": "更新會員個人資料",
"description": "更新當前登入會員的個人資料",
"operationId": "updateMemberProfile",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"name": {
"description": "使用者姓名",
"type": "string",
"example": "王大明"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "newmail@example.com"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0987654321"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "會員資料已更新"
},
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王大明"
},
"email": {
"type": "string",
"example": "user@example.com"
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
},
"email_verified_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"memberProfile": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"user_id": {
"type": "integer",
"example": 1
},
"birthday": {
"type": "string",
"example": "1990-01-01"
},
"gender": {
"type": "string",
"example": "male"
},
"address": {
"type": "string",
"example": "台北市信義區某街123號"
},
"emergency_contact": {
"type": "string",
"example": "王大明"
},
"emergency_phone": {
"type": "string",
"example": "0987654321"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/change-password": {
"put": {
"tags": [
"會員"
],
"summary": "修改會員密碼",
"description": "修改當前登入會員的密碼",
"operationId": "changeMemberPassword",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"current_password",
"password",
"password_confirmation"
],
"properties": {
"current_password": {
"description": "目前密碼",
"type": "string",
"format": "password",
"example": "oldpassword"
},
"password": {
"description": "新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
},
"password_confirmation": {
"description": "確認新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "修改成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "密碼修改成功"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "目前密碼錯誤",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "目前密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/register": {
"post": {
"tags": [
"服務提供者"
],
"summary": "服務提供者註冊",
"description": "建立新的服務提供者帳號",
"operationId": "registerProvider",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"name",
"email",
"password",
"password_confirmation"
],
"properties": {
"name": {
"description": "使用者姓名",
"type": "string",
"example": "林教練"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "coach@example.com"
},
"password": {
"description": "密碼",
"type": "string",
"format": "password",
"example": "password123"
},
"password_confirmation": {
"description": "確認密碼",
"type": "string",
"format": "password",
"example": "password123"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0912345678"
},
"business_name": {
"description": "業者名稱",
"type": "string",
"example": "藍海潛水中心"
},
"description": {
"description": "業者描述",
"type": "string",
"example": "專業潛水中心,提供各種潛水服務"
},
"contact_person": {
"description": "聯絡人",
"type": "string",
"example": "羅大師"
},
"contact_phone": {
"description": "聯絡電話",
"type": "string",
"example": "0912345678"
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "服務提供者註冊成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "服務提供者註冊成功"
},
"data": {
"properties": {
"user": {
"$ref": "#/components/schemas/User"
},
"token": {
"type": "string",
"example": "1|abcdef1234567890"
},
"token_type": {
"type": "string",
"example": "Bearer"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
}
}
},
"/provider/login": {
"post": {
"tags": [
"服務提供者"
],
"summary": "服務提供者登入",
"description": "服務提供者帳號登入系統",
"operationId": "loginProvider",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "coach@example.com"
},
"password": {
"description": "密碼",
"type": "string",
"format": "password",
"example": "password123"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "登入成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"properties": {
"id": {
"type": "integer",
"example": 11
},
"name": {
"type": "string",
"example": "測試服務提供者"
},
"email": {
"type": "string",
"example": "test_provider@example.com"
},
"email_verified_at": {
"type": "string",
"example": null,
"nullable": true
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "provider"
},
"is_active": {
"type": "integer",
"example": 1
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"providerProfile": {
"properties": {
"id": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "integer",
"example": 11
},
"business_name": {
"type": "string",
"example": "藍海潛水中心"
},
"description": {
"type": "string",
"example": "專業潛水中心,提供各種潛水服務"
},
"contact_person": {
"type": "string",
"example": "王大師"
},
"contact_phone": {
"type": "string",
"example": "0912345678"
},
"contact_email": {
"type": "string",
"example": "contact@example.com"
},
"address": {
"type": "string",
"example": "台灣屏東縣恆春鎮XXX路123號"
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "身份驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "電子郵件或密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "帳號已被停用",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "帳號已被停用"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
}
}
},
"/provider/logout": {
"post": {
"tags": [
"服務提供者"
],
"summary": "服務提供者登出",
"description": "服務提供者登出系統並撤銷當前令牌",
"operationId": "logoutProvider",
"responses": {
"200": {
"description": "登出成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "服務提供者登出成功"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/profile": {
"get": {
"tags": [
"服務提供者"
],
"summary": "取得服務提供者資料",
"description": "取得當前登入服務提供者的資料",
"operationId": "providerProfile",
"responses": {
"200": {
"description": "取得資料成功",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "測試服務提供者"
},
"email": {
"type": "string",
"example": "provider@example.com"
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "provider"
},
"is_active": {
"type": "boolean",
"example": true
},
"email_verified_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"providerProfile": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"user_id": {
"type": "integer",
"example": 1
},
"business_name": {
"type": "string",
"example": "藍海潛水中心"
},
"description": {
"type": "string",
"example": "專業潛水中心,提供各種潛水服務"
},
"contact_person": {
"type": "string",
"example": "王大師"
},
"contact_phone": {
"type": "string",
"example": "0912345678"
},
"contact_email": {
"type": "string",
"example": "contact@example.com"
},
"address": {
"type": "string",
"example": "台灣屏東縣恆春鎮XXX路123號"
},
"business_hours": {
"type": "string",
"example": "週一至週五 09:00-18:00"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"put": {
"tags": [
"服務提供者"
],
"summary": "更新服務提供者資料",
"description": "更新當前登入服務提供者的資料",
"operationId": "updateProviderProfile",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"name": {
"description": "使用者姓名",
"type": "string",
"example": "藍海潛水中心"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "newprovider@example.com"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0987654321"
},
"business_name": {
"description": "業者名稱",
"type": "string",
"example": "藍海潛水中心新分院"
},
"description": {
"description": "業者描述",
"type": "string",
"example": "專業潛水中心,提供各種高品質潛水課程與行程"
},
"contact_person": {
"description": "聯絡人",
"type": "string",
"example": "王大師"
},
"address": {
"description": "營業地址",
"type": "string",
"example": "台灣屏東縣恆春鎮XXX路456號"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "服務提供者資料已更新"
},
"data": {
"properties": {
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "藍海潛水中心"
},
"email": {
"type": "string",
"example": "provider@example.com"
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "provider"
},
"is_active": {
"type": "boolean",
"example": true
},
"email_verified_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"providerProfile": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"user_id": {
"type": "integer",
"example": 1
},
"business_name": {
"type": "string",
"example": "藍海潛水中心"
},
"description": {
"type": "string",
"example": "專業潛水中心,提供各種潛水服務"
},
"contact_person": {
"type": "string",
"example": "王大師"
},
"contact_phone": {
"type": "string",
"example": "0912345678"
},
"contact_email": {
"type": "string",
"example": "contact@example.com"
},
"address": {
"type": "string",
"example": "台灣屏東縣恆春鎮XXX路123號"
},
"business_hours": {
"type": "string",
"example": "週一至週五 09:00-18:00"
},
"created_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/change-password": {
"put": {
"tags": [
"服務提供者"
],
"summary": "修改服務提供者密碼",
"description": "修改當前登入服務提供者的密碼",
"operationId": "changeProviderPassword",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"current_password",
"password",
"password_confirmation"
],
"properties": {
"current_password": {
"description": "目前密碼",
"type": "string",
"format": "password",
"example": "oldpassword"
},
"password": {
"description": "新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
},
"password_confirmation": {
"description": "確認新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "修改成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "密碼修改成功"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "目前密碼錯誤",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "目前密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/login": {
"post": {
"tags": [
"管理員"
],
"summary": "管理員登入",
"description": "管理員帳號登入系統",
"operationId": "loginAdmin",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "admin@example.com"
},
"password": {
"description": "密碼",
"type": "string",
"format": "password",
"example": "password123"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "登入成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"properties": {
"id": {
"type": "integer",
"example": 11
},
"name": {
"type": "string",
"example": "測試管理員"
},
"email": {
"type": "string",
"example": "test_admin@example.com"
},
"email_verified_at": {
"type": "string",
"example": null,
"nullable": true
},
"phone": {
"type": "string",
"example": "0912345678"
},
"role": {
"type": "string",
"example": "admin"
},
"is_active": {
"type": "integer",
"example": 1
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"adminProfile": {
"properties": {
"id": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "integer",
"example": 11
},
"birthday": {
"type": "string",
"example": "1990-01-01T00:00:00.000000Z"
},
"gender": {
"type": "string",
"example": "male"
},
"address": {
"type": "string",
"example": null,
"nullable": true
},
"emergency_contact": {
"type": "string",
"example": null,
"nullable": true
},
"emergency_phone": {
"type": "string",
"example": null,
"nullable": true
},
"created_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-05-08T17:19:22.000000Z"
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "身份驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "電子郵件或密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "帳號已被停用",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "帳號已被停用"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
}
}
},
"/admin/logout": {
"post": {
"tags": [
"管理員"
],
"summary": "管理員登出",
"description": "管理員登出系統並撤銷當前令牌",
"operationId": "logoutAdmin",
"responses": {
"200": {
"description": "登出成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "管理員登出成功"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/profile": {
"get": {
"tags": [
"管理員"
],
"summary": "取得管理員個人資料",
"description": "取得當前登入管理員的個人資料",
"operationId": "adminProfile",
"responses": {
"200": {
"description": "取得資料成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/User"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"put": {
"tags": [
"管理員"
],
"summary": "更新管理員個人資料",
"description": "更新當前登入管理員的個人資料",
"operationId": "updateAdminProfile",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"name": {
"description": "使用者姓名",
"type": "string",
"example": "張總管"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "newadmin@example.com"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0987654321"
},
"position": {
"description": "職位",
"type": "string",
"example": "資深系統管理員"
},
"department": {
"description": "部門",
"type": "string",
"example": "系統維護部"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "管理員資料已更新"
},
"data": {
"$ref": "#/components/schemas/User"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/admin/change-password": {
"put": {
"tags": [
"管理員"
],
"summary": "修改管理員密碼",
"description": "修改當前登入管理員的密碼",
"operationId": "changeAdminPassword",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"current_password",
"password",
"password_confirmation"
],
"properties": {
"current_password": {
"description": "目前密碼",
"type": "string",
"format": "password",
"example": "oldpassword"
},
"password": {
"description": "新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
},
"password_confirmation": {
"description": "確認新密碼",
"type": "string",
"format": "password",
"example": "newpassword"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "修改成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "密碼修改成功"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "目前密碼錯誤",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "目前密碼錯誤"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "無權限存取"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "驗證失敗"
},
"errors": {
"type": "object"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/logout": {
"post": {
"tags": [
"認證"
],
"summary": "通用登出",
"description": "撤銷當前 Bearer token,適用所有角色",
"operationId": "logout",
"responses": {
"200": {
"description": "登出成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "登出成功"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "未認證",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Unauthenticated."
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/user": {
"get": {
"tags": [
"認證"
],
"summary": "取得當前使用者",
"description": "回傳當前 Bearer token 所屬的使用者資訊",
"operationId": "currentUser",
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王小明"
},
"email": {
"type": "string",
"example": "user@example.com"
},
"role": {
"type": "string",
"enum": [
"member",
"provider",
"admin"
],
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "未認證",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Unauthenticated."
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/auth/google/redirect": {
"get": {
"tags": [
"Google OAuth"
],
"summary": "取得 Google OAuth 重定向 URL",
"description": "回傳 Google OAuth 授權頁面的 redirect_url,前端應將使用者導向此 URL 以啟動 OAuth 流程",
"operationId": "googleRedirect",
"responses": {
"200": {
"description": "取得 redirect_url 成功",
"content": {
"application/json": {
"schema": {
"properties": {
"redirect_url": {
"type": "string",
"format": "uri",
"example": "https://accounts.google.com/o/oauth2/auth?client_id=..."
}
},
"type": "object"
}
}
}
}
}
}
},
"/auth/google/callback": {
"get": {
"tags": [
"Google OAuth"
],
"summary": "Google OAuth 回調",
"description": "Google OAuth 授權完成後的回調端點,通常由瀏覽器自動呼叫。成功後回傳 Bearer token 與使用者資訊",
"operationId": "googleCallback",
"parameters": [
{
"name": "code",
"in": "query",
"description": "Google 授權碼",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "state",
"in": "query",
"description": "OAuth state 參數",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OAuth 登入成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "登入成功"
},
"data": {
"properties": {
"token": {
"type": "string",
"example": "1|abcdef1234567890"
},
"token_type": {
"type": "string",
"example": "Bearer"
},
"user": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "王小明"
},
"email": {
"type": "string",
"example": "user@gmail.com"
},
"role": {
"type": "string",
"example": "member"
},
"is_active": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "OAuth 驗證失敗",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "OAuth 驗證失敗"
}
},
"type": "object"
}
}
}
}
}
}
},
"/member/bookings": {
"get": {
"tags": [
"會員預約"
],
"summary": "取得我的預約列表",
"description": "分頁回傳當前會員的所有預約",
"operationId": "listMemberBookings",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Booking"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"post": {
"tags": [
"會員預約"
],
"summary": "建立預約",
"description": "會員建立新的課程預約",
"operationId": "createBooking",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"offer_id",
"schedule_id",
"participants"
],
"properties": {
"offer_id": {
"description": "課程 ID",
"type": "integer",
"example": 1
},
"schedule_id": {
"description": "時段 ID",
"type": "integer",
"example": 2
},
"participants": {
"description": "參加人數",
"type": "integer",
"example": 2
},
"note": {
"type": "string",
"example": "需要器材租借",
"nullable": true
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "預約建立成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約成功"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗或時段已滿",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "無權限(非 member 角色)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/bookings/{id}": {
"get": {
"tags": [
"會員預約"
],
"summary": "取得單一預約",
"description": "取得單一預約",
"operationId": "getMemberBooking",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"404": {
"description": "預約不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "無權限存取",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"會員預約"
],
"summary": "取消預約",
"description": "會員取消自己的預約",
"operationId": "cancelBooking",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取消成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已取消"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "無權限或狀態不允許取消",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "預約不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/reviews": {
"post": {
"tags": [
"會員評價"
],
"summary": "建立評價",
"description": "會員對已完成的預約課程提交評價",
"operationId": "createReview",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"booking_id",
"rating"
],
"properties": {
"booking_id": {
"type": "integer",
"example": 5
},
"rating": {
"type": "integer",
"maximum": 5,
"minimum": 1,
"example": 4
},
"comment": {
"type": "string",
"example": "課程非常棒!",
"nullable": true
},
"is_anonymous": {
"type": "boolean",
"example": false
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "評價建立成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "評價已提交"
},
"data": {
"$ref": "#/components/schemas/Review"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "預約未完成或非本人預約",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/member/reviews/{id}": {
"put": {
"tags": [
"會員評價"
],
"summary": "更新評價",
"description": "更新評價",
"operationId": "updateReview",
"parameters": [
{
"name": "id",
"in": "path",
"description": "評價 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"rating": {
"type": "integer",
"maximum": 5,
"minimum": 1,
"example": 5
},
"comment": {
"type": "string",
"example": "更新後的評語",
"nullable": true
},
"is_anonymous": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/Review"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人評價",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "評價不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"會員評價"
],
"summary": "刪除評價",
"description": "刪除評價",
"operationId": "deleteReview",
"parameters": [
{
"name": "id",
"in": "path",
"description": "評價 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "評價已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人評價",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "評價不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/reviews/{id}/helpful": {
"post": {
"tags": [
"會員評價"
],
"summary": "標記評價為有幫助",
"description": "切換投票狀態(已投票則撤回)",
"operationId": "markReviewHelpful",
"parameters": [
{
"name": "id",
"in": "path",
"description": "評價 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "操作成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"helpful_count": {
"type": "integer",
"example": 4
},
"has_voted": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"404": {
"description": "評價不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/notifications": {
"get": {
"tags": [
"通知"
],
"summary": "取得通知列表",
"description": "分頁回傳當前使用者的所有通知(Member / Provider 共用)",
"operationId": "listNotifications",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"type": {
"type": "string",
"example": "booking_confirmed"
},
"title": {
"type": "string",
"example": "預約已確認"
},
"message": {
"type": "string",
"example": "您的預約已由教練確認"
},
"read_at": {
"type": "string",
"example": null,
"nullable": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/notifications/unread-count": {
"get": {
"tags": [
"通知"
],
"summary": "取得未讀通知數量",
"description": "取得未讀通知數量",
"operationId": "getUnreadNotificationCount",
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"unread_count": {
"type": "integer",
"example": 3
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/notifications/{id}/read": {
"patch": {
"tags": [
"通知"
],
"summary": "標記單一通知為已讀",
"description": "標記單一通知為已讀",
"operationId": "markNotificationRead",
"parameters": [
{
"name": "id",
"in": "path",
"description": "通知 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "標記成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "通知已標記為已讀"
}
},
"type": "object"
}
}
}
},
"404": {
"description": "通知不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/notifications/read-all": {
"patch": {
"tags": [
"通知"
],
"summary": "全部通知標記為已讀",
"description": "全部通知標記為已讀",
"operationId": "markAllNotificationsRead",
"responses": {
"200": {
"description": "標記成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "所有通知已標記為已讀"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/notifications/{id}": {
"delete": {
"tags": [
"通知"
],
"summary": "刪除通知",
"description": "刪除通知",
"operationId": "deleteNotification",
"parameters": [
{
"name": "id",
"in": "path",
"description": "通知 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "通知已刪除"
}
},
"type": "object"
}
}
}
},
"404": {
"description": "通知不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/offers": {
"get": {
"tags": [
"教練課程"
],
"summary": "取得自己的課程列表",
"description": "回傳當前服務提供者的所有課程(分頁)",
"operationId": "listProviderOffers",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"post": {
"tags": [
"教練課程"
],
"summary": "建立課程",
"description": "服務提供者建立新的潛水課程",
"operationId": "createProviderOffer",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"title",
"description",
"region",
"price",
"max_participants"
],
"properties": {
"title": {
"type": "string",
"example": "基礎開放水域課程"
},
"description": {
"type": "string",
"example": "適合初學者的 OWD 課程"
},
"region": {
"type": "string",
"example": "墾丁"
},
"price": {
"type": "number",
"format": "float",
"example": 8500
},
"max_participants": {
"type": "integer",
"example": 6
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"初學",
"OWD"
]
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "課程建立成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "課程建立成功"
},
"data": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "無權限",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/offers/{id}": {
"get": {
"tags": [
"教練課程"
],
"summary": "取得單一課程(Provider 視角)",
"description": "取得自己的指定課程,非本人課程回傳 403",
"operationId": "getProviderOffer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"put": {
"tags": [
"教練課程"
],
"summary": "更新課程",
"description": "更新課程",
"operationId": "updateProviderOffer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"title": {
"type": "string",
"example": "進階開放水域課程"
},
"description": {
"type": "string",
"example": "AOWD 課程"
},
"region": {
"type": "string",
"example": "小琉球"
},
"price": {
"type": "number",
"format": "float",
"example": 12000
},
"max_participants": {
"type": "integer",
"example": 4
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"進階",
"AOWD"
]
},
"is_active": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"教練課程"
],
"summary": "刪除課程",
"description": "刪除課程",
"operationId": "deleteProviderOffer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "課程已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/offers/{id}/cover": {
"post": {
"tags": [
"教練圖片"
],
"summary": "上傳封面圖片",
"description": "上傳課程封面圖片(multipart/form-data",
"operationId": "uploadOfferCover",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"required": [
"cover_image"
],
"properties": {
"cover_image": {
"description": "封面圖片(jpg/png,最大 5MB",
"type": "string",
"format": "binary"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "上傳成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"cover_image_url": {
"type": "string",
"example": "https://example.com/covers/1.jpg"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "圖片驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"教練圖片"
],
"summary": "刪除封面圖片",
"description": "刪除封面圖片",
"operationId": "deleteOfferCover",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "封面圖片已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/offers/{id}/images": {
"post": {
"tags": [
"教練圖片"
],
"summary": "上傳相簿圖片",
"description": "新增課程相簿圖片(multipart/form-data,可多張)",
"operationId": "uploadOfferImages",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"required": [
"images[]"
],
"properties": {
"images[]": {
"description": "相簿圖片(每張最大 5MB",
"type": "array",
"items": {
"type": "string",
"format": "binary"
}
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "上傳成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"images": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"https://example.com/img/1.jpg"
]
}
},
"type": "object"
}
}
}
},
"422": {
"description": "圖片驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/images/{id}": {
"delete": {
"tags": [
"教練圖片"
],
"summary": "刪除相簿圖片",
"description": "刪除相簿圖片",
"operationId": "deleteOfferImage",
"parameters": [
{
"name": "id",
"in": "path",
"description": "圖片 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "圖片已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人圖片",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "圖片不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/schedules": {
"get": {
"tags": [
"教練時段"
],
"summary": "取得時段列表",
"description": "回傳服務提供者的所有時段,可依 offer_id 篩選",
"operationId": "listProviderSchedules",
"parameters": [
{
"name": "offer_id",
"in": "query",
"description": "課程 ID 篩選",
"required": false,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CourseSchedule"
}
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"post": {
"tags": [
"教練時段"
],
"summary": "建立時段",
"description": "建立時段",
"operationId": "createProviderSchedule",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"offer_id",
"start_date",
"end_date",
"available_slots"
],
"properties": {
"offer_id": {
"type": "integer",
"example": 1
},
"start_date": {
"type": "string",
"format": "date",
"example": "2025-07-01"
},
"end_date": {
"type": "string",
"format": "date",
"example": "2025-07-03"
},
"available_slots": {
"type": "integer",
"example": 4
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "時段建立成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/CourseSchedule"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "驗證失敗",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"403": {
"description": "非本人課程",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/schedules/{id}": {
"put": {
"tags": [
"教練時段"
],
"summary": "更新時段",
"description": "更新時段",
"operationId": "updateProviderSchedule",
"parameters": [
{
"name": "id",
"in": "path",
"description": "時段 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"start_date": {
"type": "string",
"format": "date",
"example": "2025-07-05"
},
"end_date": {
"type": "string",
"format": "date",
"example": "2025-07-07"
},
"available_slots": {
"type": "integer",
"example": 6
},
"is_active": {
"type": "boolean",
"example": true
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "更新成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/CourseSchedule"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人時段",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "時段不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"教練時段"
],
"summary": "刪除時段",
"description": "刪除時段",
"operationId": "deleteProviderSchedule",
"parameters": [
{
"name": "id",
"in": "path",
"description": "時段 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "刪除成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "時段已刪除"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人時段",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"404": {
"description": "時段不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/bookings": {
"get": {
"tags": [
"教練預約"
],
"summary": "取得收到的預約列表",
"description": "分頁回傳服務提供者收到的所有預約",
"operationId": "listProviderBookings",
"parameters": [
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數",
"schema": {
"type": "integer",
"default": 15
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Booking"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/bookings/{id}/confirm": {
"put": {
"tags": [
"教練預約"
],
"summary": "確認預約",
"description": "確認預約",
"operationId": "confirmBooking",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "確認成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已確認"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程的預約",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "狀態不允許確認",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/bookings/{id}/reject": {
"put": {
"tags": [
"教練預約"
],
"summary": "拒絕預約",
"description": "拒絕預約",
"operationId": "rejectBooking",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "拒絕成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已拒絕"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程的預約",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "狀態不允許拒絕",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/bookings/{id}/complete": {
"put": {
"tags": [
"教練預約"
],
"summary": "標記預約完成",
"description": "標記預約完成",
"operationId": "completeBookingByProvider",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "標記成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已完成"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程的預約",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "狀態不允許完成",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/provider/bookings/{id}/cancel": {
"put": {
"tags": [
"教練預約"
],
"summary": "取消預約(Provider",
"description": "取消預約(Provider",
"operationId": "cancelBookingByProvider",
"parameters": [
{
"name": "id",
"in": "path",
"description": "預約 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取消成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "預約已取消"
},
"data": {
"$ref": "#/components/schemas/Booking"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "非本人課程的預約",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
},
"422": {
"description": "狀態不允許取消",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/diving-offers": {
"get": {
"tags": [
"公開課程"
],
"summary": "查詢潛水課程列表",
"description": "支援關鍵字、地區、標籤篩選,回傳分頁結果",
"operationId": "listDivingOffers",
"parameters": [
{
"name": "q",
"in": "query",
"description": "關鍵字搜尋",
"schema": {
"type": "string"
}
},
{
"name": "region",
"in": "query",
"description": "地區篩選",
"schema": {
"type": "string",
"example": "墾丁"
}
},
{
"name": "tag",
"in": "query",
"description": "標籤篩選",
"schema": {
"type": "string",
"example": "OWD"
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數(預設 15,最大 50",
"schema": {
"type": "integer",
"default": 15,
"maximum": 50
}
},
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
}
],
"responses": {
"200": {
"description": "查詢成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
}
}
}
}
}
},
"/diving-offers/{id}": {
"get": {
"tags": [
"公開課程"
],
"summary": "取得單一潛水課程",
"description": "回傳課程詳情,包含封面圖片與相簿",
"operationId": "getDivingOffer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"$ref": "#/components/schemas/DivingOffer"
}
},
"type": "object"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
}
}
},
"/diving-offers/{id}/reviews": {
"get": {
"tags": [
"公開課程"
],
"summary": "取得課程評價列表",
"description": "回傳評分摘要、分頁評價列表與分頁 meta",
"operationId": "listOfferReviews",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
},
{
"name": "sort",
"in": "query",
"description": "排序方式(newest / helpful",
"schema": {
"type": "string",
"default": "newest",
"enum": [
"newest",
"helpful"
]
}
},
{
"name": "page",
"in": "query",
"description": "頁碼",
"schema": {
"type": "integer",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "每頁筆數(預設 15,最大 50",
"schema": {
"type": "integer",
"default": 15,
"maximum": 50
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"properties": {
"summary": {
"properties": {
"average_rating": {
"type": "number",
"format": "float",
"example": 4.2
},
"total_reviews": {
"type": "integer",
"example": 24
},
"distribution": {
"properties": {
"1": {
"type": "integer",
"example": 1
},
"2": {
"type": "integer",
"example": 2
},
"3": {
"type": "integer",
"example": 3
},
"4": {
"type": "integer",
"example": 8
},
"5": {
"type": "integer",
"example": 10
}
},
"type": "object"
}
},
"type": "object"
},
"reviews": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Review"
}
},
"meta": {
"$ref": "#/components/schemas/PaginationMeta"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
}
}
},
"/diving-offers/{id}/schedules": {
"get": {
"tags": [
"公開課程"
],
"summary": "取得課程時段列表",
"description": "回傳指定課程的所有可用時段",
"operationId": "listOfferSchedules",
"parameters": [
{
"name": "id",
"in": "path",
"description": "課程 ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "取得成功",
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"type": "boolean",
"example": true
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CourseSchedule"
}
}
},
"type": "object"
}
}
}
},
"404": {
"description": "課程不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiErrorResponse"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"PaginationMeta": {
"properties": {
"current_page": {
"type": "integer",
"example": 1
},
"last_page": {
"type": "integer",
"example": 5
},
"per_page": {
"type": "integer",
"example": 15
},
"total": {
"type": "integer",
"example": 72
}
},
"type": "object"
},
"ApiErrorResponse": {
"properties": {
"status": {
"type": "boolean",
"example": false
},
"message": {
"type": "string",
"example": "操作失敗"
},
"errors": {
"type": "object",
"nullable": true
}
},
"type": "object"
},
"DivingOffer": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"provider_id": {
"type": "integer",
"example": 3
},
"title": {
"type": "string",
"example": "基礎開放水域課程"
},
"description": {
"type": "string",
"example": "適合初學者的 OWD 課程"
},
"region": {
"type": "string",
"example": "墾丁"
},
"price": {
"type": "number",
"format": "float",
"example": 8500
},
"max_participants": {
"type": "integer",
"example": 6
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"初學",
"OWD"
]
},
"cover_image_url": {
"type": "string",
"example": "https://example.com/image.jpg",
"nullable": true
},
"images": {
"type": "array",
"items": {
"type": "string"
},
"example": []
},
"is_active": {
"type": "boolean",
"example": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"Review": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"offer_id": {
"type": "integer",
"example": 1
},
"rating": {
"type": "integer",
"maximum": 5,
"minimum": 1,
"example": 4
},
"comment": {
"type": "string",
"example": "課程非常棒!",
"nullable": true
},
"is_anonymous": {
"type": "boolean",
"example": false
},
"helpful_count": {
"type": "integer",
"example": 3
},
"has_voted": {
"type": "boolean",
"example": false
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"CourseSchedule": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"offer_id": {
"type": "integer",
"example": 1
},
"start_date": {
"type": "string",
"format": "date",
"example": "2025-07-01"
},
"end_date": {
"type": "string",
"format": "date",
"example": "2025-07-03"
},
"available_slots": {
"type": "integer",
"example": 4
},
"is_active": {
"type": "boolean",
"example": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"Booking": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"member_id": {
"type": "integer",
"example": 5
},
"offer_id": {
"type": "integer",
"example": 1
},
"schedule_id": {
"type": "integer",
"example": 2
},
"status": {
"type": "string",
"enum": [
"pending",
"confirmed",
"rejected",
"completed",
"cancelled"
],
"example": "pending"
},
"participants": {
"type": "integer",
"example": 2
},
"note": {
"type": "string",
"example": "",
"nullable": true
},
"created_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
},
"updated_at": {
"type": "string",
"example": "2025-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"AdminProfile": {
"title": "管理員個人資料",
"description": "管理員的詳細個人資料",
"properties": {
"id": {
"description": "資料ID",
"type": "integer",
"format": "int64",
"example": 1
},
"user_id": {
"description": "關聯的使用者ID",
"type": "integer",
"format": "int64",
"example": 1
},
"position": {
"description": "職位",
"type": "string",
"example": "系統管理員"
},
"department": {
"description": "部門",
"type": "string",
"example": "IT部門"
},
"permissions": {
"description": "權限列表",
"type": "array",
"items": {
"type": "string",
"example": "manage_users"
}
},
"created_at": {
"description": "創建時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"description": "更新時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"MemberProfile": {
"title": "會員個人資料",
"description": "會員的詳細個人資料",
"properties": {
"id": {
"description": "資料ID",
"type": "integer",
"format": "int64",
"example": 1
},
"user_id": {
"description": "關聯的使用者ID",
"type": "integer",
"format": "int64",
"example": 1
},
"birthday": {
"description": "生日",
"type": "string",
"format": "date",
"example": "1990-01-01"
},
"gender": {
"description": "性別",
"type": "string",
"enum": [
"male",
"female",
"other"
],
"example": "male"
},
"address": {
"description": "地址",
"type": "string",
"example": "台北市信義區某街123號"
},
"emergency_contact": {
"description": "緊急聯絡人",
"type": "string",
"example": "王大明"
},
"emergency_phone": {
"description": "緊急聯絡電話",
"type": "string",
"example": "0987654321"
},
"created_at": {
"description": "創建時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"description": "更新時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"ProviderProfile": {
"title": "服務提供者資料",
"description": "服務提供者的詳細資料",
"properties": {
"id": {
"description": "資料ID",
"type": "integer",
"format": "int64",
"example": 1
},
"user_id": {
"description": "關聯的使用者ID",
"type": "integer",
"format": "int64",
"example": 1
},
"business_name": {
"description": "業者名稱",
"type": "string",
"example": "藍海潛水中心"
},
"business_license": {
"description": "營業執照號碼",
"type": "string",
"example": "A123456789"
},
"description": {
"description": "業者描述",
"type": "string",
"example": "專業潛水中心,提供各種潛水課程和裝備租賃服務"
},
"contact_person": {
"description": "聯絡人",
"type": "string",
"example": "張三"
},
"contact_phone": {
"description": "聯絡電話",
"type": "string",
"example": "0912345678"
},
"contact_email": {
"description": "聯絡電子郵件",
"type": "string",
"example": "contact@bluedive.com"
},
"address": {
"description": "營業地址",
"type": "string",
"example": "台灣屏東縣恆春鎮XXX路123號"
},
"dive_sites": {
"description": "提供的潛點",
"type": "string",
"example": "墾丁,綠島,蘭嶼"
},
"services": {
"description": "提供的服務",
"type": "string",
"example": "體驗潛水,初級潛水課程,進階潛水課程,裝備租賃"
},
"certifications": {
"description": "業者相關認證",
"type": "string",
"example": "PADI五星級潛水中心,SSI認證中心"
},
"facilities": {
"description": "設施",
"type": "string",
"example": "空氣填充站,沖洗區,更衣室,休息區"
},
"business_hours": {
"description": "營業時間",
"type": "string",
"example": "週一至週五 09:00-18:00,週六日 08:00-19:00"
},
"verification_status": {
"description": "審核狀態:unsubmitted / pending / approved / rejected",
"type": "string",
"example": "approved"
},
"rejection_reason": {
"description": "駁回原因(rejected 時有值)",
"type": "string",
"example": null,
"nullable": true
},
"is_verified": {
"description": "是否通過平台驗證(相容欄位,= verification_status 為 approved",
"type": "boolean",
"example": true
},
"rating": {
"description": "評分",
"type": "number",
"format": "float",
"example": 4.8
},
"website": {
"description": "官方網站",
"type": "string",
"example": "https://www.bluedive.com"
},
"social_media": {
"description": "社群媒體連結",
"type": "string",
"example": "https://www.facebook.com/bluedive"
},
"logo_url": {
"description": "業者標誌URL",
"type": "string",
"example": "https://example.com/logo.png"
},
"banner_url": {
"description": "業者橫幅URL",
"type": "string",
"example": "https://example.com/banner.png"
},
"is_active": {
"description": "是否啟用",
"type": "boolean",
"example": true
},
"created_at": {
"description": "創建時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"description": "更新時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
}
},
"type": "object"
},
"User": {
"title": "使用者",
"description": "使用者資料模型",
"properties": {
"id": {
"description": "使用者ID",
"type": "integer",
"format": "int64",
"example": 1
},
"name": {
"description": "使用者姓名",
"type": "string",
"example": "王小明"
},
"email": {
"description": "電子郵件",
"type": "string",
"format": "email",
"example": "user@example.com"
},
"phone": {
"description": "電話號碼",
"type": "string",
"example": "0912345678"
},
"role": {
"description": "角色",
"type": "string",
"enum": [
"member",
"provider",
"admin"
],
"example": "member"
},
"is_active": {
"description": "是否啟用",
"type": "boolean",
"example": true
},
"email_verified_at": {
"description": "電子郵件驗證時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"created_at": {
"description": "創建時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"updated_at": {
"description": "更新時間",
"type": "string",
"format": "date-time",
"example": "2023-01-01T00:00:00.000000Z"
},
"memberProfile": {
"$ref": "#/components/schemas/MemberProfile"
},
"providerProfile": {
"$ref": "#/components/schemas/ProviderProfile"
},
"adminProfile": {
"$ref": "#/components/schemas/AdminProfile"
}
},
"type": "object"
}
},
"securitySchemes": {
"bearerAuth": {
"type": "http",
"bearerFormat": "JWT",
"scheme": "bearer"
}
}
},
"tags": [
{
"name": "Admin 統計",
"description": "管理員平台統計"
},
{
"name": "Admin 會員管理",
"description": "管理員的會員帳號管理"
},
{
"name": "Admin 教練管理",
"description": "管理員的服務提供者帳號管理"
},
{
"name": "Admin 課程管理",
"description": "管理員的課程、預約、評價管理"
},
{
"name": "會員",
"description": "會員相關操作"
},
{
"name": "服務提供者",
"description": "服務提供者相關操作"
},
{
"name": "管理員",
"description": "管理員相關操作"
},
{
"name": "認證",
"description": "通用認證操作(登出、取得當前使用者)"
},
{
"name": "Google OAuth",
"description": "Google OAuth 2.0 社群登入"
},
{
"name": "會員預約",
"description": "會員的預約管理"
},
{
"name": "會員評價",
"description": "會員的評價管理"
},
{
"name": "通知",
"description": "站內通知管理(Member / Provider 共用)"
},
{
"name": "教練課程",
"description": "服務提供者的課程管理"
},
{
"name": "教練圖片",
"description": "服務提供者的課程圖片管理"
},
{
"name": "教練時段",
"description": "服務提供者的課程時段管理"
},
{
"name": "教練預約",
"description": "服務提供者的預約管理"
},
{
"name": "公開課程",
"description": "無需認證的公開潛水課程查詢端點"
}
]
}