Files
CFDivePlatform/openspec/config.yaml
T
2026-10-14 23:56:26 +08:00

100 lines
6.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
schema: spec-driven
context: |
## 專案:CFDivePlatform
潛水課程媒合平台,連結潛水教練(Provider)與學員(Member)。
各功能的行為以 `openspec/specs/` 為準;本段只描述專案背景與慣例,不逐項複製規格內容。
每次歸檔(archive)後,請檢查本段是否需要更新。
## 架構
- 後端:Laravel 11 + Sanctum(Bearer token)+ MySQL 8 + Redis(cache / session / queue)
- 即時通訊:Laravel Reverb(WebSocket),前端以 Laravel Echo 連線
- 檔案儲存:`public` disk,支援切換為 S3 相容物件儲存(見 `file-storage-s3` spec)
- 前端:Vue 3 + Vite + Tailwind CSS + Pinia + Vue Router 4 + Axios
- 原始碼在 `frontend/`(同一個 repo)
- 部署:Docker Compose,程式碼與 vendor 烘進 image,不使用 bind mount(見 `image-baked-deployment` spec)
- 服務:app(php-fpm)、nginx、frontend、db、redis、reverb、queue-worker、scheduler
- push master 會觸發 Gitea Actions 自動部署,因此變更一律走 PR,禁止直接 push master
- 測試:PHPUnit Feature / Unit,CI 與本機預設使用 SQLite;涉及 `lockForUpdate` 等行鎖行為的測試在 SQLite 上不具驗證力
## 使用者角色
- `member`:一般會員,瀏覽/搜尋課程、預約、聊天、評價;Email 或 Google OAuth 登入
- `provider`:教練/業者,管理課程、時段、預約;需通過資格審核才會公開課程與接受預約
- `admin`:平台管理員;帳號只能由主機端 `php artisan app:create-admin` 建立,不提供公開註冊
- 角色存於 `users.role`,三種角色各有獨立的登入端點與 Profile 資料表
## 已實作範圍(細節見對應 spec)
- Member Portal、Coach Portal(`/coach/*`)、Admin Panel(`/admin/*`)
- 認證:三角色登入、Token Refresh、登入限流、帳號鎖定、OAuth state 驗證
- 課程(diving offers)公開查詢與教練 CRUD、課程圖片上傳(含伺服器端壓縮)
- 課程時段、預約生命週期(pending → confirmed → completed / 取消)、名額超賣防護
- 預約即時訊息(文字 + 圖片、已讀回執)、使用者在線狀態
- 評價(含匿名、編輯紀錄、有幫助投票)
- 站內通知與 Email 通知(除即時訊息通知外皆經 Queue 處理)
- 教練資格審核(證照上傳、送審、通過 / 駁回 / 撤銷)
- 排程:逾期 pending 預約自動失效、已結束預約自動完成
- Swagger(l5-swagger)API 文件,註解集中於 `app/Docs/`
## 尚未實作
- 金流整合
- 訂閱方案(`subscriptions` / `plans` 資料表已於 2026-05-25 移除)
## 關鍵資料模型
- `users`:role(member / provider / admin)、`is_active`
- `provider_profiles`:業者資料與 `verification_status`;`provider_certifications`:證照
- `member_profiles`、`admin_profiles`
- `diving_offers`(含 `provider_id`、`cover_image`)、`course_images`
- `course_schedules`(含 `max_participants` / `current_participants`)、`bookings`
- `reviews`、`review_edits`、`review_votes`
- `booking_messages`、`notifications`、`social_accounts`
## 前端慣例
- 三組認證各自獨立:Axios 實例、Pinia store、storage key 皆分開
- Member:`src/stores/auth.js`、`src/api/axios.js`,sessionStorage `token` / `user`
- Coach:`src/stores/coachAuth.js`、`src/api/coachAxios.js`,sessionStorage `coach_token` / `coach_user`
- Admin:`src/stores/adminAuth.js`、`src/api/adminAxios.js`,localStorage `admin_token` / `admin_user`
(與其他兩者不一致為已知議題,見 docs/analysis/2026-10-14-project-review-todo.md M4)
- Coach 頁面包在 `CoachLayout.vue`,Admin 頁面包在 `AdminLayout.vue`
- Protected 路由以 route meta 標示:`requiresAuth`(member)、`requiresCoach`、`requiresAdmin`
- 401 時自動以 refresh token 換新並重試
## 後端慣例
- Controller 位於 `app/Http/Controllers/API/`,Swagger 註解位於 `app/Docs/`
- 路由集中於 `routes/api.php`;admin 群組以 `admin` middleware 保護
- member / provider 路由群組目前僅有 `auth:sanctum`,角色檢查需在 Controller 內自行處理
(已知缺口,見 docs/analysis/2026-10-14-project-review-todo.md H1;新增路由時不可假設已有角色保護)
## API 回應格式
成功:`{ status: true, message?: "...", data: {...} 或 [...] }`
失敗:`{ status: false, message: "...", errors?: {...} }`
rules:
proposal:
- 必須列出受影響的主規格(`openspec/specs/` 下的 capability 名稱)
- 必須說明是否影響既有 API 回應格式或前端行為
specs:
- 每個 Requirement 至少要有一個 `#### Scenario`
- Scenario 必須具體到可直接轉成測試(明確的前置條件、動作、預期的 HTTP 狀態碼與回應內容)
- 涉及角色權限的 Requirement,必須明確寫出各角色(member / provider / admin / 未登入)的預期結果
design:
- 若涉及 CLAUDE.md 列出的安全觸發條件(外部輸入、資料庫讀寫、身份驗證/授權、檔案上傳、外部 API),必須包含「安全確認」段落,回答輸入驗證、資料庫存取方式、權限檢查層級
- 新增或修改的路由必須註明所掛的角色 middleware 或 Controller 內的所有權檢查
tasks:
- 後端任務標記 [後端],前端任務標記 [前端],整合測試標記 [整合測試]
- 每個 task 描述應包含具體的檔案路徑或方法名稱
- 每個 spec 的 Scenario 至少要對應一個 [整合測試] task,缺少對應者不得進入實作
- 手動驗證類 task 放在最後一個 group
operations:
apply:
guidance:
- 實作前先逐一對照 spec 的每個 `#### Scenario` 與 tasks.md 的測試 task([整合測試] 或單元測試);有 Scenario 沒有對應測試 task 時停止實作,列出缺漏並詢問使用者是否補上 tasks(CLAUDE.md 規定)
- 涉及權限行為時,確認有 member / provider / admin / 未登入的跨角色測試 task
- design.md 觸及安全觸發條件但缺「安全確認」段落時,停止實作並回報
- 所有 task 完成後,先執行 `verify-and-report` skill(php artisan test、pint、AC 測試涵蓋、spec 同步狀態),再建議歸檔
- 實作在功能分支進行,禁止直接在 master 上修改
archive:
guidance:
- 歸檔後檢查 `openspec/config.yaml` 的 context(已實作範圍、尚未實作)是否需要更新,這份檔案不會自動維護
- 歸檔是獨立的 PR,不要與實作混在同一個分支(CLAUDE.md「Git 與 PR 流程」)