Sfoglia il codice sorgente

docs(plan): add incremental implementation plan for 7D health dimension system

Sisyphus 4 mesi fa
parent
commit
2ecc20d856

+ 847 - 0
docs/superpowers/plans/2026-06-27-health-dimensions-incremental-plan.md

@@ -0,0 +1,847 @@
+# 7维健康体系增量实施计划
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** 完成7维健康评分系统与设计规范的差距填补,覆盖商品→能量奖励、Dify AI推荐、维度详情页、问卷前端、trend计算、body首页入口、管理端配置和测试。
+
+**Architecture:** 后端Spring Boot 2.7.18 + MyBatis-Plus,前端uni-app Vue 2(微信小程序),Web管理端Vue 2 + Element UI。7维评分核心已实现(Controller+Service+DTO+Entity+DB),剩余为增量衔接工作。
+
+**Tech Stack:** Java 8, Spring Boot 2.7.18, MyBatis-Plus, MySQL 8.0, uni-app Vue 2, Element UI Vue 2
+
+---
+
+## TL;DR
+
+> **Quick Summary**: 填补7维健康体系与设计规范的10项差距:后端4项(商品能量、Dify推荐、趋势计算、身能量集成)、前端3项(详情页、问卷页、入口导航)、管理端2项(维度配置、数据源管理)、测试1项。核心评分引擎无需改动。
+>
+> **Deliverables**:
+> - 商品购买成功后自动奖励五维能量
+> - Dify AI智能推荐替代LIKE搜索
+> - 7个维度各自的详情页(历史趋势+建议+推荐商品)
+> - 维度问卷专用前端页面
+> - 趋势计算从硬编码改为基于历史数据
+> - body首页导航入口
+> - 管理端维度常模CRUD + 数据源CRUD
+> - 后端服务单元测试
+>
+> **Estimated Effort**: Medium (10 tasks)
+> **Parallel Execution**: YES - 4 waves, max 4 parallel
+> **Critical Path**: Task 1 (trend) → independent | Task 4 (身能量) → independent
+
+---
+
+## Context
+
+### Original Request
+根据设计规范(`.sisyphus/drafts/health-dimensions-design.md`)制定7维健康体系的完整实施计划。
+
+### Codebase State Summary
+经过全面探索,7维健康评分框架**核心已完全实现**:
+- **后端**:`HealthDimensionController` + `DimensionScoreServiceImpl` + DTOs + Entity + Mapper + DB表 — 100%
+- **前端**:`health-dimensions.vue`(健康指数环+雷达图+维度卡片+上传弹窗)— 100%
+- **剩余**:10项增量差距
+
+### Key Decisions Made
+- 范围:全部差距项(10项),用户确认
+- 测试:包含后端单元测试
+- 保存:`.sisyphus/plans/` + 拷贝到 `docs/superpowers/plans/` 提交
+
+---
+
+## Work Objectives
+
+### Core Objective
+完成7维健康体系剩余10项增量功能的实施,覆盖后端增强、前端页面、管理端配置和测试。
+
+### Concrete Deliverables
+- `ProductOrderService.java` - 支付成功后触发能量奖励
+- `DifySyncService.java` - 完整的Dify API调用实现
+- `RecommendationService.java` - 集成Dify AI推荐
+- `DimensionScoreServiceImpl.java` - 趋势计算修正
+- `EnergyService.java` - 读取维度分数影响身能量
+- 7个维度详情页 (`pages/body/dimension-detail/`)
+- 问卷前端页 (`pages/body/dimension-questionnaire.vue`)
+- `body/index.vue` - 添加维度入口链接
+- Web管理端维度常模管理页
+- Web管理端数据源管理页
+- 后端JUnit测试
+
+### Definition of Done
+- [ ] `mvn clean compile` 通过
+- [ ] 所有新增/修改的后端逻辑可编译
+- [ ] 前端页面在pages.json注册且路径可访问
+- [ ] 单元测试通过(覆盖率≥60%新增代码)
+
+### Must Have
+- 商品购买成功→能量奖励:`ProductOrderService.pay()` + `handlePaymentSuccess()` 调用 `EnergyService.awardEnergy()`
+- Dify同步:`DifySyncService` 实现 REST API 调用(POST/PUT/DELETE文档到Dify Dataset)
+- AI推荐:`RecommendationService` 在关键词搜索无结果时调用 Dify 推荐
+- 趋势:`DimensionScoreServiceImpl` 基于最近2次评分计算 up/down/stable
+- 身能量联动:`EnergyService` 或新Service读取7维评分并影响body维度能量
+- 维度详情页:7个维度各自的页面,含历史折线图、建议、关联商品
+- 问卷页:专用问卷页调用 `/api/dimension/questionnaire`
+- body首页:添加"健康维度"入口按钮
+- 管理端:维度常模CRUD + 数据源CRUD
+
+### Must NOT Have (Guardrails)
+- 不改动7维评分核心聚合逻辑(`DimensionScoreServiceImpl.getHealthDimension()` 的7维聚合)
+- 不改动前端已实现的 `health-dimensions.vue` 核心结构(雷达图、维度卡片等)
+- 不改动数据库已有表结构(仅可能新增索引或数据行)
+- 不重写 `ProductOrderService` 的订单流程,仅在支付成功后插入能量奖励调用
+- 不引入新依赖/库
+
+---
+
+## Verification Strategy
+
+> **ZERO HUMAN INTERVENTION** - ALL verification is agent-executed. No exceptions.
+
+### Test Decision
+- **Infrastructure exists**: YES (后端有JUnit/Spring Boot Test支持)
+- **Automated tests**: YES (Tests after) - 为新增/修改的后端逻辑编写单元测试
+- **Framework**: JUnit 5 + Spring Boot Test + Mockito
+
+### QA Policy
+Every task MUST include agent-executed QA scenarios. Evidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`.
+
+- **Backend changes**: Use Bash (mvn test / curl API endpoints)
+- **Frontend pages**: Use Playwright (navigate, assert DOM)
+- **Admin UI**: Use Playwright (navigate, fill forms, assert)
+
+---
+
+## Execution Strategy
+
+### Parallel Execution Waves
+
+```
+Wave 1 (Backend Core - Start Immediately):
+├── Task 1: Trend calculation fix [quick]
+├── Task 2: Product→Energy reward [quick]
+├── Task 3: Dify AI sync + integration [unspecified-high]
+└── Task 4: 7-dimension → body energy integration [quick]
+
+Wave 2 (Frontend Pages):
+├── Task 5: Body index → dimensions entry [quick]
+├── Task 6: Questionnaire frontend page [visual-engineering]
+└── Task 7: Dimension detail pages (7 pages) [visual-engineering]
+
+Wave 3 (Admin UI + Testing):
+├── Task 8: Dimension config management (Web admin) [quick]
+├── Task 9: Data source management (Web admin) [quick]
+└── Task 10: Unit tests [quick]
+
+Wave FINAL (Verification):
+├── F1: Plan compliance audit (oracle)
+├── F2: Code quality review (unspecified-high)
+├── F3: Real manual QA (unspecified-high + playwright)
+└── F4: Scope fidelity check (deep)
+```
+
+---
+
+## TODOs
+
+- [ ] 1. Trend Calculation — 基于历史数据计算趋势
+
+  **What to do**:
+  - 在 `DimensionScoreServiceImpl.java` 中找到 `item.setTrend("stable")` 行(约第78行)
+  - 将趋势计算改为基于最近2次评分的历史比较
+  - 逻辑:比较当前评分与上一次评分,若差异≥5分则判定up/down,否则stable
+  - 使用 `HistoryScores(memberId, dimension, 2)` 获取最近2条记录
+  - 修改 `getHealthDimension()` 方法中构建 DimensionItem 的部分
+
+  **Must NOT do**:
+  - 不改动 `getHealthDimension()` 的整体结构
+  - 不改动其他方法
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Single simple logic change, low complexity
+  - **Skills**: [] (no special skills needed)
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 1 (with Tasks 2, 3, 4)
+  - **Blocks**: None
+  - **Blocked By**: None (can start immediately)
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java:52-98` — `getHealthDimension()` 方法,第78行硬编码 `"stable"`
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java:143-160` — `getDimensionHistory()` 方法,用作参考
+  - `.sisyphus/drafts/health-dimensions-design.md` — 设计规范§7.1 趋势定义
+
+  **Acceptance Criteria**:
+  - [ ] 当最近2次评分差≥5分时,trend返回"up"或"down"
+  - [ ] 当评分差<5分或无历史数据时,trend返回"stable"
+  - [ ] `mvn clean compile` 通过
+
+  **QA Scenarios**:
+  ```
+  Scenario: Trend shows "up" when score increased by ≥5
+    Tool: Bash (curl)
+    Preconditions: Member has score 70 on day-1 and 80 on day-2 for "growth" dimension
+    Steps:
+      1. POST /api/dimension/overview { memberId: 1 }
+      2. Find "growth" dimension item in response
+    Expected Result: growth.trend === "up"
+    Evidence: .sisyphus/evidence/task-1-trend-up.json
+
+  Scenario: Trend shows "stable" with no history
+    Tool: Bash (curl)
+    Preconditions: Member has only 1 score record for "sleep" dimension
+    Steps:
+      1. POST /api/dimension/overview { memberId: 2 }
+      2. Find "sleep" dimension item
+    Expected Result: sleep.trend === "stable"
+    Evidence: .sisyphus/evidence/task-1-trend-stable.json
+  ```
+
+  **Commit**: YES
+  - Message: `fix(dimension): calculate trend from score history instead of hardcoding`
+  - Files: `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java`
+
+- [ ] 2. Product→Energy Reward — 商品购买后自动奖励能量
+
+  **What to do**:
+  - 在 `ProductOrderService.java` 中:
+    - 注入 `EnergyService` (使用 `@Resource`)
+    - 在 `pay()` 方法中,在 `order.setStatus("paid")` 和 `orderMapper.updateById(order)` 之后,调用 `energyService.awardEnergy()`
+    - 在 `handlePaymentSuccess()` 方法中,同样的位置插入能量奖励
+    - 能量值:使用固定值 10(或根据商品价格计算,如 `totalAmount / 100`,以分为单位)
+    - sourceType 使用 `"product"`
+    - 确定 `childId`:从订单的 `buyerId` 对应的 `User.familyId` 中查找 children(可选:或直接使用 buyerId 作为 childId)
+    - 如果 buyer 不是 child 角色,则需要通过 `UserService` 查找该 buyer 家庭下的 child
+
+  **Must NOT do**:
+  - 不改动订单支付流程的现有逻辑
+  - 不改变 `pay()` 方法的返回结构
+  - 不阻塞支付流程(能量奖励失败不应影响订单状态)
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Simple insertion of existing pattern (copy from `HealthCheckinService`)
+  - **Skills**: [] (no special skills needed)
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 1 (with Tasks 1, 3, 4)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java:140-168` — `pay()` 方法,在 `updateById` 后插入
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java:170-187` — `handlePaymentSuccess()` 方法
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/HealthCheckinService.java:161` — 调用 `energyService.awardEnergy()` 的模式参考
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/EnergyService.java:591-593` — `awardEnergy()` 方法签名
+  - `cfc-backend/src/main/java/com/etotem/cfc/entity/EnergySourceConfig.java:19` — sourceType 枚举含 "product"
+  - `.sisyphus/drafts/health-dimensions-design.md` §8.2 — 改进方案
+
+  **Acceptance Criteria**:
+  - [ ] `pay()` 方法中支付成功后调用 `energyService.awardEnergy()`
+  - [ ] `handlePaymentSuccess()` 方法中也调用能量奖励
+  - [ ] 能量奖励失败不阻断支付返回
+  - [ ] `mvn clean compile` 通过
+
+  **QA Scenarios**:
+  ```
+  Scenario: Product purchase awards energy on payment success
+    Tool: Bash (curl)
+    Preconditions: A product with id=1, a user with token
+    Steps:
+      1. POST /api/product/order/pay { orderNo: "PO1234567890" }
+      2. Check response status === 200
+      3. POST /api/energy/balance { childId: 1 }
+      4. Verify body dimension energy has increased
+    Expected Result: Energy balance shows product-purchase energy
+    Evidence: .sisyphus/evidence/task-2-energy-awarded.json
+  ```
+
+  **Commit**: YES
+  - Message: `feat(product): award energy on successful payment`
+  - Files: `cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java`
+
+- [ ] 3. Dify AI Sync and Recommendation — 实现Dify知识库同步和AI推荐
+
+  **What to do**:
+  - 完成 `DifySyncService.java` 中的 TODO:
+    - `syncToDify()`: 根据 `dimensionCodes` 查询 `ProductDimensionConfigMapper` 获取 `difyDatasetId`,调用Dify REST API上传文档
+    - `removeFromDify()`: 调用Dify REST API删除文档
+    - 使用 Spring `RestTemplate` 发送 HTTP 请求到 `{difyBaseUrl}/datasets/{datasetId}/documents`
+  - 修改 `RecommendationService.java`:
+    - 当关键词LIKE搜索无结果或结果不足时,调用 Dify API 获取AI推荐
+    - 解析Dify返回结果,映射到商品ID
+    - 回退逻辑:Dify失败时继续使用原有LIKE搜索
+  - 添加 `product_dimension_config` 的 `difyDatasetId` 配置更新
+
+  **Must NOT do**:
+  - 不阻塞主流程(Dify失败仅记录日志)
+  - 不改动 `RecommendationService` 的现有搜索逻辑(仅作为补充)
+
+  **Recommended Agent Profile**:
+  - **Category**: `unspecified-high`
+    - Reason: Multiple integration points (REST API calls, data mapping, fallback logic)
+  - **Skills**: [] (no special skills needed)
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 1 (with Tasks 1, 2, 4)
+  - **Blocks**: None
+  - **Blocked By**: None (Dify API integration is standalone)
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/DifySyncService.java` — TODO实现
+  - `cfc-backend/src/main/java/com/etotem/cfc/entity/ProductDimensionConfig.java` — 含 `difyDatasetId` 字段
+  - `cfc-backend/src/main/java/com/etotem/cfc/mapper/ProductDimensionConfigMapper.java` — 查询维度配置
+  - `cfc-backend/src/main/resources/application.yml:79-82` — Dify配置(base-url, api-key, nutrition-api-key)
+  - Dify API 文档: `POST /v1/datasets/{dataset_id}/documents` — 上传文档
+  - Dify API 文档: `DELETE /v1/datasets/{dataset_id}/documents/{doc_id}` — 删除文档
+
+  **Acceptance Criteria**:
+  - [ ] `syncToDify()` 成功发起HTTP POST请求到Dify API
+  - [ ] `removeFromDify()` 成功发起HTTP DELETE请求
+  - [ ] Dify API调用失败仅记录error log,不阻塞主流程
+  - [ ] `RecommendationService` 在LIKE搜索无结果时使用Dify推荐
+  - [ ] `mvn clean compile` 通过
+
+  **QA Scenarios**:
+  ```
+  Scenario: Dify sync sends HTTP request
+    Tool: Bash (curl mock)
+    Preconditions: Dify API is configured, a knowledge base item exists
+    Steps:
+      1. Trigger knowledge base save
+      2. Check log for "同步知识点" message
+    Expected Result: DifySyncService.syncToDify() called without error
+    Evidence: .sisyphus/evidence/task-3-dify-sync.log
+
+  Scenario: Recommendation falls back to LIKE search on Dify failure
+    Tool: Bash (curl)
+    Preconditions: Dify API returns error
+    Steps:
+      1. POST /api/product/recommend { dimension: "gut", keyword: "益生菌" }
+      2. Check response has data even if Dify fails
+    Expected Result: Returns products from LIKE search (existing behavior preserved)
+    Evidence: .sisyphus/evidence/task-3-recommend-fallback.json
+  ```
+
+  **Commit**: YES
+  - Message: `feat(dify): implement knowledge sync API and AI recommendation`
+  - Files: `cfc-backend/src/main/java/com/etotem/cfc/service/DifySyncService.java`, `cfc-backend/src/main/java/com/etotem/cfc/service/RecommendationService.java`
+
+- [ ] 4. 7-Dimension → Body Energy Integration — 7维评分影响身能量
+
+  **What to do**:
+  - 创建新的Service(或修改现有 `EnergyService`)来建立7维评分到五维「身」能量的映射
+  - 逻辑:读取 `health_dimension_scores` 表中某个 child 的最新7维评分,综合计算一个「身」能量加成值
+  - 在 `EnergyService.recalculateDimensionEnergy()` 或类似方法中集成
+  - 或创建 `DimensionEnergySyncService` 新 Service,供 `DimensionScoreServiceImpl` 在评分更新后调用
+  - 能量加成规则:7维平均分 × 系数(如 0.5)+ 基础值(简化方案)
+  - 在 `DimensionScoreServiceImpl` 的 `uploadScore()` 和 `submitQuestionnaire()` 成功后自动调用
+
+  **Must NOT do**:
+  - 不改动七维评分核心逻辑
+  - 不改造 `EnergyService` 能量分配的核心算法
+  - 不引入循环依赖
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Simple data read + write, follows existing awardEnergy pattern
+  - **Skills**: [] (no special skills needed)
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 1 (with Tasks 1, 2, 3)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `.sisyphus/drafts/health-dimensions-design.md` §10 — 7维→五维「身」衔接逻辑
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java:100-116` — `uploadScore()` 方法
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/EnergyService.java:591-593` — `awardEnergy()` 方法
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/HealthDimensionScoreService.java` — 查询维度评分
+
+  **Acceptance Criteria**:
+  - [ ] 维度评分更新(upload/questionnaire)后自动触发身能量更新
+  - [ ] 7维平均分映射为body维度能量值
+  - [ ] `mvn clean compile` 通过
+
+  **QA Scenarios**:
+  ```
+  Scenario: Body energy updates after dimension score upload
+    Tool: Bash (curl)
+    Preconditions: Member has 5 dimension scores
+    Steps:
+      1. POST /api/dimension/upload { memberId: 1, dimension: "growth", score: 80, sourceType: "MANUAL" }
+      2. POST /api/energy/overview { childId: 1 }
+      3. Check body dimension energy value
+    Expected Result: Body energy reflects new dimension scores
+    Evidence: .sisyphus/evidence/task-4-body-energy.json
+  ```
+
+  **Commit**: YES
+  - Message: `feat(dimension): integrate 7-dimension scores into body energy`
+  - Files: `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java`, `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionEnergySyncService.java` (new)
+
+- [ ] 5. Body Index → Dimensions Entry — 身体首页添加维度入口导航
+
+  **What to do**:
+  - 在 `body/index.vue` 中找到功能入口区域(约第48-57行 `func-section`)
+  - 添加一个新的功能入口项,跳转到 `health-dimensions.vue`
+  - 图标使用 `📊` 或 `💚`,文案使用 "健康维度"
+  - 导航使用 `uni.navigateTo({ url: '/pages/body/dimension-overview?childId=...' })`
+  - 在 `onFuncClick` 方法中处理新入口
+  - 如果 `health-dimensions.vue` 不在首页直接可见,添加入口是必须的
+
+  **Must NOT do**:
+  - 不改变现有功能入口的结构
+  - 不修改其他功能入口的行为
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Simple UI modification, add 1 entry to existing list
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 2 (with Tasks 6, 7)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-frontend/pages/body/index.vue:279-284` — 现有功能入口列表 `funcList`
+  - `cfc-frontend/pages/body/index.vue:497-509` — `onFuncClick` 处理方法
+  - `cfc-frontend/pages/body/health-dimensions.vue` — 目标页面
+
+  **Acceptance Criteria**:
+  - [ ] body首页显示"健康维度"功能入口
+  - [ ] 点击后导航到健康维度页面
+  - [ ] 未登录时显示登录引导
+
+  **QA Scenarios**:
+  ```
+  Scenario: Click health-dimensions entry navigates to dimensions page
+    Tool: Playwright
+    Preconditions: User logged in, on body/index page
+    Steps:
+      1. Locate element with text "健康维度" in func-grid
+      2. Click it
+      3. Wait for navigation
+    Expected Result: Page URL contains "health-dimensions" or "dimension-overview"
+    Evidence: .sisyphus/evidence/task-5-navigation.png
+
+  Scenario: Unauthenticated user sees login prompt
+    Tool: Playwright
+    Preconditions: User not logged in
+    Steps:
+      1. Click "健康维度" entry
+    Expected Result: Login modal appears
+    Evidence: .sisyphus/evidence/task-5-login-prompt.png
+  ```
+
+  **Commit**: YES
+  - Message: `feat(body): add health-dimensions navigation entry`
+  - Files: `cfc-frontend/pages/body/index.vue`
+
+- [ ] 6. Dimension Questionnaire Page — 维度问卷前端页面
+
+  **What to do**:
+  - 创建新页面 `cfc-frontend/pages/body/dimension-questionnaire.vue`
+  - 页面功能:选择维度 → 回答该维度的标准化问题 → 提交评分
+  - 调用后端 API: `POST /api/dimension/questionnaire`
+  - 问题数据:前端预定义问题列表,每维度3-5个问题,选择题(单选)
+  - 提交成功后显示评分结果并跳转回维度全景页
+  - 在 `pages.json` 中注册新页面
+  - 添加 API 函数 `submitDimensionQuestionnaire` 到 `utils/api.js`
+
+  **Must NOT do**:
+  - 不替换已有的手动上传弹窗
+  - 不引入复杂状态管理
+
+  **Recommended Agent Profile**:
+  - **Category**: `visual-engineering`
+    - Reason: Needs UI design + API integration, moderate complexity
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 2 (with Tasks 5, 7)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-frontend/pages/body/health-dimensions.vue` — UI样式参考
+  - `cfc-backend/src/main/java/com/etotem/cfc/controller/HealthDimensionController.java:49-59` — 后端问卷API
+  - `cfc-backend/src/main/java/com/etotem/cfc/dto/HealthDimensionQuestionnaireVO.java` — DTO结构
+  - `cfc-frontend/utils/api.js` — 需要添加 `submitDimensionQuestionnaire`
+  - `cfc-frontend/pages.json` — 注册新页面
+  - `.sisyphus/drafts/health-dimensions-design.md` §6.2 — 问卷维度映射
+
+  **Acceptance Criteria**:
+  - [ ] 页面可选维度
+  - [ ] 每维度3-5个标准化问题
+  - [ ] 提交后调用 `/api/dimension/questionnaire`
+  - [ ] 提交成功后有反馈并跳转
+  - [ ] 页面在 `pages.json` 注册
+
+  **QA Scenarios**:
+  ```
+  Scenario: Submit questionnaire for sleep dimension
+    Tool: Playwright
+    Preconditions: User logged in, member exists
+    Steps:
+      1. Navigate to dimension-questionnaire page
+      2. Select "睡眠质量" dimension
+      3. Answer 3 questions (select options)
+      4. Click submit
+    Expected Result: API returns success, redirect to dimensions page
+    Evidence: .sisyphus/evidence/task-6-questionnaire-submit.png
+
+  Scenario: Validation - no dimension selected
+    Tool: Playwright
+    Preconditions: User on questionnaire page
+    Steps:
+      1. Click submit without selecting dimension
+    Expected Result: Toast shows "请选择维度"
+    Evidence: .sisyphus/evidence/task-6-validation.png
+  ```
+
+  **Commit**: YES
+  - Message: `feat(body): add dimension questionnaire page`
+  - Files: `cfc-frontend/pages/body/dimension-questionnaire.vue` (new), `cfc-frontend/pages.json`, `cfc-frontend/utils/api.js`
+
+- [ ] 7. Dimension Detail Pages — 7个维度的详情页
+
+  **What to do**:
+  - 创建新页面 `cfc-frontend/pages/body/dimension-detail.vue`(单页面+路由参数区分维度)
+  - 路由参数: `dimension` (code: growth/sleep/vision/immunity/nutrition/gut/exercise)
+  - 页面内容:
+    - 维度标题和当前评分(大号显示+等级颜色)
+    - 历史评分趋势折线图(Canvas或CSS实现,无需第三方库)
+    - 当前评分在常模中的百分位展示
+    - 该维度的改善建议(预置文本,每维度3-5条)
+    - 关联商品推荐(调用 `getProductsByDomain('body')` 并过滤)
+  - 调用后端API: `POST /api/dimension/history { memberId, dimension, limit: 10 }`
+  - 从 `health-dimensions.vue` 的维度卡片点击可导航至此详情页
+  - 在 `pages.json` 中注册新页面
+
+  **Must NOT do**:
+  - 不删除已有的 `health-dimensions.vue` 全览页面
+  - 不引入第三方图表库
+  - 不包含实际医疗建议
+
+  **Recommended Agent Profile**:
+  - **Category**: `visual-engineering`
+    - Reason: Complex UI with history chart, multiple sections, API integration
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 2 (with Tasks 5, 6)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/controller/HealthDimensionController.java:61-76` — `/api/dimension/history` API
+  - `cfc-backend/src/main/java/com/etotem/cfc/dto/HealthDimensionVO.java` — DimensionItem结构
+  - `cfc-frontend/pages/body/health-dimensions.vue` — UI样式参考
+  - `cfc-frontend/utils/api.js` — API函数
+  - `cfc-frontend/pages.json` — 注册新页面
+  - `.sisyphus/drafts/health-dimensions-design.md` §7.2 — 维度详情页要求
+
+  **Acceptance Criteria**:
+  - [ ] 7个维度共享同一详情页组件,通过参数区分
+  - [ ] 显示维度名称、当前评分、等级颜色
+  - [ ] 历史趋势折线图(至少最近5次评分)
+  - [ ] 百分位展示
+  - [ ] 3-5条改善建议
+  - [ ] 关联商品列表
+  - [ ] 在 `pages.json` 注册
+  - [ ] 从维度全景页可点击进入详情
+
+  **QA Scenarios**:
+  ```
+  Scenario: View dimension detail for gut health
+    Tool: Playwright
+    Preconditions: Member has gut dimension history
+    Steps:
+      1. Navigate to /pages/body/dimension-detail?dimension=gut&childId=1
+      2. Verify shows "肠胃健康" title
+      3. Verify score displayed with level color
+      4. Verify history chart has data points
+    Expected Result: All sections render correctly
+    Evidence: .sisyphus/evidence/task-7-dimension-detail.png
+
+  Scenario: Empty state - no history data
+    Tool: Playwright
+    Preconditions: Member has no history for "vision"
+    Steps:
+      1. Navigate to /pages/body/dimension-detail?dimension=vision&childId=2
+    Expected Result: Shows "暂无历史数据" empty state
+    Evidence: .sisyphus/evidence/task-7-empty-state.png
+  ```
+
+  **Commit**: YES
+  - Message: `feat(body): add 7 dimension detail pages`
+  - Files: `cfc-frontend/pages/body/dimension-detail.vue` (new), `cfc-frontend/pages.json`, `cfc-frontend/pages/body/health-dimensions.vue`
+
+- [ ] 8. Dimension Config Management (Web Admin) — 管理端维度常模配置
+
+  **What to do**:
+  - 在 `cfc-web/` 中创建新视图页面 `src/views/admin/dimension-config.vue`
+  - 功能:
+    - 列出 `health_norm_reference` 表中的所有维度常模数据
+    - 编辑:修改某个维度/年龄段/性别的百分位阈值(p5/p15/p25/p50/p75/p85/p95)
+    - 新增:添加新的常模行
+    - 删除:删除常模行(带确认弹窗)
+  - 使用 Element UI 组件:el-table, el-form, el-dialog, el-input-number, el-button
+  - 调用后端API:
+    - 后端需新增 `HealthNormController`(或复用现有 admin controller)
+    - API: POST /api/admin/dimension/norm/list, /api/admin/dimension/norm/save, /api/admin/dimension/norm/delete
+  - 在 `router/index.js` 中添加路由: `/admin/dimension-config`
+  - 在 `store/` 中添加对应的 API 封装(或直接使用 axios)
+  - 从 `cfc-backend/` 中创建对应的 Controller:
+    - `controller/admin/DimensionAdminController.java`
+    - 注入 `HealthNormReferenceMapper` 进行 CRUD 操作
+
+  **Must NOT do**:
+  - 不修改已有维度评分数据
+  - 不改动前端已有页面
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Standard CRUD admin panel, follows existing patterns
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 3 (with Tasks 9, 10)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/entity/HealthNormReference.java` — 常模实体(dimension, gender, age, percentile5/15/25/50/75/85/95)
+  - `cfc-backend/src/main/java/com/etotem/cfc/mapper/HealthNormReferenceMapper.java` — 已有 Mapper(含 `selectNorm` 方法)
+  - `cfc-web/src/views/admin/` — 其他管理端页面作为样式/模式参考
+  - `cfc-web/src/router/index.js` — 路由配置
+  - `.sisyphus/drafts/health-dimensions-design.md` §7.3 — 维度配置管理要求
+
+  **Acceptance Criteria**:
+  - [ ] 管理端可查看所有维度的常模列表
+  - [ ] 可编辑常模的百分位阈值
+  - [ ] 可新增常模行
+  - [ ] 可删除常模行(带确认)
+  - [ ] 后端API通过 `mvn clean compile`
+  - [ ] 路由 `/admin/dimension-config` 可访问
+
+  **QA Scenarios**:
+  ```
+  Scenario: View and edit dimension norm
+    Tool: Playwright
+    Preconditions: Admin is logged in to web admin
+    Steps:
+      1. Navigate to /admin/dimension-config
+      2. Verify table shows dimension norms with all percentile columns
+      3. Click edit on first row
+      4. Change p95 value
+      5. Click save
+    Expected Result: Norm value updated successfully
+    Evidence: .sisyphus/evidence/task-8-norm-edit.png
+
+  Scenario: Delete norm with confirmation
+    Tool: Playwright
+    Preconditions: Admin on dimension-config page
+    Steps:
+      1. Click delete on a row
+      2. Confirm deletion dialog
+    Expected Result: Row removed from table
+    Evidence: .sisyphus/evidence/task-8-norm-delete.png
+  ```
+
+  **Commit**: YES
+  - Message: `feat(admin): add dimension config management`
+  - Files: `cfc-web/src/views/admin/dimension-config.vue` (new), `cfc-web/src/router/index.js`, `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/DimensionAdminController.java` (new), `cfc-backend/src/main/resources/mapper/HealthNormReferenceMapper.xml` (if new queries needed)
+
+- [ ] 9. Data Source Management (Web Admin) — 管理端数据源管理
+
+  **What to do**:
+  - 在 `cfc-web/` 中创建新视图页面 `src/views/admin/data-source-config.vue`
+  - 功能:
+    - 列出 `health_data_sources` 表的所有数据源配置
+    - 编辑/新增/删除数据源行
+  - 使用 Element UI 组件
+  - 调用后端API:
+    - 后端新增 Controller: `POST /api/admin/dimension/data-source/list`, `/save`, `/delete`
+    - 可使用 `DimensionAdminController` 合并同类端点
+  - 在路由中添加 `/admin/data-source-config`
+
+  **Must NOT do**:
+  - 不修改已有数据源数据
+  - 不重复造轮子(与Task 8共享Controller)
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Standard CRUD, essentially same pattern as Task 8
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 3 (with Tasks 8, 10)
+  - **Blocks**: None
+  - **Blocked By**: None
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/entity/HealthDataSourceRecord.java` — 数据源实体
+  - Task 8 创建的 `DimensionAdminController.java` — 可复用同类端点
+  - `cfc-web/src/router/index.js`
+  - `.sisyphus/drafts/health-dimensions-design.md` §7.3 — 数据源配置要求
+
+  **Acceptance Criteria**:
+  - [ ] 管理端可查看所有数据源
+  - [ ] 可编辑/新增/删除数据源
+  - [ ] 后端API编译通过
+  - [ ] 路由 `/admin/data-source-config` 可访问
+
+  **QA Scenarios**:
+  ```
+  Scenario: List and add data source
+    Tool: Playwright
+    Preconditions: Admin logged in
+    Steps:
+      1. Navigate to /admin/data-source-config
+      2. Verify table shows data sources
+      3. Click "新增" button
+      4. Fill form: name="测试源", type="MANUAL"
+      5. Click save
+    Expected Result: New data source appears in table
+    Evidence: .sisyphus/evidence/task-9-datasource-add.png
+  ```
+
+  **Commit**: YES
+  - Message: `feat(admin): add data source management`
+  - Files: `cfc-web/src/views/admin/data-source-config.vue` (new), `cfc-web/src/router/index.js`, `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/DimensionAdminController.java`
+
+- [ ] 10. Unit Tests — 后端服务单元测试
+
+  **What to do**:
+  - 为以下后端服务编写JUnit + Mockito单元测试:
+    - `DimensionScoreServiceImpl` — 测试聚合逻辑、趋势计算、百分位计算、等级分类
+    - `ProductOrderService` — 测试支付成功后能量奖励调用(使用Mock验证)
+    - `DifySyncService` — 测试API调用(使用Mock RestTemplate)
+  - 测试结构:
+    - `cfc-backend/src/test/java/com/etotem/cfc/service/impl/DimensionScoreServiceImplTest.java`
+    - `cfc-backend/src/test/java/com/etotem/cfc/service/ProductOrderServiceTest.java`
+    - `cfc-backend/src/test/java/com/etotem/cfc/service/DifySyncServiceTest.java`
+  - 使用 `@SpringBootTest` 或直接 `MockitoExtension` + `@InjectMocks` + `@Mock`
+  - 使用 `MockMvc` 或直接调用 Service 方法
+  - 至少覆盖:
+    - DimensionScoreServiceImpl: 健康指数计算(全维度/部分维度)、趋势判定(up/down/stable)、百分位、等级
+    - ProductOrderService: pay()调用energyService、handlePaymentSuccess()调用energyService
+    - DifySyncService: syncToDify() send request、异常不传播
+
+  **Must NOT do**:
+  - 不编写集成测试(只写单元测试)
+  - 不测试已存在的前端页面(只测试新增/修改代码)
+  - 不过度Mock(只Mock外部依赖)
+
+  **Recommended Agent Profile**:
+  - **Category**: `quick`
+    - Reason: Standard unit test patterns
+  - **Skills**: []
+  - **Skills Evaluated but Omitted**: n/a
+
+  **Parallelization**:
+  - **Can Run In Parallel**: YES
+  - **Parallel Group**: Wave 3 (with Tasks 8, 9)
+  - **Blocks**: None
+  - **Blocked By**: Tasks 1-4 (需要实现完成才能测试)
+
+  **References**:
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/impl/DimensionScoreServiceImpl.java` — 被测类
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java` — 被测类
+  - `cfc-backend/src/main/java/com/etotem/cfc/service/DifySyncService.java` — 被测类
+  - `cfc-backend/pom.xml` — 测试依赖(Spring Boot Starter Test 应已有)
+
+  **Acceptance Criteria**:
+  - [ ] DimensionScoreServiceImplTest: 5个测试方法通过
+  - [ ] ProductOrderServiceTest: 2个测试方法通过
+  - [ ] DifySyncServiceTest: 2个测试方法通过
+  - [ ] `mvn test` 全部通过
+
+  **QA Scenarios**:
+  ```
+  Scenario: Run all unit tests
+    Tool: Bash
+    Preconditions: All backend implementation completed
+    Steps:
+      1. cd cfc-backend
+      2. mvn test
+    Expected Result: BUILD SUCCESS, all 9+ tests pass
+    Evidence: .sisyphus/evidence/task-10-test-results.log
+  ```
+
+  **Commit**: YES
+  - Message: `test(dimension): add unit tests for dimension services`
+  - Files: `cfc-backend/src/test/java/com/etotem/cfc/service/impl/DimensionScoreServiceImplTest.java` (new), `cfc-backend/src/test/java/com/etotem/cfc/service/ProductOrderServiceTest.java` (new), `cfc-backend/src/test/java/com/etotem/cfc/service/DifySyncServiceTest.java` (new)
+
+---
+
+## Final Verification Wave (MANDATORY)
+
+> 4 review agents run in PARALLEL. ALL must APPROVE.
+
+- [ ] F1. **Plan Compliance Audit** — `oracle`
+  Read the plan end-to-end. For each "Must Have": verify implementation exists. For each "Must NOT Have": search codebase for forbidden patterns. Check evidence files exist. Compare deliverables against plan.
+  Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`
+
+- [ ] F2. **Code Quality Review** — `unspecified-high`
+  Run `mvn clean compile` + linter check. Review all changed files for: `as any`/`@SuppressWarnings`, empty catches, console.log in prod, commented-out code, unused imports.
+  Output: `Build [PASS/FAIL] | Files [N clean/N issues] | VERDICT`
+
+- [ ] F3. **Real Manual QA** — `unspecified-high` (+ `playwright` skill if UI)
+  Execute EVERY QA scenario from EVERY task. Test cross-task integration. Test edge cases: empty state, invalid input.
+  Output: `Scenarios [N/N pass] | Integration [N/N] | VERDICT`
+
+- [ ] F4. **Scope Fidelity Check** — `deep`
+  For each task: read "What to do", read actual diff (git log/diff). Verify 1:1 compliance. Check "Must NOT do" compliance.
+  Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | VERDICT`
+
+---
+
+## Commit Strategy
+
+- **Task 1**: `fix(dimension): calculate trend from score history instead of hardcoding`
+- **Task 2**: `feat(product): award energy on successful payment`
+- **Task 3**: `feat(dify): implement knowledge sync API and AI recommendation`
+- **Task 4**: `feat(dimension): integrate 7-dimension scores into body energy`
+- **Task 5**: `feat(body): add health-dimensions navigation entry`
+- **Task 6**: `feat(body): add dimension questionnaire page`
+- **Task 7**: `feat(body): add 7 dimension detail pages`
+- **Task 8**: `feat(admin): add dimension config management`
+- **Task 9**: `feat(admin): add data source management`
+- **Task 10**: `test(dimension): add unit tests for dimension services`
+
+---
+
+## Success Criteria
+
+### Verification Commands
+```bash
+cd cfc-backend && mvn clean compile  # Expected: BUILD SUCCESS
+cd cfc-backend && mvn test           # Expected: Tests pass
+```
+
+### Final Checklist
+- [ ] All 10 "Must Have" present
+- [ ] All "Must NOT Have" absent
+- [ ] All tests pass
+- [ ] No regression in existing dimension functionality