Files
CFDivePlatform/openspec/specs/api-cache-layer/spec.md
T
a620906209 0cd1047b10
Run Tests / test (pull_request) Successful in 30s
docs(openspec): 補齊所有 spec 缺少的 Purpose section 與規格標頭
repo 內 35/38 份既有 spec 都是舊版歸檔流程留下的原始 delta 內容(`##
ADDED Requirements`,缺標題與 Purpose),openspec CLI 現版本嚴格驗證
(--strict)會報錯或警告。逐一補上:

- 缺標題/Purpose 的 30 份:加上 `# <name> Specification` 標題 + 依內容
  撰寫的 Purpose 段落,`## ADDED Requirements` 改回 `## Requirements`
- compose-cloud-baseline、scheduler-container:已有標題與
  Requirements,只補 Purpose 包裝
- provider-verification:已有標題與 Purpose,只需把
  `## ADDED Requirements` 改回 `## Requirements`
- admin-user-management、notification-email:各有一條 requirement 缺
  SHALL/MUST 關鍵字(純敘述句或表格),補上規範用語,內容不變

`openspec validate --specs --strict`:38/38 全過(原本 4/38)。純文件
補齊,未變更任何 requirement 的實質內容或行為描述。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LpcY9b7y9x4fusHBTXciQ
2026-08-03 04:11:06 +08:00

75 lines
2.7 KiB
Markdown
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.
# api-cache-layer Specification
## Purpose
定義以 Redis 作為 Laravel 快取驅動,涵蓋 Admin 統計、課程列表、評價分布的快取策略、TTL 與資料異動時的失效時機。
## Requirements
### Requirement: Redis 作為快取驅動
系統 SHALL 使用 Redis 作為 Laravel 快取驅動,取代現有的 `database` driver。
#### Scenario: 環境設定正確
- **WHEN** `.env``CACHE_STORE=redis``REDIS_HOST=redis`Docker service name)、`REDIS_CLIENT=predis`
- **THEN** `docker-compose up``php artisan cache:clear` 執行成功,無連線錯誤
#### Scenario: Redis service 在 docker-compose 中存在
- **WHEN** 執行 `docker-compose up`
- **THEN** `redis` container 正常啟動,`cfdive-app` 可連線至 Redis
---
### Requirement: Admin 統計數據快取
`GET /api/admin/stats` SHALL 使用 `Cache::remember()` 快取結果,TTL 5 分鐘,Cache key 為 `admin_stats`
#### Scenario: 首次請求寫入快取
- **WHEN** Admin 送出 `GET /api/admin/stats`,且快取中無 `admin_stats` key
- **THEN** 系統執行 DB 查詢並將結果寫入 Redis,回傳統計數據
#### Scenario: 後續請求命中快取
- **WHEN** Admin 在 5 分鐘內再次送出 `GET /api/admin/stats`
- **THEN** 系統直接從 Redis 回傳,不執行任何 DB 查詢
#### Scenario: 快取過期後自動重整
- **WHEN** 5 分鐘 TTL 到期後再次請求
- **THEN** 系統重新執行 DB 查詢並更新快取
---
### Requirement: 課程列表快取
`GET /api/diving-offers` SHALL 快取搜尋結果,TTL 3 分鐘,Cache key 包含查詢參數的 hash,並使用 `diving_offers` tag 管理失效。
#### Scenario: 相同搜尋條件命中快取
- **WHEN** 同樣的搜尋參數(region、tag、keyword 等)在 3 分鐘內再次請求
- **THEN** 系統從 Redis 回傳,不執行 DB 查詢
#### Scenario: Provider 異動課程時清除快取
- **WHEN** Provider 成功新增、修改或刪除課程(`POST/PUT/DELETE /api/provider/offers`
- **THEN** 系統呼叫 `Cache::tags(['diving_offers'])->flush()` 清除所有課程列表快取,下次請求重新查詢
---
### Requirement: 評價分布快取
`GET /api/diving-offers/{id}/reviews``distribution`(1–5 星分布統計)SHALL 獨立快取,TTL 10 分鐘,Cache key 為 `offer_review_distribution_{id}`
#### Scenario: 分布統計命中快取
- **WHEN** 同一課程 reviews 端點在 10 分鐘內再次請求
- **THEN** `distribution` 欄位從 Redis 取得,不執行 `GROUP BY` SQL
#### Scenario: 新增/修改/刪除評價時清除分布快取
- **WHEN** Member 成功新增、修改或刪除某課程的評價
- **THEN** 系統呼叫 `Cache::forget("offer_review_distribution_{offerId}")` 清除對應快取