Răsfoiți Sursa

docs(spec): 指标变化曲线·指标速查·指标关联设计规范 v1.0

iwt 3 zile în urmă
părinte
comite
920cf0afa1

+ 4 - 2
docs/superpowers/PROJECT-OVERVIEW.md

@@ -1,8 +1,9 @@
 # 浠艾福 项目全景 — 阶段性需求与设计汇总
 
-**文档版本:** v2.15
-**日期:** 2026-10-05
+**文档版本:** v2.16
+**日期:** 2026-10-09
 **状态:** 已确认(v2.1 Phase 2-4 全栈完成)+ 虚拟支付改造(Tasks 1-12 已完成,退款闭环实施中)+ 新用户注册引导(12 Tasks 全栈完成)+ 家庭成员关系条增强(✅ 已实施)+ TabBar 重构(✅ 4Tab + 中间⭐扇形菜单,设计已对齐实现)+ **LIFETIME 终身会员(✅ 11 Tasks 全栈完成)** + **健康数据中心(✅ 全栈完成)** + **SKU 价格单位统一分 + 规格选择响应式修复(✅ 7 Tasks 全栈完成)** + **AI健康教练人格分化与管家自助选择(✅ 11 Tasks 全栈完成)** + **优惠券全链路改为家庭维度(待实施)** + **关系三图重构(关键人拓展章鱼图/珍珠图/能力图,设计规格已完成)** + **注册零填写+信息按需补充(✅ 全栈完成:登录直接进首页 + 家庭邀请独立页真实姓名/家庭身份必填 + 功能→信息字段映射表 + 添加成员手机号冲突邀请加入)** + **健康报告归属重分配(✅ 后端接口 + 管理端页面 + 小程序入口已实现,见 `specs/2026-10-05-health-report-reassign-design.md`)**
+**指标变化曲线·指标速查·指标关联(✅ 设计已确认 v1.0,待实施,见 `specs/2026-10-09-indicator-change-curve-design.md`)**
 **维护:** 所有需求变更需更新本文档
 
 ---
@@ -116,6 +117,7 @@
 | 营养健康部分缺陷修复 | Phase 1 | ✅ 已实施(5项缺陷已修复) | `plans/2026-06-22-营养健康部分缺陷修复计划.md` |
 | 主动健康六阶模型改进(P0-P3) | Phase 5 | ✅ P0/P1-1/P1-2/P2-1/P2-2/P3 后端全完成(P2-2家庭互动+ P3社区扩散Controller/Service/Entity全量存在) | `specs/2026-07-22-active-health-six-stage-design.md` (设计总纲) |
 | 健康数据中心(看见·主动健康闭环) | Phase 5 | ✅ 全栈完成(身维度首页改造:Tab栏+四维雷达图+数据采集区+数据查看+方案汇总;在线测评新增认知/心理/关系3套题库+dim路由;方案汇总页+health_plans表+4后端接口) | `specs/2026-08-08-health-data-center-design.md` + `plans/health-data-center-implementation-plan.md` |
+| 指标变化曲线·指标速查·指标关联 | Phase 5/Q4 | 🟡 设计已确认 v1.0 待实施(统一指标层升级 indicator_definitions/indicator_values + indicator_mapping_rules/indicator_correlations 两新表 + NormalizeIndicatorPipeline 单一写者 + 4视图API + change-ranking + Spearman 校准 + TrendChart canvas 组件 + 曲线/速查两页面 + 管理端关联/映射两页) | `specs/2026-10-09-indicator-change-curve-design.md` |
 
 ---
 

+ 452 - 0
docs/superpowers/specs/2026-10-09-indicator-change-curve-design.md

@@ -0,0 +1,452 @@
+# 指标变化曲线 · 指标速查 · 指标关联 设计规范
+
+**版本:** v1.0
+**日期:** 2026-10-09
+**状态:** 已确认(头脑风暴 + Oracle 架构评审通过)
+**作者:** Sisyphus
+
+---
+
+## 1. 背景与目标
+
+### 1.1 现状问题
+
+- 同一类报告(如肠道菌群报告)多次上传后,页面只展示**单份报告**的详情,无法看到各项指标**随时间的变化**(哪项菌群升了、哪项降了)
+- 食材推荐指数虽有 `food_recommend_idx_log` 变化日志和 `getTrend()` 接口,但**没有按变化幅度排序**的能力
+- 指标名散落在各报告的 `health_indicators`(文本名),**没有统一的指标身份**,无法跨报告类型对比、无法做指标间的关联
+- 报告与报告之间、指标与指标之间的**关联关系**(如「记忆力 ↔ 影响睡眠的菌群含量」正/负相关、强度)完全没有数据模型支撑
+- `health_reports.report_date` 目前存的是**上传时间**而非报告真实日期,曲线横轴必然错位
+- 用户与规划师无法快速回答:「这个孩子最近 3 次菌群报告,哪些指标在好转、哪些在恶化?」
+
+### 1.2 设计目标
+
+1. **指标变化曲线**:同一类报告、不同报告日期 → 展示各指标数值随报告日期的变化(菌群增减、食材推荐升降),支持**按变化幅度排名**
+2. **指标速查**:查询某一成员当前所有指标的数值 + 变化趋势(分类分页)
+3. **指标关联关系**:定义指标之间的关联(正/负相关、强度、说明),管理端人工定义 + 真实数据校准(混合模式)
+
+### 1.3 用户故事
+
+- 作为家长,我想看孩子两次菌群报告之间哪些菌群/营养指标上升了、哪些下降了,好判断调理方向
+- 作为家长,我想知道「记忆力」这类认知指标和菌群报告里「影响睡眠的菌群」是否相关、相关性多强
+- 作为规划师/运营,我想在管理端维护指标关联关系和归一化映射规则,校准数据
+
+### 1.4 不在本文档范围(二期)
+
+- DAN / 体检等其余报告详情页的「变化」区块(一期只做菌群报告详情页)
+- 跨报告类型的同曲线叠加对比(如菌群乳杆菌 vs 体检某项)
+- `good_direction` 自动推断(一期管理端手配)
+
+---
+
+## 2. 现状调研结论
+
+| 现有资产 | 内容 | 对本次的可用性 |
+|---|---|---|
+| `health_reports` | 报告主表(report_type/report_date/subject_id/payload_json) | 曲线原数据;`report_date` 需修正为真实日期 |
+| `health_indicators` | 解析后的指标明细(report_id/category/indicator_name/indicator_value/status) | 报告指标原数据;保持为单一写者目标,**不删除** |
+| `report_type_registry` | 报告类型登记 + expected_indicators | 「同一类报告」分组依据;定义/映射种子来源 |
+| `food_recommend_idx` / `_log` | 食材推荐指数 + 变更日志(previous/new/report_id/changed_at) | 食材曲线几乎现成;缺变化幅度排名;保留语义 |
+| `indicator_definitions` / `indicator_values` | 通用指标字典 + 泛用指标值(sourceType/sourceId/definitionId/numericValue/recordedAt) | **升级为全平台统一指标层**(当前仅舌诊在用) |
+| `five_dimension_scores` / `health_dimension_scores` | 五维 / 七维评分(含 assessedAt) | 维度评分趋势现成;**不写入统一时序**,API 层单独合入 |
+| 指标关联表 | **不存在** | 新建 `indicator_correlations` |
+
+**关键缺口**:统一指标身份、归一化映射层、指标关联表、真实报告日期、变化幅度排名接口。
+
+---
+
+## 3. 设计决策
+
+| 决策项 | 选择 | 理由 |
+|--------|------|------|
+| 指标统一身份 | **方案 A**:复用 `indicator_definitions` + `indicator_values` 升级为统一指标层 | 项目本就有意的通用结构;跨类型统一;关联可跨类型;速查一处查全 |
+| 指标范围 | 报告解析指标(含菌属、营养、维生素等)+ 食材推荐指数 + 五维/七维评分 | 用户确认「全报告类型统一」+「上述 + 五维/七维评分」 |
+| 五维/七维存储 | **不进** `indicator_values`,保留原表,API 层单独合入「维度评分」小节 | 维度评分是聚合值,与原始测量混在一个时序中层级混乱 |
+| 关联关系 | 人工定义(候选对+方向+人工强度)+ 真实数据校准(computed_strength + sample_size),混合模式 | 用户确认 |
+| 报告日期 | 从 PDF 提取真实报告/采样日期;历史回填 | 曲线横轴准确性前提,用户确认纳入 |
+| 归一化映射 | 独立表 `indicator_mapping_rules`(source_type+raw_name→definition_id),exact→fuzzy→AI兜底→惰性注册 | Oracle 评审:比在 definitions 上加 aliases 列更可运营、可支撑 fuzzy/AI 兜底 |
+| 食材推荐 | 保留 `food_recommend_idx`+`log`(变化日志语义),同时**增写** `indicator_values`(source_type=food_recommend) | 不破坏现有变化日志接口 |
+| 双写一致性 | 单一写者模式:解析照旧写 `health_indicators`,`NormalizeIndicatorPipeline` 同流程写 `indicator_values`,幂等覆盖 | Oracle 评审:避免两表分叉 |
+| 校准算法 | Spearman 秩相关;单对象 ≥3 配对、聚合有效样本 ≥30 才用 computed 覆盖 manual;非数值型对跳过 | 菌群丰度偏态分布,Spearman 稳健;样本不足不误导 |
+| 图表实现 | 沿用小程序手写 canvas 模式,新增 `TrendChart.vue`,不引入图表库 | 小程序包体积 + HBuilderX 打包约束 |
+| 变化着色 | `good_direction`(越高越好/越低越好/区间内越好)驱动箭头与颜色 | Oracle 评审:没有它无法判断变化是改善还是恶化 |
+| 关联对排序 | `definition_id_a < definition_id_b`(按 code 字典序),应用层强制 | 唯一键对称,避免 A-B / B-A 重复 |
+
+---
+
+## 4. 数据模型
+
+### 4.1 报告日期修正
+
+- PDF 解析阶段(`PdfParseService` / LangGraph `report_parse_agent.py`)新增提取「报告日期 / 采样日期」→ `payload.reportDate`
+- 入库时 `health_reports.report_date` 优先使用真实日期,缺失回退上传时间
+- 历史回填任务:扫描 `report_date` 缺失或为上传时间的旧报告,从其 `payload_json` / 存储 PDF 中重新提取真实日期并回填;**幂等可重跑**;无法提取的置 NULL(不伪装成上传时间)
+- ⚠️ 实现前先确认 `health_indicators.collection_date` 列在数据库真实存在(实体注释标注「DB列不存在」),若确实缺失先补迁移
+
+### 4.2 `indicator_definitions` 扩展
+
+新增列:
+
+| 列 | 类型 | 说明 |
+|---|---|---|
+| `source_kind` | VARCHAR(32) | `report_indicator` / `bacteria` / `food_index` / `dimension_score` |
+| `report_type_scope` | VARCHAR(32) | 适用报告类型(空=通用),支撑「同一类报告」分组 |
+| `value_type` | VARCHAR(16) | `numeric` / `categorical` / `level`(语义类型,与 dataType 区分) |
+| `good_direction` | VARCHAR(16) | `higher_is_better` / `lower_is_better` / `in_range_is_better` / `neutral` |
+| `dimension_code` | VARCHAR(16) | 关联五维(body/mind/wisdom/action/wealth,可空) |
+
+保留现有:`domain` / `category` / `code` / `name` / `dataType` / `options` / `unit` / `refRange` / `sortOrder` / `status`。
+
+**目录来源**:
+- `report_type_registry.expected_indicators` → 预生成每类报告的指标定义
+- 菌属 200+ / 食材 224 → **惰性注册**(首次出现即 upsert,不预埋),code 使用 `bacteria.<name>` / `food.<foodId>` / `indicator.<category>.<name>` 风格
+- 五维/七维 → 预置少量定义(`dim.body` 等,仅作展示标签,不写 indicator_values)
+
+### 4.3 `indicator_values` 扩展(统一观测时序)
+
+新增列:
+
+| 列 | 类型 | 说明 |
+|---|---|---|
+| `subject_id` | BIGINT | 观测对象(对齐 `health_reports.subject_id` / family_members.id) |
+| `family_id` | BIGINT | 所属家庭 |
+| `report_id` | BIGINT | 来源报告(可空:食物指数 / 维度评分类) |
+| `report_date` | DATE | 冗余报告日期,供时序查询 |
+| `unit` | VARCHAR(32) | 观测单位(若与定义不一致,写入时告警) |
+| `status` | VARCHAR(32) | 观测时状态快照(正常/偏高/偏低…) |
+
+保留现有:`source_type` / `source_id` / `definition_id` / `value` / `numeric_value` / `remark` / `recorded_at`。
+
+**索引与约束**:
+```sql
+ALTER TABLE indicator_values
+  ADD COLUMN subject_id BIGINT NULL,
+  ADD COLUMN family_id BIGINT NULL,
+  ADD COLUMN report_id BIGINT NULL,
+  ADD COLUMN report_date DATE NULL,
+  ADD COLUMN unit VARCHAR(32) NULL,
+  ADD COLUMN status VARCHAR(32) NULL,
+  ADD UNIQUE KEY uk_source_definition (source_type, source_id, definition_id),
+  ADD INDEX idx_subject_def_date (subject_id, definition_id, report_date),
+  ADD INDEX idx_def (definition_id);
+```
+
+- 唯一约束保证**幂等**:同一 (source_type, source_id, definition_id) 重解析只覆盖更新
+- `source_type` 取值:报告类型(`gut_flora` 等)/ `food_recommend` / `dimension_score`
+
+### 4.4 `indicator_mapping_rules`(新建)
+
+```sql
+CREATE TABLE IF NOT EXISTS indicator_mapping_rules (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  source_type VARCHAR(32) NOT NULL COMMENT 'gut_flora|physical_exam|dan_a2|food_recommend|five_dimension|health_dimension',
+  raw_name VARCHAR(200) NOT NULL COMMENT '报告中的原始名称(指标名/菌名/食材名)',
+  alias_text TEXT COMMENT '别名 JSON 数组,用于模糊匹配',
+  definition_id BIGINT NOT NULL COMMENT 'FK → indicator_definitions.id',
+  match_type VARCHAR(20) DEFAULT 'exact' COMMENT 'exact|fuzzy|ai_fallback|auto_created',
+  priority INT DEFAULT 0 COMMENT '多规则冲突时取最高',
+  status TINYINT DEFAULT 1,
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  UNIQUE KEY uk_source_raw (source_type, raw_name),
+  INDEX idx_def (definition_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='指标归一化映射规则';
+```
+
+### 4.5 `indicator_correlations`(新建)
+
+```sql
+CREATE TABLE IF NOT EXISTS indicator_correlations (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  definition_id_a BIGINT NOT NULL COMMENT 'code 字典序较小的指标',
+  definition_id_b BIGINT NOT NULL COMMENT 'code 字典序较大的指标',
+  relation_type VARCHAR(20) DEFAULT 'correlation' COMMENT 'correlation(相关)|influence(影响)|same_source(同源)',
+  direction VARCHAR(10) NOT NULL COMMENT 'positive|negative',
+  manual_strength DECIMAL(3,2) NOT NULL COMMENT '人工标定强度 0~1,样本不足时使用',
+  computed_strength DECIMAL(4,3) NULL COMMENT '统计计算相关系数(Spearman rho)',
+  method VARCHAR(20) DEFAULT 'spearman' COMMENT 'pearson|spearman',
+  sample_size INT DEFAULT 0 COMMENT '参与计算的聚合有效样本数',
+  confidence VARCHAR(10) COMMENT 'high(>=30)|medium(10~29)|low(<10)',
+  effective_strength DECIMAL(4,3) NOT NULL COMMENT '展示值:有效样本>=30 时取 computed,否则取 manual',
+  manual_locked TINYINT DEFAULT 0 COMMENT '1=人工锁定,数据校准不覆盖 direction/manual_strength/effective_strength',
+  cohort_scope VARCHAR(20) DEFAULT 'subject' COMMENT 'subject|family|population',
+  status VARCHAR(20) DEFAULT 'active' COMMENT 'active|inactive|pending',
+  computed_at DATETIME NULL COMMENT '最后校准时间',
+  created_by BIGINT NULL COMMENT '创建者(人工定义时)',
+  description VARCHAR(500) NULL COMMENT '给用户看的解释',
+  source_note VARCHAR(255) NULL COMMENT '依据/出处',
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  UNIQUE KEY uk_pair (definition_id_a, definition_id_b),
+  INDEX idx_def_a (definition_id_a),
+  INDEX idx_def_b (definition_id_b)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='指标关联关系(人工定义 + 数据校准)';
+```
+
+**对序规则**:写入前按 `definition.code` 字典序比较,小的存 `a`、大的存 `b`,应用层强制,保证唯一键对称。
+
+### 4.6 数据校准(Spearman 任务)
+
+- 定时任务(Spring `@Scheduled`,每日凌晨)+ 管理端手动触发(`/api/admin/indicator/correlation/calibrate`)
+- 范围:`status='active'` 且 `manual_locked=0` 的关联对
+- 算法:
+  1. 仅计算两端指标均为数值型/有序等级型的配对(`value_type IN ('numeric','level')`)
+  2. 按 `subject_id` 分组,对每个对象取该指标对的**配对测量序列**(按 report_date 对齐,≥3 个配对点才参与)
+  3. 每对象算 Spearman rho → Fisher z 变换 → 全对象 z 均值 → 还原为平均 rho
+  4. 有效样本量 = 参与聚合的对象配对点总数;`confidence`:≥30 → high,10~29 → medium,<10 → low
+  5. 更新 `computed_strength` / `sample_size` / `method` / `confidence` / `computed_at`
+  6. `effective_strength = 有效样本>=30 ? computed_strength : manual_strength`(方向若与人工矛盾且锁定时,保持人工)
+- Java 8 无内置相关函数:新增约 20 行工具方法(排序后计算秩差平方),不引外部依赖
+
+---
+
+## 5. 归一化映射管道(单一写者)
+
+```
+报告解析/采集确认(或重解析)
+  ├─ 原有逻辑照旧写 health_indicators(不动现有消费者:HealthAnalysisService 等)
+  └─ NormalizeIndicatorPipeline(同流程/同事务内)
+       1. 收集该报告全部:health_indicators 明细 + 菌属(payload/gut_flora)+ 食物(payload/食材)
+       2. 每条 (source_type=报告类型, raw_name) 解析 definition_id:
+            exact 命中 indicator_mapping_rules → definition_id
+            fuzzy 命中(CJK 二元组 / 拼音归一化)→ definition_id
+            AI 兜底(AiGateway → LangGraph 归类)→ 建议 definition_id(登记 pending 规则,管理端确认)
+            新发现 → 惰性注册新 definition + 自动登记 exact 规则(match_type=auto_created)
+       3. 幂等写入 indicator_values
+            INSERT ... ON DUPLICATE KEY UPDATE (source_type, source_id, definition_id)
+       4. 记录 subject_id / family_id / report_id / report_date(真实报告日期)
+```
+
+**食物推荐指数钩子**:`FoodRecommendService.recalculateForUser()` 完成后,把该用户最新 `food_recommend_idx` 全量快照写入 `indicator_values`(`source_type=food_recommend`,`source_id=food_recommend_idx.id`,`definition_id` 经 `food.<foodId>` 映射)。
+
+**批量种子**:管理端 `/api/admin/indicator/mapping/import` 一次性导入菌属 200+ / 食材 224 / expected_indicators 的映射种子。
+
+---
+
+## 6. 后端 API 契约
+
+> 统一 `@PostMapping`、`Result<T>`、JWT;`subject_id` 服务端校验归属(当前用户家庭内成员)。
+
+### 6.1 指标曲线
+
+```
+POST /api/indicator/trend
+body: { subjectId, definitionIds: [1,2,3] }
+→ data: {
+    "items": [{
+      "definitionId": 1, "name": "双歧杆菌属",
+      "points": [ { "reportDate":"2026-08-15", "value":"12.8", "unit":"%", "status":"偏高" }, ... ]
+    }]
+  }
+```
+
+横轴 `reportDate` = 真实报告日期,升序。
+
+### 6.2 变化幅度排名
+
+```
+POST /api/indicator/change-ranking
+body: { subjectId, reportType?, category?, scope: "adjacent"|"first-vs-latest", orderBy: "up"|"down"|"magnitude", limit: 50 }
+→ data: {
+    "items": [{
+      "definitionId": 5, "name": "维生素B1", "category": "维生素",
+      "sourceKind": "report_indicator", "unit": "mg",
+      "before": { "reportDate":"2026-08-15", "value":"2" },
+      "after":  { "reportDate":"2026-10-01", "value":"4" },
+      "delta": 2, "deltaPct": 100,
+      "movement": "up"|"down"|"flat",
+      "trendLabel": "改善"|"恶化"|"中性"   // 按 good_direction 判定
+    }],
+    "overall": { "improvedCount": 12, "worsenedCount": 3, "flatCount": 5 }
+  }
+```
+
+- `scope=adjacent`:相邻两次报告之差(默认);`first-vs-latest`:首尾对比
+- 排序:`magnitude` 按 Δ 绝对值降序(默认);`up`/`down` 按 Δ 正/负降序
+- 食材指数单独过滤(`sourceKind=food_index`)或混合(按 category 过滤)
+
+### 6.3 指标速查
+
+```
+POST /api/indicator/quick-lookup
+body: { subjectId, category?, page: 1, pageSize: 30 }
+→ data: {
+    "categories": [ { "name":"核心菌属", "total": 32 }, ... ],
+    "items": [{
+      "definitionId": 1, "name": "双歧杆菌属", "category": "核心菌属",
+      "value": "12.8", "unit": "%", "refRange": "0.19-14.59", "status": "偏高",
+      "trend": "up"|"down"|"flat", "trendLabel": "改善",
+      "latestReportDate": "2026-10-01", "pointsCount": 3
+    }],
+    "dimensionScores": [   // 五维/七维评分小节(不写 indicator_values,API 层 join 原表)
+      { "dimensionCode":"body", "name":"身", "score": 82, "assessedAt":"2026-09-30", "trend": "up" }
+    ]
+  }
+```
+
+分类分页(每类 ≤30 项),避免一次拉取 200+ 菌属。
+
+### 6.4 指标关联查询
+
+```
+POST /api/indicator/correlation/list
+body: { subjectId, definitionId }
+→ data: {
+    "relations": [{
+      "relation": { "pairId": 1, "indicatorA": {"definitionId":1,"name":"记忆力"}, "indicatorB": {...},
+                    "direction":"positive", "effectiveStrength": 0.72,
+                    "strengthSource":"computed"|"manual", "sampleSize": 45,
+                    "confidence":"high", "manualLocked": false,
+                    "description":"记忆力与睡眠相关菌群含量正相关……" },
+      "subjectEvidence": {   // 该成员自己的配对数据支撑(如有)
+        "points": 4, "personalRho": 0.68, "hasEnough": true
+      }
+    }]
+  }
+```
+
+### 6.5 管理端(cfc-web)
+
+| 接口 | 用途 |
+|---|---|
+| `POST /api/admin/indicator/correlation/save` | 人工定义/编辑关联对(A/B/方向/人工强度/说明/locked/来源) |
+| `POST /api/admin/indicator/correlation/list` | 关联对分页列表(含校准状态) |
+| `POST /api/admin/indicator/correlation/calibrate` | 手动触发全校准或单对校准 |
+| `POST /api/admin/indicator/mapping/import` | 批量导入映射种子(JSON/CSV) |
+| `POST /api/admin/indicator/mapping/list` | 映射规则分页 + 未匹配 raw 的 review 列表 |
+
+### 6.6 复用既有接口
+
+- `POST /api/food/recommendation/trend`(食材单指标趋势)继续用于菌群食物详情页
+- `POST /api/health/knowledge/query` 知识库弹出框继续用于速查/曲线页指标名称点击
+
+---
+
+## 7. 前端页面
+
+### 7.1 小程序(家长端双角色视图)
+
+**指标变化曲线页** `pages/health/indicator-curve.vue`(新增)
+- 入口:菌群报告详情页顶部「变化」入口、`pages/health/report-list` 顶部、身维度页
+- 布局:
+  - 顶部筛选:成员切换 + 报告类型 + 时间范围
+  - 曲线区:指标选择器 → `TrendChart` 折线(横轴=真实报告日期,多报告点,数据点标注数值)
+  - 变化排名区:Tab(菌群变化 / 食材变化 / 指标变化)+ 排序(升幅↑ / 降幅↓ / 绝对幅度);相邻两次报告 Δ;按 `good_direction` 着色
+- 图表:新增通用 `components/TrendChart.vue`(多序列折线 + 数据点 + 箭头),沿用**手写 canvas** 模式(参考 `RadarChart.vue` 的 type=2d + DPR 适配 + 重试初始化),不引入图表库
+
+**指标速查页** `pages/health/indicator-quicklook.vue`(新增)
+- 分类 Tab + 分页(每类 ≤30 项/页)
+- 每项一行:名称(可点弹知识库,复用 `health-knowledge-popup`)| 最新值 | 参考区间 | ↑↓→ 趋势 | 最近报告日期
+- 独立小节:五维/七维评分趋势
+- 点击单项 → 跳转该指标曲线页(携带 definitionId)
+
+**菌群报告详情页** `pages/health/gut-flora-detail.vue`(改)
+- 增加「变化」区块:最近两次同类型报告的菌属 Δ,红/绿标注(一期仅此报告详情页;DAN/体检详情页变化区块留到二期)
+
+**pages.json**:注册 2 个新页面路径;**utils/api.js**:新增 trend / change-ranking / quick-lookup / correlation/list 封装(遵守 API 去重规范,同 URL 单一规范入口)
+
+### 7.2 Web 管理端(cfc-web)
+
+**`views/admin/IndicatorCorrelations.vue`**(新增)
+- 关联对配置:选 A/B 指标(定义搜索框)、方向、人工强度、说明、`manual_locked` 开关
+- 列表:computed_strength / sample_size / confidence / last_calibrated_at;一键触发校准
+
+**`views/admin/IndicatorMappings.vue`**(新增)
+- 归一化规则管理(source_type + raw_name → definition_id)+ 批量导入 + 未匹配 raw review(AI 建议确认)
+
+**router**:注册对应管理端路由(admin 权限)
+
+---
+
+## 8. 变化颜色与箭头规则
+
+由 `good_direction` × 变化方向判定,全局统一:
+
+| good_direction | 数值↑ | 数值↓ | 备注 |
+|---|---|---|---|
+| `higher_is_better` | 🟢 绿 ↑(改善) | 🔴 红 ↓(恶化) | 如双歧杆菌属 |
+| `lower_is_better` | 🔴 红 ↑(恶化) | 🟢 绿 ↓(改善) | 如炎症水平 |
+| `in_range_is_better` | 向参考区间内移动 → 🟢 绿 ↑/↓;远离 → 🔴 红 | 结合 refRange 判定 | 如维生素 |
+| `neutral` | ⚪ 灰 ↑ | ⚪ 灰 ↓ | 无优劣方向 |
+| 无变化 | ⚪ 灰 → | | |
+
+实现遵循小程序限制:`:class="'mb-' + item._cssClass"` 内联表达式(禁方法调用、禁中文类名),`_cssClass` 由后端或前端 computed 映射为英文(`impr-up`/`worst-down`/`flat` 等)。
+
+---
+
+## 9. 验收标准
+
+| # | 验收项 | 验证方式 |
+|---|---|---|
+| 1 | 上传第二份同类型报告后,曲线页显示完整前后对比;变化排名按幅度排序正确 | 手工 + e2e |
+| 2 | 变化箭头颜色符合 good_direction(如炎症下降=绿、双歧杆菌上升=绿) | 手工 |
+| 3 | 速查按分类分页正常,含五维/七维小节;点击单项跳转曲线 | 手工 |
+| 4 | 管理端配置关联对 → 小程序立即可见;有真实配对数据显示校准强度+样本量;样本<30 显示人工值 | 手工 |
+| 5 | 新报告 report_date = PDF 真实日期;历史回填任务幂等可重跑(连跑两次结果一致) | 脚本 + 手工 |
+| 6 | 归一化幂等:同一报告重解析不产生重复 observation(唯一键生效) | 脚本断言 |
+| 7 | `report_type_registry.expected_indicators` 与默认映射种子导入后,解析出的常见指标 100% 命中映射(无 AI 兜底) | 脚本统计 |
+| 8 | `mvn clean compile` 通过;前端 script 语法校验(node --check)通过;API 去重审计通过 | CI 命令 |
+
+---
+
+## 10. 文件变更清单
+
+| 层 | 文件 | 操作 | 内容 |
+|---|---|---|---|
+| 后端 | `config/DatabaseInitializer.java` | 改 | 迁移:definitions/values 加列 + 索引 + 唯一键;新建 mapping_rules/correlations 两表;report_date 真实日期回填;确认/修复 health_indicators.collection_date;种子映射导入(迁移编号递增查找) |
+| 后端 | `resources/schema.sql` | 改 | 同步 4 处 DDL |
+| 后端 | `entity/IndicatorDefinition.java` / `IndicatorValue.java` | 改 | 新字段 |
+| 后端 | `entity/IndicatorMappingRule.java` / `entity/IndicatorCorrelation.java` | 新建 | 新实体 |
+| 后端 | `mapper/IndicatorMappingRuleMapper.java` / `mapper/IndicatorCorrelationMapper.java` | 新建 | BaseMapper |
+| 后端 | `service/IndicatorMappingService.java` | 新建 | resolve(raw)→definitionId;register;import 种子 |
+| 后端 | `service/NormalizeIndicatorPipeline.java` | 新建 | 解析后钩子,幂等写 indicator_values |
+| 后端 | `service/IndicatorTrendService.java` | 新建 | trend / change-ranking / quick-lookup |
+| 后端 | `service/IndicatorCorrelationService.java` | 新建 | 关联 CRUD + effective_strength + Spearman 校准 |
+| 后端 | `service/ReportDateExtractor.java` | 新建 | PDF/payload 真实日期提取 + 回填 |
+| 后端 | `controller/IndicatorController.java` | 新建 | /api/indicator/*(4 个视图接口) |
+| 后端 | `controller/admin/IndicatorCorrelationAdminController.java` / `IndicatorMappingAdminController.java` | 新建 | 管理端接口 |
+| 后端 | `service/FoodRecommendService.java` | 改 | recalculateForUser 后增写 indicator_values |
+| 后端 | `service/AiGateway.java`(及 LangGraph) | 改 | 新增指标归类兜底方法/endpoint |
+| 后端 | 新增 `job/IndicatorCalibrationJob.java` | 新建 | @Scheduled 每日校准 |
+| 小程序 | `components/TrendChart.vue` | 新建 | 通用折线组件(手写 canvas) |
+| 小程序 | `pages/health/indicator-curve.vue` / `indicator-quicklook.vue` | 新建 | 曲线页 / 速查页 |
+| 小程序 | `pages/health/gut-flora-detail.vue` | 改 | 增加「变化」区块 |
+| 小程序 | `pages.json` | 改 | 注册 2 页 |
+| 小程序 | `utils/api.js` | 改 | 新增 4 个接口封装 |
+| Web 端 | `views/admin/IndicatorCorrelations.vue` / `IndicatorMappings.vue` | 新建 | 关联配置 / 映射管理 |
+| Web 端 | `router/index.js` | 改 | 注册管理端路由 |
+| 测试 | `tests/e2e/indicator-curve-flow.spec.js` 等 | 新建 | 曲线/速查/关联冒烟 |
+
+---
+
+## 11. 风险与权衡
+
+| 风险 | 缓解 |
+|---|---|
+| 归一化映射质量(AI 兜底可能错配) | 映射规则管理端可 review;AI 建议先登记 pending,人工确认后生效 |
+| 双写一致性(health_indicators vs indicator_values) | 单一写者;同事务;唯一键幂等覆盖 |
+| 速查性能(200+ 菌属 × 多次报告) | subject_id + 复合索引;分类分页;每类 30 项 |
+| 历史报告回填工作量大 | 分批、幂等、可中断续跑;取不出日期的置 NULL |
+| 方向/颜色误判 | good_direction 管理端可维护;一期手配,二期自动推断 |
+| 关联校准样本不足 | effective_strength 逻辑:样本 ≥30 才用计算值,否则人工值;confidence 分级展示 |
+| 指标名变化(同一菌不同报告写法不同) | fuzzy 匹配 + alias_text + AI 兜底多级回落 |
+
+---
+
+## 12. 实现顺序(分期)
+
+1. **P1 后端数据层**:迁移(4 处 DDL + report_date 回填 + collection_date 确认)→ 实体/Mapper/Service → `mvn clean compile`
+2. **P2 归一化管道**:`IndicatorMappingService` + `NormalizeIndicatorPipeline` + 食物钩子 + 种子导入 → 幂等验证
+3. **P3 视图 API**:trend / change-ranking / quick-lookup(含五维七维小节)+ correlation/list → `mvn clean compile`
+4. **P4 小程序页面**:`TrendChart` → 曲线页 → 速查页 → 菌群详情「变化」区块 → pages.json / api.js → HBuilderX 打包人工验证
+5. **P5 管理端**:`IndicatorCorrelations.vue` + `IndicatorMappings.vue` + admin API + 路由
+6. **P6 校准任务**:Spearman 工具 + `IndicatorCalibrationJob` + 管理端手动触发 + 验收清单逐项过
+
+---
+
+## 13. 二期展望
+
+- DAN / 体检等其余报告详情页「变化」区块
+- 跨报告类型同曲线叠加对比(菌群乳杆菌 vs 体检某项)
+- 关联关系的知识库弹出框内展示(点击关联项弹出说明)
+- `good_direction` 从参考区间/历史数据自动推断
+- 关联方向与人工矛盾时的冲突提醒与运营工作流