{ "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/providers/{id}/toggle-verified": { "put": { "tags": [ "Admin 教練管理" ], "summary": "切換教練審核狀態", "description": "通過或撤銷教練審核,回傳新的 is_verified 狀態", "operationId": "toggleProviderVerified", "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_verified": { "type": "boolean", "example": true } }, "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-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/register": { "post": { "tags": [ "管理員" ], "summary": "管理員註冊", "description": "建立新的管理員帳號", "operationId": "registerAdmin", "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": "admin@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" }, "position": { "description": "職位", "type": "string", "example": "系統管理員" }, "department": { "description": "部門", "type": "string", "example": "IT部門" } }, "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" } } } } } } }, "/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" }, "is_verified": { "description": "是否通過平台驗證", "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": "無需認證的公開潛水課程查詢端點" } ] }