Files
CFDivePlatform/openspec/specs/diving-offers-api/spec.md
T
a620906209 550e2fc97a feat:實作 Member Portal MVP 前端與後端整合
後端:
- 新增 DivingOffer Model / DivingOfferController(列表+詳情 API,支援搜尋/篩選/分頁)
- 修正 Google OAuth callback 改為 redirect 至前端(SocialAuthController)
- 新增 config/cors.php 允許前端 origin
- .gitignore 新增 frontend/ 排除規則

前端(frontend/):
- Vue 3 + Vite + Tailwind CSS + Pinia + Vue Router
- 頁面:首頁、課程列表、課程詳情、登入、註冊、個人資料、OAuth callback
- 整合至 Docker(multi-stage build,nginx 靜態服務於 port 5173)

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

2.1 KiB
Raw Blame History

ADDED Requirements

Requirement: 課程列表 API

後端 SHALL 提供公開的 GET /api/diving-offers endpoint,回傳分頁的潛水課程列表,支援關鍵字搜尋與篩選,無需認證即可存取。

Scenario: 取得全部課程列表

  • WHEN 客戶端發送 GET /api/diving-offers 且不帶任何參數
  • THEN 回傳 HTTP 200body 包含 { data: [...], meta: { total, per_page, current_page } },預設每頁 12 筆

Scenario: 依關鍵字搜尋課程

  • WHEN 客戶端發送 GET /api/diving-offers?q=墾丁
  • THEN 回傳 titlelocation 包含「墾丁」的課程列表

Scenario: 依地區篩選課程

  • WHEN 客戶端發送 GET /api/diving-offers?region=南部
  • THEN 只回傳 region 欄位等於「南部」的課程

Scenario: 依標籤篩選課程

  • WHEN 客戶端發送 GET /api/diving-offers?tag=初學者
  • THEN 只回傳 tag 欄位包含「初學者」的課程

Scenario: 分頁參數

  • WHEN 客戶端發送 GET /api/diving-offers?page=2&per_page=6
  • THEN 回傳第 2 頁資料,每頁 6 筆,meta 包含正確的分頁資訊

Requirement: 課程詳情 API

後端 SHALL 提供公開的 GET /api/diving-offers/{id} endpoint,回傳單一課程完整資訊,無需認證即可存取。

Scenario: 取得存在的課程詳情

  • WHEN 客戶端發送 GET /api/diving-offers/1(該 id 存在)
  • THEN 回傳 HTTP 200body 包含 { data: { id, title, location, spot, rating, reviews, price, badges, description, tag, region, created_at } }

Scenario: 課程不存在

  • WHEN 客戶端發送 GET /api/diving-offers/99999(該 id 不存在)
  • THEN 回傳 HTTP 404body 包含 { message: "課程不存在" }

Requirement: CORS 允許前端 Origin

後端 SHALL 在 config/cors.php 中允許來自前端開發 originhttp://localhost:5173)的跨域請求。

Scenario: 前端跨域請求課程列表

  • WHEN 瀏覽器從 http://localhost:5173 發送 GET /api/diving-offers
  • THEN 後端回應包含正確的 CORS header,瀏覽器不阻擋請求