a620906209
|
c3572682ad
|
chore(openspec): 歸檔 cloud-ready-p1 + 同步主規格
Run Tests / test (pull_request) Successful in 30s
- 所有 task 驗證完成(7.1 stderr log / 7.2 無新增日誌檔 / 7.3 session 走 Redis)
- 同步 env-cloud-annotations 主 spec(LOG_CHANNEL 取代 LOG_STACK + 新增 scenario)
- 新增 scheduler-container 主 spec(獨立 container 取代 cron daemon)
- 移至 archive/2026-06-18-cloud-ready-p1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-18 03:05:57 +08:00 |
|
a620906209
|
d423cf5079
|
feat(infra): 雲端就緒 P1 — Session/Log/Scheduler 改造
Run Tests / test (pull_request) Successful in 29s
- Dockerfile:移除 cron 安裝與 scheduler crontab 設定
- docker-entrypoint.sh:移除 service cron start
- docker-compose.yml:新增 scheduler service(php artisan schedule:work)
- .env.example:SESSION_DRIVER=redis、LOG_CHANNEL=stderr、移除 LOG_STACK/LOG_DAILY_DAYS
- docs/STARTUP.md:新增 Log 查看、VPS 維護窗口操作與 Rollback 說明
VPS 部署需手動更新 .env 並執行 docker compose up -d --build(詳見 STARTUP.md §11)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-18 02:34:01 +08:00 |
|
a620906209
|
e08c6652a5
|
chore(openspec): 歸檔 cloud-ready-zero-impact + 同步主規格
Run Tests / test (pull_request) Successful in 29s
- openspec/changes/archive/2026-06-18-cloud-ready-zero-impact/:change 歸檔
- openspec/specs/compose-cloud-baseline/:新增主規格(healthcheck + override 隔離)
- openspec/specs/env-cloud-annotations/:新增主規格(.env.example 雲端標示)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-18 02:01:12 +08:00 |
|
a620906209
|
be629feef9
|
feat(infra): 雲端就緒零影響改動 (compose overlay + healthcheck + env)
Run Tests / test (pull_request) Successful in 30s
- docker-compose.yml:app healthcheck 改用 nc -z 127.0.0.1 9000 驗證 PHP-FPM port
- docker-compose.yml:移除 phpmyadmin、mailpit(開發工具不屬於正式服務)
- compose.override.yml:新增,含 phpmyadmin(8081)、mailpit(8025)port mapping
- .env.example:QUEUE_CONNECTION 預設改 redis;補充 FILESYSTEM_DISK、LOG_STACK、SESSION_DRIVER 雲端注意事項
- docs/STARTUP.md:新增「部署模式」章節,明確區分 VPS 與雲端 -f 指令
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-18 01:48:24 +08:00 |
|
a620906209
|
80f5cf179f
|
chore(openspec): 歸檔 feature-test-coverage、provider-verification-workflow 變更
Run Tests / test (pull_request) Failing after 1m53s
兩個 change 全任務完成(feature-test-coverage 40/40、provider-verification-workflow 48/48)。
同步規格:
- feature-test-coverage/spec.md 補齊 ## Requirements 區塊標頭(結構修正)
- Admin 教練審核 scenario 改為 approve 端點(toggle-verified 已由 #36 移除)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 19:19:52 +08:00 |
|
a620906209
|
4383239bab
|
Merge pull request 'test(feature): 補齊五個核心業務流程 Feature test——Offer/Schedule CRUD、Admin 管理、通知觸發、預約列表' (#38) from feat/feature-test-coverage into master
Deploy Production / deploy (push) Successful in 19s
Run Tests / test (push) Failing after 1m50s
Reviewed-on: #38
|
2026-06-16 10:24:17 +00:00 |
|
a620906209
|
49a4b89655
|
test(feature): 補齊五個核心業務流程 Feature test——Offer/Schedule CRUD、Admin 管理、通知觸發、預約列表
Run Tests / test (pull_request) Successful in 1m51s
ProviderOfferCrudTest(7 案例):store/update/destroy 正常流程 + 所有權邊界(403)+ 未認證(401)
ProviderScheduleCrudTest(7 案例):store/update/destroy + 容量不變式(422)+ destroy 同步取消 active bookings
AdminUserManagementTest(5 案例):列表角色過濾 + toggle-active/toggle-verified DB 副作用 + 非 admin 403
NotificationTriggerTest(5 案例):5 條直接觸發路徑,收件者各不同(BookingCreated/CancelledByMember → provider;其餘 → member)
BookingListTest(4 案例):三角色資料隔離邊界 + 未認證 401
全套件 215 passed / 529 assertions,零 regression。
同步新增 openspec/changes/feature-test-coverage/ 與 openspec/specs/feature-test-coverage/spec.md。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-16 18:23:11 +08:00 |
|
a620906209
|
a18f52b2e8
|
Merge pull request 'chore(openspec): 歸檔 course-image-compression 變更' (#35) from chore/archive-cic into master
Deploy Production / deploy (push) Successful in 12s
Run Tests / test (push) Successful in 6m11s
Reviewed-on: #35
|
2026-06-11 19:41:00 +00:00 |
|
a620906209
|
43720482c4
|
feat(verification): 教練審核流程完整版——狀態機/證照送審/Admin 裁決/通知
Run Tests / test (pull_request) Successful in 2m3s
實作 openspec change provider-verification-workflow(25/25 tasks):
- is_verified 升級為 verification_status 四狀態機(unsubmitted/pending/
approved/rejected),migration 自動轉換既有資料,API 以 accessor 保留
is_verified 相容輸出
- 教練端:證照上傳(≤3 張、複用 CompressesImages)、送審、駁回原因
顯示與重送(/coach/verification 新頁面)
- Admin 端:審核佇列、通過/駁回(原因必填)、撤銷 approved;移除
toggle-verified 端點(防繞過狀態機);裁決後 flush 課程快取
- 通知:審核通過/駁回(站內+Email,駁回含原因)
- 可見性與預約入口改判 approved(行為等價)
- 測試 +18(ProviderVerificationTest 10、AdminVerificationTest 8),
既有 4 個測試檔 helper 遷移;Swagger 同步
- 規格同步:provider-verification 全面改寫、admin-user-management
toggle 段落改為移除聲明
容器內全套件 173 passed / 439 assertions。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-12 00:26:12 +08:00 |
|
a620906209
|
a7d5f81890
|
chore(openspec): 歸檔 course-image-compression 變更
Run Tests / test (pull_request) Successful in 1m58s
實作已 merge(PR #34),規格增量已於實作時同步至主規格。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 23:53:15 +08:00 |
|
a620906209
|
6414222a18
|
feat(images): 課程圖片伺服器端壓縮——scaleDown 2048 + JPEG 85,上限放寬至 10MB
Run Tests / test (pull_request) Successful in 2m0s
實作 openspec change course-image-compression(O3.1 體感優化):
- 新增 App\Traits\CompressesImages:與聊天圖片管線參數一致的共用壓縮邏輯
- CourseImageController 封面/相簿套用壓縮,上傳上限 2MB→10MB(容納手機原圖)
- 前端課程卡片與相簿縮圖加 loading=lazy(詳情頁首屏封面刻意不加)
- CourseImageTest +4 案例(10MB 邊界、轉存 .jpg、>2048 縮小、小圖不放大)
- course-image-upload 主規格同步(新增伺服器端壓縮 requirement)
容器內全套件 155 passed / 400 assertions。
聊天端改用 trait 留待後續(該處無測試覆蓋,不在本 change 重構)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 23:43:24 +08:00 |
|
a620906209
|
5825e74d2d
|
chore(openspec): 歸檔 provider-verification-gaps 變更
Run Tests / test (pull_request) Successful in 1m59s
實作已 merge(PR #31),規格增量已於實作時同步至主規格。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 22:59:32 +08:00 |
|
a620906209
|
90d0a57e73
|
feat(offers): 補齊 provider-verification 可見性缺口——子端點過濾與預約入口檢查
Run Tests / test (pull_request) Successful in 1m56s
實作 openspec change provider-verification-gaps(8/8 tasks):
- schedules/reviews publicList 套用 visibleToPublic,隱藏課程回 404
- MemberBookingController::store Layer 1 擋未驗證教練課程的新預約(422)
- 政策:教練被取消驗證只擋新預約,既有 pending/confirmed/completed 照常
- 主規格 Notes 已知限制轉為正式 Requirements
- 測試 +5(可見性子端點 3、預約入口 2),既有 booking/review 測試 helper
補 verified ProviderProfile
- 容器內全套件 151 passed / 388 assertions;另以 demo 資料端到端驗證
(已驗證教練 200/200/200、未驗證 404/404/404)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 22:48:59 +08:00 |
|
a620906209
|
99cf35c1ec
|
docs: 稽核文檔改為執行紀錄、開 provider-verification-gaps change 規劃遺留缺口
Run Tests / test (pull_request) Successful in 2m1s
- 稽核報告:已完成的修補計畫改寫為執行紀錄(commit 對照表 + 偏差說明),
未處理事項收斂為三項(verification 缺口 / 效能優化 / 新功能路線圖)
- 新 change provider-verification-gaps:規劃 schedules/reviews 公開子端點
過濾與預約入口檢查(含「既有預約不受影響」政策決定),待實作
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 19:06:34 +08:00 |
|
a620906209
|
a97a7d096c
|
chore(openspec): 補歸檔 2026-06-11-audit-remediation change
Run Tests / test (pull_request) Successful in 2m2s
事後補齊本次稽核修補的 OpenSpec 歷史紀錄(proposal / design /
tasks / 規格增量),主規格已於實作時直接更新,本 archive 僅為
變更軌跡。design.md 記錄 5 項關鍵決策(artisan command 取代
HTTP 端點、10/min 為基準、列表過濾而非禁止上架等)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 18:44:14 +08:00 |
|
a620906209
|
cec2078035
|
test(auth): 同步 admin register 端點移除——刪除過時測試、更新覆蓋規格
原 test_admin_register_* 測的是已移除的 P0 漏洞端點,
端點關閉防護與帳號建立改由 AdminAccountCreationTest 覆蓋。
容器內全套件 146 passed / 378 assertions。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 17:52:37 +08:00 |
|
a620906209
|
d3a0d300c6
|
docs(openspec): 規格清理——補 Purpose、修正前端 repo 描述、補 admin 查詢端點
- auth-test-coverage:補歸檔後遺留的 TBD Purpose
- member-portal-ui:前端實際位於本 repo frontend/,修正獨立 repo 描述
- admin-auth:補 check-member / check-provider 端點規格
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 17:49:00 +08:00 |
|
a620906209
|
3c38d085bd
|
feat(offers): 未驗證教練的課程不對公開端點曝光
is_verified 原本只有 Admin toggle 開關、無任何業務約束(稽核 P1-1)。
- DivingOffer 新增 visibleToPublic scope:provider_id null 或教練已驗證
- 公開 index/show 套用過濾,未驗證教練課程列表排除、詳情 404
- toggle-verified 後 flush diving_offers 快取標籤,切換立即生效
- 新增 provider-verification 規格(含已知限制註記)與 7 條可見性測試
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 17:42:43 +08:00 |
|
a620906209
|
88a81aac41
|
docs(openspec): 同步 login-rate-limiting 規格門檻至實作值 10/min
規格原寫 5/min,實作與測試(commit 0dabc4e)皆為 throttle:10,1,
以實作為準消除規格漂移,並註記放寬理由(帳號鎖定已涵蓋暴力破解防護)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 17:37:19 +08:00 |
|
a620906209
|
aeb8c975e2
|
security(auth): 移除公開 admin/register 端點,改由 app:create-admin 建立管理員
P0 漏洞:原 POST /api/admin/register 無任何防護,任何人可註冊管理員帳號。
- 移除路由、AuthController::registerAdmin、對應 Swagger 文件
- 新增 app:create-admin artisan command(密碼門檻 min:8)
- 補 AdminAccountCreationTest 防止端點被重新打開
- 同步 admin-auth 規格,並收錄 2026-06-11 稽核報告與路線圖文檔
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-11 17:36:33 +08:00 |
|
a620906209
|
ca5b843362
|
chore(openspec): 歸檔 auth-tests 變更並建立 auth-test-coverage 主規格
Run Tests / test (pull_request) Failing after 43s
34 項驗收情境與測試已 1:1 對應且全數通過,將變更移至
openspec/changes/archive/2026-06-07-auth-tests/,並依其內容建立
openspec/specs/auth-test-coverage/spec.md 作為主規格文件。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-08 04:02:05 +08:00 |
|
a620906209
|
6f446f601f
|
test(auth): 新增三角色登入/註冊/登出、P2 帳號鎖定、OAuth state 驗證測試
新增 34 個 Feature 測試(AuthLoginTest 19、AuthLockoutTest 11、
AuthOAuthTest 4)涵蓋 member/provider/admin 的註冊、登入、登出與跨角色
隔離;P2 帳號鎖定的 Fixed Window 計數、companion cache key 與 email
正規化;以及 P2 OAuth state 的 CSRF 驗證與一次性消耗。
同時新增 .gitea/workflows/test.yml 在 push/PR 時於 CI 自動執行測試
(含 GD 等擴充套件安裝),並補上對應的 OpenSpec 變更文件
(proposal/design/spec/tasks,34 項驗收情境與測試 1:1 對應)。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-08 04:01:33 +08:00 |
|
a620906209
|
2a0e9255ae
|
security(auth): P2 帳號鎖定 + OAuth state 驗證
- Account lockout:連續失敗 5 次鎖定 15 分鐘(Fixed Window,Cache)
- Member / Provider 各自獨立 namespace
- Email 正規化(strtolower+trim)
- 不存在帳號不累計計數(防 Cache 污染)
- companion key 記錄 locked_until(ISO 8601)
- OAuth CSRF 防護:移除 stateless(),手動 state 生成與驗證
- session('oauth_state') + session('state') 雙寫確保 Socialite 內建驗證通過
- state mismatch redirect 至 /login?error=oauth_failed
- throttle 從 5,1 調整為 10,1,避免 IP throttle 在 lockout 前觸發
- NormalizesEmail Trait、config/auth_lockout.php
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-03 01:20:25 +08:00 |
|
a620906209
|
d9f0fe11c6
|
security(auth): P1 Token Refresh + sessionStorage
- 新增三個 refresh 端點(member/provider/admin),revoke 舊 token 發行新 7 天 token
- axios.js / coachAxios.js:401 interceptor 改為 refresh-then-retry,含 isRefreshing queue 防並發、isRedirecting flag 防雙重 redirect
- auth.js / coachAuth.js / AuthCallbackView.vue:localStorage 全改為 sessionStorage
- echo.js / notificationAxios.js:同步改為 sessionStorage
- notifications.js:401 時停止 polling(stopPolling),不印 error log
- 新增 TokenRefreshTest.php(11 tests / 24 assertions):refresh 成功/失效/跨角色 403
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-02 04:33:35 +08:00 |
|
a620906209
|
cb9c9a9385
|
security(auth): P0 認證安全強化
- Token 過期時間設為 7 天(sanctum.php expiration)
- prune-expired 每日排程清除過期 token 記錄
- Google OAuth redirect 改用 URL fragment(#token=)避免 token 出現在 server log
- SocialAuthController env() 改 config() 修正 config:cache 下 redirect 失效問題
- 登入端點加 rate limiting:member/provider throttle:5,1,admin throttle:3,1
- axios/coachAxios 加 401 response interceptor,token 過期自動登出
- 修正 migration SQLite 相容性(MODIFY COLUMN),Feature tests 從 7 通過恢復至 41
- 新增 AuthRateLimitTest(5 tests)驗證各角色頻率限制行為
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-02 01:54:40 +08:00 |
|
a620906209
|
4a5559a79e
|
chore(openspec): 移除已 archive 的 change 原路徑
補上 mv 後未 stage 的刪除紀錄,保持 working tree 乾淨。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-29 01:17:41 +08:00 |
|
a620906209
|
83e0e599a0
|
docs(openspec): archive realtime-booking-chat,同步主 specs
- archive openspec/changes/realtime-booking-chat → archive/2026-05-29-realtime-booking-chat
- 新增 openspec/specs/booking-chat/spec.md(即時訊息完整規格)
- 新增 openspec/specs/user-presence/spec.md(Presence Channel 規格)
- 更新 openspec/specs/booking-lifecycle/spec.md(補訊息頻道語義與封存 Scenario)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-29 01:14:52 +08:00 |
|
a620906209
|
ab24f210a6
|
feat: 即時預約聊天室(realtime booking chat)
## 新增功能
- 會員與教練在 confirmed 預約期間可互傳文字與圖片訊息
- Presence Channel 顯示對方在線狀態(即時加入/離線)
- 已讀回執:對方讀取訊息後即時更新
- 預約完成(completed)後訊息封存唯讀
- 圖片上傳使用 intervention/image 處理(移除 EXIF、限制尺寸、強制重新編碼)
## 通知系統
- 收到新訊息時 Bell Icon 即時更新(NotificationCreated via private channel)
- 預約列表卡片顯示未讀角標(GET /api/bookings/messages/unread-counts 批次查詢)
- 瀏覽器分頁在背景時推送 Web Notification
## 基礎建設
- 引入 Laravel Reverb 作為自架 WebSocket 伺服器
- docker-compose 新增 reverb service(連接 proxy_net,供 NPM 代理)
- 前端安裝 laravel-echo + pusher-js,初始化 Echo plugin
- Dockerfile 補 GD JPEG/WebP/FreeType 支援
## 清理
- 移除 test_broadcast.php 與 resources/js/echo.js(Blade 殘留)
- 移除 /ping、/testpost 測試路由
- channels.php 改用 class-based 授權語法,移除 debug log
- BookingChat.vue otherType 提取為 computed 消除重複
- docker-entrypoint.sh 健康檢查改用 env var 取代硬編碼密碼
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-28 03:59:14 +08:00 |
|
a620906209
|
0dda2bb2a3
|
docs:補全所有 API 端點 Swagger 文件(73 個端點)
Tests / PHP 8.2 (pull_request) Failing after 2s
Tests / PHP 8.3 (pull_request) Failing after 2s
- 修正 AuthApiDoc.php 路徑錯位(/register/member → /member/register 等)
及 change-password 方法(Post→Put);補上 POST /logout、GET /user
- 新增 AuthSupplementDoc.php(Google OAuth 2 端點)
- 新增 PublicApiDoc.php(共用 Schema + 公開課程 4 端點)
- 新增 MemberApiDoc.php(預約、評價、通知共 13 端點)
- 新增 ProviderApiDoc.php(課程、圖片、時段、預約管理共 18 端點)
- 新增 AdminApiDoc.php(統計、會員/教練/課程管理共 16 端點)
- 更新 README.md
- 歸檔 swagger-api-docs-completion change,同步主規格
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-24 18:24:50 +00:00 |
|
a620906209
|
b475a61d14
|
chore:新增 swagger-api-docs-completion change 規劃
proposal / design / specs / tasks 全部就緒,21 tasks 待實作
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-24 18:24:50 +00:00 |
|
a620906209
|
bda6533105
|
chore:歸檔 api-performance-optimization,同步主規格
- 移至 openspec/changes/archive/2026-05-25-api-performance-optimization/
- 新增主規格:api-cache-layer、db-index-optimization
- 更新 review-lifecycle 規格(補分頁、eager load)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-25 00:45:08 +08:00 |
|
a620906209
|
efb1f22be3
|
feat:實作 API 效能優化 — Redis 快取、分頁、DB 索引
- 引入 Redis(predis)快取層:Admin Stats(5分鐘)、課程列表(3分鐘,tag-based 失效)、評價分布(10分鐘)
- ReviewController::publicList 改為 paginate + eager load votes,消除 N+1
- AdminReviewController::index 加入分頁(預設 20,最大 100)
- 新增 notifications / diving_offers 效能索引 migration
- 新增 docker-compose.override.yml 本機開發 port mapping 機制(不進 git)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-25 00:17:16 +08:00 |
|
a620906209
|
915e404dfc
|
fix:修正 Email 設定與規格同步
- .env.example:MAIL_MAILER 改為 smtp(對應 Mailpit 本地測試流程)
- notification-email spec:移除 ReviewReceived Email 觸發(僅 database channel)
- notification-email spec:Email CTA 連結改為 /my-bookings(移除 /{id})
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-17 23:21:16 +08:00 |
|
a620906209
|
0bce40a5bf
|
feat:實作通知系統 — 站內通知、Email 通知、Polling 機制
後端
- 新增 6 個 Notification class(預約建立/確認/拒絕/取消/完成、收到評價),database + mail 雙 channel
- 新增 NotificationController(list / unread-count / markRead / markAllRead / destroy)
- 整合通知觸發至 MemberBookingController、ProviderBookingController、CompleteFinishedBookings、ReviewController
- 新增 notifications / jobs / failed_jobs migration
- Docker Compose 加入 queue-worker、mailpit service
- DivingOffer 補上 provider() 關聯
前端
- 新增 notificationStore(Polling 30s/60s 自適應 + Page Visibility API)
- 新增 NotificationBell(未讀 Badge)、NotificationDrawer(側邊通知中心)
- main.js:auth store init 前置於 router.use(),修正 beforeEach guard 時序問題
- notificationAxios:依路徑動態選擇 member/coach token
- NotificationDrawer:改用 new URL().pathname 提取 action_url 路徑
OpenSpec
- 歸檔 notification-system change
- 同步 notification-core / notification-email / notification-triggers specs 至主規格
- 更新 booking-lifecycle / review-lifecycle spec(補充通知觸發 requirement)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-17 22:26:14 +08:00 |
|
a620906209
|
ca2ed14de3
|
feat:實作課程圖片上傳 — 封面 + 相簿管理
後端:
- Migration:diving_offers 新增 cover_image 欄位、新增 course_images 表(含索引)
- CourseImage Model(CREATED_AT、url accessor)
- DivingOffer:cover_image_url accessor、hasMany courseImages、static::deleting() 孤兒清理
- CourseImageController:封面上傳/刪除、相簿上傳(max 3)/刪除,統一 mimes+size 驗證
- DivingOfferController:index/show 回傳加入 cover_image_url 與 images 陣列
- 修正 APP_URL 加入 port(:8080),Storage::url() 才能產生正確圖片連結
前端:
- courseImageApi.js:uploadCover/deleteCover/uploadImage/deleteImage
- CourseCard:有封面顯示 <img>,無封面顯示漸層佔位
- CourseDetailView:封面大圖 + 相簿縮圖橫列(點擊開新分頁)
- OfferFormView(編輯模式):封面預覽/更換/刪除、相簿縮圖管理(達 3 張隱藏上傳按鈕)
基礎設施:
- docker-entrypoint.sh:加入 storage:link --force
- docker-compose.yml:移除 storage-data named volume(改用 bind mount,避免 Nginx 讀不到圖片)
測試:
- CourseImageTest.php:14 個 Feature Test 全部 PASS(Storage::fake)
涵蓋:上傳成功/格式驗證/大小驗證/所有權、刪除/無封面不報錯、
相簿上限/sort_order 遞增、孤兒清理
OpenSpec:
- course-images change 歸檔至 archive/2026-05-12-course-images
- 新增 specs/course-image-upload 主規格(含 bind mount 持久化說明)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-12 03:54:45 +08:00 |
|
a620906209
|
8ef293332a
|
feat:實作評價系統 — 匿名評價、有幫助投票、手動完成預約
後端:
- 新增 reviews / review_edits / review_votes migration(含索引)
- Review / ReviewEdit / ReviewVote Model
- ReviewController:評價 CRUD、資格驗證(completed booking)、rating 即時重算
- toggleHelpful:Member 限定、GREATEST 原子防負、DB transaction 同步
- AdminReviewController:全量列表、刪除(含重算)
- AdminBookingController:全量列表、手動標記 completed
- ProviderBookingController 新增 complete 方法(教練手動完成預約)
- DevelopmentSeeder:快速重建測試資料(admin/coach/member + offers + bookings)
- EnsureAdmin middleware 正式納入 bootstrap/app.php
- Nginx server_name 加入 cfdive.local
前端:
- 課程詳情頁加入評價區塊(星等分布、排序切換、撰寫/修改/刪除、有幫助 Toggle)
- Coach Portal 新增「課程評價」頁(只讀,依課程分組)
- Coach 預約管理加入「完成」按鈕
- Admin 新增「預約管理」頁(標記完成)、「評價管理」頁(刪除)
- Admin / Coach Navbar 新增對應連結
OpenSpec:
- review-system change 歸檔至 archive/2026-05-12-review-system
- 新增 specs/review-lifecycle 與 specs/review-voting 主規格
- review-voting spec 補充 Member 限定與 GREATEST 原子更新說明
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-12 02:46:54 +08:00 |
|
a620906209
|
88c0c09ccb
|
feat:實作預約系統 — 時段管理、預約生命週期與前端整合
後端:
- 新增 course_schedules / bookings migration(含索引)
- BookingStatus / ScheduleStatus PHP BackedEnum
- CourseSchedule / Booking Model(七狀態機 VALID_TRANSITIONS)
- ScheduleController、ProviderBookingController、MemberBookingController
- 雙層名額驗證(API 層快速失敗 + DB lockForUpdate 防超賣)
- 24h 取消截止、pending 不佔位設計
- ExpirePendingBookings(每小時)/ CompleteFinishedBookings(每日)Scheduler
- Docker cron 配置、CACHE_STORE 改為 file 修正 502
前端:
- 課程詳情頁加入時段選擇與預約流程
- 我的預約頁(展開式卡片、狀態說明、連結課程詳情)
- Coach 時段管理(上午/下午時間選擇器、新課程引導)
- Coach 預約管理(依課程分組、待確認徽章)
- Navbar 新增「我的預約」與「時段/預約管理」入口
- 密碼格式提示與即時比對
OpenSpec:
- booking-system change 歸檔至 archive/2026-05-12-booking-system
- 新增 specs/course-scheduling 與 specs/booking-lifecycle 主規格
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-12 00:24:51 +08:00 |
|
a620906209
|
24145419b0
|
feat:實作 Admin Panel — 平台管理後台
後端:
- AdminStatsController:總會員/教練/課程數統計 API
- AdminUserController:會員與教練列表、詳情、啟用/停用、教練驗證(toggle 反轉語意)
- AdminOfferController:全平台課程列表與刪除
- routes/api.php:新增 /api/admin/stats、members、providers、offers 等路由
前端(frontend/):
- adminAuth store、adminAxios(第三套獨立認證)
- /admin/* 路由群組 + requiresAdmin guard
- AdminNavBar、AdminLayout
- App.vue:isCoachPage → isBackofficePage(/coach/* 和 /admin/* 皆隱藏會員 NavBar)
- LoginView、DashboardView(統計卡片)
- MembersView、ProvidersView(含驗證操作)、OffersView(含刪除確認)
OpenSpec:
- 新增 specs:admin-auth / admin-user-management / admin-offer-management / admin-stats / admin-panel-ui
- 歸檔:openspec/changes/archive/2026-05-10-admin-panel
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-10 04:07:13 +08:00 |
|
a620906209
|
3827223be3
|
feat:實作 Coach Portal — 教練後台課程管理
後端:
- Migration:diving_offers 新增 provider_id(nullable FK)
- Migration:users.role ENUM 加入 provider 值
- Migration:diving_offers.spot 改為 nullable
- AuthController:registerProvider business_name 改為選填
- AuthController:updateProviderProfile 補上 certifications / dive_sites / services / facilities / website / social_media
- ProviderOfferController:教練課程 CRUD(index/show/store/update/destroy),實作 provider_id 所有權不變式(404 → 403 兩步驟)
前端(frontend/):
- coachAuth store、coachAxios(獨立於 member auth)
- /coach/* 路由群組 + beforeEach guard
- CoachNavBar、CoachLayout(教練頁隱藏會員 NavBar)
- LoginView、RegisterView、DashboardView(表格 + 刪除確認)
- OfferFormView(新增/編輯共用)、ProfileView
OpenSpec:
- openspec/config.yaml 補入專案 context 與 rules
- 新增 specs:coach-offers-api / coach-portal-ui / provider-auth
- 更新 spec:diving-offers-api 加入 provider_id
- 歸檔:openspec/changes/archive/2026-05-10-coach-portal
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-05-10 03:34:14 +08:00 |
|
a620906209
|
e44d69a973
|
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 |
|