Files
dpb/doc/桃育种系统模块扩展需求规格.v2.3.md
T
34047007@qq.com b95053c52c init: 初始化 dpb 桃育种系统代码库
前后端 + 后端 FastAPI 全量源码、部署脚本与文档。
2026-08-06 00:17:49 +08:00

965 lines
107 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.
# 桃育种系统 · 模块扩展需求规格(V2 草案)
> 编制日期:2026-07-28
> 依据:通用育种软件功能清单(用户提供) + 国际成熟方案(BrAPI / BMS·Breedbase / RosBREED / MIAPPE / Crop Ontology / FAO-MCPD / Genesys + `doc\果树所\育种\yz.sql` 真实桃性状 + 现有 14 个 breeding 域
> 状态:**草案,待评审**。字段取值/枚举以「待确认」标注处需与业务方对齐后再落地(遵循"不确定不擅自动手"准则)。
## 版本历史
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.0 | 2026-07-28 | 初稿+复审:14 域对标、新增 7 模块、§8 复审(9 遗漏)、EAV 定稿为混合固定列。BrAPI/MIAPPE/team/库存 待定 |
| v1.1 | 2026-07-28 | 决策落地:① 采纳**直接对齐 BrAPI API**(新增 BrAPI 只读适配层)② 采纳 **MIAPPE 合规****不建 team 模块**(仅数据隔离,不需要,留 RBAC+created_id)④ **库存延后**(暂用报表) |
| v1.2 | 2026-07-28 | 取值决策(用户授权"你来定"):敲定 stage/generation/group_type/design_type 四枚举(§9+ propagation 纳入一期(§3.8);trait 种子建议 yz.sql;字段表补 generation/germplasm_id |
| v1.3 | 2026-07-28 | §8 二次复审落地:① **MET 链路彻底修补**trial_study.block_count + planting.trial_study_id + tree.trial_study_id/block_no + plot.block_no),与库存 `seed_lot` 一并建模,形成 seed_lot→seedling→planting→tree→trial_study 选择强度链(§3.13/§4/§5)② §0 原则1 与混合模型对齐(修订措辞)③ observation/field_operation 改显式 FK(弃多态)④ 补 environment_condition / audit_log / selection_rule / prediction 字段规格(§3.9–§3.12)⑤ tree_evaluation 明确"按 pa_four 扩列"+ 统一性状值视图 ⑥ 补「选择阈值规则」+「批量表型导入」规划 ⑦ 文档计数/枚举对齐修正 |
| v1.4 | 2026-07-28 | 国际基准三轮复审(BrAPI/Breedbase/RosBREED/MIAPPE/Crop Ontology/FAO-MCPD/Genesys)落地:① 新增 `trial_study_entry`entry 清单+entry_numberMET 设计矩阵)② site 补 lat/long/elevation(空间 BLUP/MIAPPE)③ observation 加 `status` 校验态(数据质量)④ trait 加 `ontology_uri`Crop Ontology 对接)⑤ 明确 tree.trial_study_id/block_no 为**派生**(单写点=planting,防双真相漂移)⑥ germplasm 补护照描述符块(FAO-MCPD)⑦ 新增 `genotyping_dataset`+marker.panelGS 训练群体分组)⑧ selection_result 加 `rule_id`(决策闭环)⑨ 补 crossing block 父/母本树(pollination 挂 female/male_tree_id)⑩ experiment_factor / breeding_report / breeding_program 标记延后。详见 §8.6 |
| v1.6 | 2026-07-28 | 第五轮复审(v1.5 自洽+国际盲点)全部采纳:① tree_evaluation 加 trial_study_idA1 核心性状环境键)② planting 粒度=block 级 + entry 跨 block 多 plantingA2)③ 新增 planting_treatment 关联表(A3)④ seed_lot.used_count 明确粒数(A4)⑤ §4 补 tree_photo 行(A5)⑥ tree→germplasm 重复测量聚合 EBVA6)⑦ 国际补强:marker.assembly_version、genotype_call VCF/GP、trial_study.season、observation.validated_by/date/unit、trait.method_uri/scale_uri、planting.propagation_id、observationUnit level、kinship A 矩阵、selection_rule EBV 阈值、breeding_program 自由文本说明 ⑧ selection_result.trial_study_id、新表数据权限约束(并补齐 v1.5 因替换异常遗漏的 §3.14/treatment 行/used_count)。详见 §8.8 |
| v1.7 | 2026-07-28 | V2.11 方案书《统计分析决策支持》逐条对照评估落地(用户确认报告一期必须):① **`breeding_report` 确认进一期**(P2,年度 Word/PDF 报告实体+生成服务,不再仅只读端点,原 v1.4 延后项移除)② **`breeding_prediction_value` 值表前移 V1.1**(与 V1.1 统计引擎同期持久化 EBV,支撑年遗传趋势图/双轨选择/亲本单株决策;仅 GS 模型训练留 V2.0)③ `tree_evaluation``crop_load`(坐果量评级 1/2/3 协变量,降果实性状环境误差,专册 1.3)④ `breeding_trait``valid_min/valid_max`(自定义生物学合理阈值,数据质量校验/异常标记)⑤ 超期预警/通知列为工程项(cron + selection_rule,不阻塞数据模型)。详见 §8.9 |
| v1.8 | 2026-07-29 | 团队/课题组隔离收口(讨论定稿):**不建 team 模块,改用系统已有 `sys_dept` 承载"课题组"**,启用框架"本部门及子部门"数据范围实现**课题组间隔离**;breeding 业务表**不加 `owner_team` 字段**(隔离靠创建者 `dept_id` 推断,由 `Permission._permission_condition()` 自动注入)。边界:性状字典/选择规则/种质/基地地块/人员等**公共基础数据跨组共享**;育种流程(杂交→评价)与统计分析(育种值/指数/报告)**按课题组隔离**。落地为配置级(建 dept 节点+配角色 data_scope+用户归属),非代码,需确认真实课题组清单后执行。 |
| v1.9 | 2026-07-29 | **枚举归属决策(方案A 已定)**:性状的**量表选项/范围**单一真相内联在 `breeding_trait.scale_json`categorical 存 `options`、numeric 存 `min/max/step`),**不进 `sys_dict`**`sys_dict` 仅承载"实体状态/分类枚举"(§9 的 `breeding_stage`/`breeding_generation``tree.status``germplasm_type` 等,非被测变量)。与"生成器机制 A/B/C"是两回事,勿混。详见 §3.1 / §0 原则1。 |
| v2.0 | 2026-07-30 | **遗传评估数据模型架构决策锁定**:① 新增 **`breeding_clone` 独立系谱表**(§3.0clone_id/combination_id/母父本/planting_year/status**无砧木**),与 `germplasm`(亲本/种质档案)**分离**,聚合路径由 `tree.germplasm_id`→germplasm 级 EBV 改为 `tree.clone_id``breeding_clone` 级 EBV(§3.0/§4/§5 同步修订)② `breeding_trait``stage`juvenile/evaluation,与 `category` 正交)③ 新增 **`breeding_rootstock` 砧木字典**(§3.17,只挂 observation 层)④ 新增 **数据质量门禁**(§3.16:缺失标记/异常值/单位强校验/按(clone_id,地点,年份,性状名)去重)⑤ 显式锁定 **砧木建模铁律**(§5.x:记 observation 层 + BLUP 固定效应扣除 + 绝不进 A 矩阵)⑥ 新增 **间接早选**(§5.y)⑦ 实施路线最前插入 **第0阶段 数据治理**(占40%、前置)。均为决策锁定、方案态,待用户"做"后落地 |
| v2.1 | 2026-07-30 | **review 修订(R1R9**:① **R1** §4 tree 加 `clone_id`(FK→breeding_clone,定植必填,聚合锚点) ② **R2** 系谱升级为独立 `breeding_pedigree`(§3.18,个体覆盖 clone+germplasm,dam/sire 指回本表递归闭环)`breeding_clone.female/male_parent_id` 降冗余;`germplasm.pedigree` 自由文本移除 ③ **R3** `breeding_prediction_value``heritability`(h² 同批次落库)、个体锚点改 `clone_id`**R4** 新增模型健康监控(§5.z:h²连年突降/排名翻转告警) ⑤ **R5** 报告 §5.2 模块1 去掉种质内联表型/系谱 ⑥ **R6** 报告 R 引擎统一 subprocess 隔离(弃 rpy2) ⑦ **R7** 统一表名 `breeding_observation`**R8** GCA/SCA 定位为亲本选配辅助 ⑨ **R9** 混合模型加 `clone×year` 随机互作。仍方案态,待"做"落地 |
| v2.2 | 2026-07-30 | **深度复审 A–H 全量落地(用户逐条确认 + F1/F2 架构拍板)**,详见 §8.10:**A 组内部矛盾**——A1 `tree.clone_id` 改为「实生苗定植可空/参试无性系必填、入选晋升才建 clone」(删"定植必填/1树=1clone");A2 `produced_clone_id`=被扩繁原 clone(沿用不新建);A3 全文 `rootstock_id` 统一 FK→`breeding_rootstock`(删 FK→germplasm);A4 A 矩阵系谱以 `breeding_pedigree` 为唯一权威、combination 父母本仅作派生源。**B 组统计**——B1 `heritability` 由明细移主表 `breeding_prediction`;B2 术语正名**加性(狭义)遗传力**、落库取克隆均值 h²=V_clone/(V_clone+V_e/k̄)B3 补 sommer 基线公式;B4 双轨选择统一 clone 级判定。**C 组门禁**——C1 门禁作用于 `breeding_trait_observation` 长表;C2 加 `issue_status`;C3 门禁×状态机衔接。**D 组 clone 居中**——D1 `selection_result`+clone_idD2 `breeding_clone`+generationD3 `trial_study_entry`+clone_idD4 补 tree↔clone 状态流转矩阵。**F 组架构(本轮拍板)**——F1 **裁定走单一长表、废固定列、报表用视图 pivot**F2 保留两张长表职责正交(`breeding_trait_observation` 单株鉴定明细/喂 EBV`breeding_observation` 仅 plot/combination+物候/不喂 EBV),plot 级果实均值由**统计 VIEW 聚合、不双写**;统计管线用普通 **VIEW 保 fresh**、看板层才用 **MV**(MV 不得作 BLUP 输入);F3 门禁关键键实生苗阶段退化为 tree_id;F4 判重键含 tree_id(保 clonal replicates);F5 §5.2 公式补 rootstock 固定效应。**G/H**——G1 统一编号服务定义+clone_id 序号扩位;G2 鉴定类表禁物理删+UPDATE 强制 auditG3 method 文本+method_uri 受控合并;H1-H3 打磨。仍方案态,待"做"落地 |
| v2.3 | 2026-08-04 | **统计引擎两轮 P0 代码落地(自 v2.0 起首次从方案态推进到可运行,均 e2e 验证通过)**,详见 §8.11 / `桃育种系统统计引擎实施记录.md`:① **G×E 交互引擎**(§5.2 互作项落地)——`run_ablup``gxe=True` + `gxe_env=site/year`method=GXEBLUP),site→自动固定效应 `trial_study`、year→`year`,σ²gxe/gxe_ratio/n_cross_env 落 `breeding_prediction.note`,不可辨识门禁(无跨环境重复/单元内无重复)→409,同 clone 多株坍缩为基因型节点 `c{clone}`,异步 `StatisticsJobModel` job_type=GXE/ABLUP+SUCCESS/FAILED;② **性状方向标注**(§3.1/§5.9/§5.z 落地)——`breeding_trait``direction`(desc/asc)/`into_ebv`(1/0)/`default_h2`(先验),选择指数(zsum/smith_hazel/EBV 排行/决策预览/轮次对比按方向归一,低优性状(裂果率/病害级别/酸度)不再选反;`into_ebv='0'` 仅从选种候选剔除;`default_h2` 无实测 h² 时兜底;并修复两处结构性 bug(`ebv_ranking` 方向盲区→读时重排、`compare_predictions` 硬编码降序→方向感知) |
---
## 0. 设计原则(本规格的宪法)
1. **性状字典与测量值分离 + 统一长表存储(对标 BrAPI `ObservationVariable` + `Observation`**`trait` 是唯一的性状字典(代码/类型/单位/量表),**新增桃性状只加字典、不动核心表结构**;测量值一律走**长表 EAV**,分两张职责正交的表——① **单株鉴定明细**`breeding_trait_observation`(挂 `evaluation_id`tree 级,clone 级 EBV 取数主路径)② **物候时序 + plot/combination 级观测**`breeding_observation`。统计层经"统一性状值视图"(DB 普通 `VIEW`,按 `trait_code` pivot)归一供 BLUP 消费(§8.4)。**v2.2/F1 裁定:废弃初稿"核心性状固定列 + EAV 双轨"口径——`tree_evaluation` 已删固定列、全迁 `breeding_trait_observation` 长表;当初上固定列的收益=报表/SQL 聚合快,改由 DB 视图/物化视图 pivot 顶上,不回退固定列)**。这是与初稿最大的修正:字典一处定义、值全部长表、报表用视图。
2. **Program/Trial/Study 三层(对标 BrAPI**:把"多年多点试验"从 site/plot 里抽象出来,支持同一品系跨生态点、跨年同步试验(MET, Multi-Environment Trial)。
3. **桃语义而非大田语义**:清单里的「P/F1/F2 世代、拔节期/抽穗期、播种季节、随机区组/间比」是按一年生大田作物(玉米/小麦)写的,**对桃(多年生无性繁殖果树)必须语义替换**(见 §1)。
4. **砧木–接穗建模**:桃特有的「嫁接繁殖」维度,现有系统完全缺失,必须补齐。
5. **预留分子层**`marker`/`genotype_sample`/`genotype_call` 对齐 BrAPI `Sample`+`Calls`,未来接 GBS / PeachSNP170K 做基因组选择(GS)不改骨架。
6. **统计与决策是地基不是补丁**:上面的数据模型必须能让 V1.1 统计引擎(R `sommer`/`lme4` 做 ABLUP/EBV、选择指数)与 V3.0 AI 决策直接消费,不做"先堆数据再补分析"的短视设计。
7. **API 直接对齐 BrAPI(已采纳)**:保留现有 `/breeding/*`UI 业务接口)的同时,新增 **BrAPI 兼容只读适配层**`/brapi/v2/...`)。数据模型已按 BrAPI 实体设计,适配成本低,可无缝对接 Breedbase / Flapjack / 国际数据交换,避免未来重复造导入导出。
8. **MIAPPE 合规(已采纳)**:试验元数据按 MIAPPE 的 **Investigation(=target/Program) / Study(=trial_study) / ObservationUnit(=tree/plot) / ObservationVariable(=trait)** 对齐,作为数据共享/投稿的一致性基线。
---
## 1. 桃育种语义替换表(清单 → 桃)
| 清单原文(大田作物语境) | 桃系统应改为 | 落点 |
|---|---|---|
| P / F1 / F2 世代(选择阶段) | **选择阶段 `stage`**:实生苗 → 初选株 → 复选株 → 品系 → 区试品系 → 新品种(枚举见 §9 | germplasm/tree/cross/selection_result 的 `stage` |
| 遗传世代 | **遗传世代 `generation`**F1 / F2 / BC1 / BC2 / BC3(与 `cross_type` 联动;引入种质留空) | 权威 `cross_combination.generation``tree`/`germplasm` 冗余拷贝便于筛选 |
| 拔节期 / 抽穗期 | 桃物候:萌芽 / 开花(初花·盛花) / 坐果 / 果实发育 / 成熟 / 落叶 | `observation`(物候类变量) |
| 播种季节 | 桃用**嫁接 / 定植**(砧木 + 接穗),非播种 | planting.rootstock_id → **breeding_rootstock**A3 |
| 自交系 | 桃为**克隆(无性繁殖)**,入选株 = 待审定克隆,需砧木关联 | germplasm.is_rootstock(仅"可作砧木"标记)/ tree.rootstock_id → **breeding_rootstock**(A3,全文砧木 FK 统一指字典,不指 germplasm |
| 随机区组 / 间比试验 | 桃果园株数少,简化为 **区组 + 重复 + 对照**轻量设计 | trial.design_type |
| 材料编号 | accession_no(唯一 accession 编号) | germplasm.accession_no |
**stage / generation 枚举(v1.2 已定,详 §9**:依 RosBREED 桃无性选育流水线与现有 14 域敲定,作为 `sys_dict` 新增字典类型(`breeding_stage` / `breeding_generation`),落库英码、前端显中文。
---
## 2. 目标模块总览(现有 14 + 新增 13,部分为规划)
**A. 现有 14 域(保留 + 字段调整)**
germplasm / site / plot / target / cross_combination / pollination / seed_treatment / seedling / planting / tree / tree_evaluation / tree_photo / selection_result / personnel
**B. 新增模块(P0P2,含 v1.3 复审补入)**
| 模块 | 表名 | BrAPI 映射 | 优先级 |
|---|---|---|---|
| trait(性状字典) | breeding_trait | ObservationVariable | P0 地基 |
| observationplot/物候观测) | breeding_observation | Observation | P0 地基 |
| trait_observation(单株鉴定明细,**v2.2/F2 补登记** | breeding_trait_observation | Observation | P0 地基 |
| field_operation(农事操作) | breeding_field_operation | Observation(op_type) | P0 |
| trial(多年多点试验) | breeding_trial + breeding_trial_study + **breeding_trial_study_entry**(v1.4) | Trial / Study / Entry | P1 |
| group(分组/标签) | breeding_group + breeding_group_member | List | P1 |
| statistics(统计报表) | breeding_report(配置)+ 聚合端点 | — | P2 |
| propagation(克隆扩繁) | breeding_propagation | — | P1(§3.8 |
| seed_lot(种子批·库存) | breeding_seed_lot | — | P1(§3.13,与 MET 一并建模) |
| environment_condition(环境因子) | breeding_environment_condition | — | P1(§3.9G×E 地基) |
| audit_log(审计日志) | breeding_audit_log | — | P1(§3.10 |
| selection_rule(选择阈值规则) | breeding_selection_rule | — | P1(§3.11,决策地基) |
| treatment(试验因子/处理) | breeding_treatment | Treatment(BrAPI) | P1(§3.14,支撑 split_plot 等设计的因子主效应/互作估计) |
| planting_treatment(定植-处理关联) | breeding_planting_treatment | — | P1(§3.15treatment 多对多落地) |
| 分子基因型层 | breeding_marker(含 panel) / breeding_genotype_sample / breeding_genotype_call + **breeding_genotyping_dataset**(v1.4) | Sample / Calls / Marker / Dataset | V2.0(地基先建) |
| prediction(育种值) | breeding_prediction / breeding_prediction_value | — | **值表 V1.1EBV 持久化)/ GS 模型训练 V2.0(§3.12** |
> 注:原稿数"21"已过期,此处以清单为准;其中 seed_lot / environment_condition / audit_log / selection_rule 为 v1.3 复审补入一期,`prediction` 留 V2.0。
**重要简化(避免模块膨胀)**
- **物候期不单列模块** → 只是 `observation` 中「物候类变量」的观测。
- **系谱树不单列模块** → 靠 `cross_combination.parent_combination_id` 自链 + `germplasm.pedigree` 字符串 + 前端 D3 树图 + `/pedigree/{id}` 聚合端点。
---
## 3. 新模块字段规格
### 3.0 breeding_clone(入选克隆系谱表,P0 数据治理地基)
> 桃为无性繁殖,入选株 = 待审定克隆。本表是**遗传身份(clone)层**,与亲本/种质档案 `germplasm`(父母本来源)**分离**(v2.0 决策:亲本资源 vs 入选克隆分离)。砧木只挂在 observation 层,**本表无砧木字段**(建模铁律,§5.x)。嫁接扩繁株沿用原 clone_id,不新建。
> **v2.2/A1 修订)** clone ≠ 每株实生苗。杂种实生苗定植时**不建 clone**`tree.clone_id` 可空),仅当该单株**入选晋升**时由流程创建一条 `breeding_clone` 并回填 `tree.clone_id`;参试无性系(来自 `entry`)定植即有 clone。故本表行数 = 入选克隆数(数百级),而非定植实生苗数(数千级),避免 EBV 全收缩到单株均值。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int | PK | 自增主键 |
| clone_id | varchar(32) | UNIQUE NOT NULL | 组合码 + **单株序(≥4 位,容纳单组合数千株,G1)**,如 `JY-DJB-001-0007`;全局唯一可追溯。**由统一编号服务在入选晋升时生成(§8.9),非定植时**(A1) |
| combination_id | int | FK→breeding_cross_combination NOT NULL | 所属杂交组合 |
| female_parent_id | int | FK→breeding_germplasm | 母本(**冗余直查列**;权威系谱见 §3.18 `breeding_pedigree`,避免 A 矩阵递归断裂) |
| male_parent_id | int | FK→breeding_germplasm | 父本(**冗余直查列**;同上) |
| planting_year | int | NOT NULL | 定植年份 |
| generation | varchar(16) | | **v2.2/D2**:世代 F1/BC1/F2…;脚注:可由 `combination_id`→组合父母本派生,与 `tree.generation` 保持一致,冗余存此便于 clone 级筛选与系谱世代统计 |
| status | varchar(1) | NOT NULL DEFAULT '1' | clone 级决选状态:1入选/2初选/3重点/4保存/5淘汰(淘汰=状态变更非删除) |
| uuid / is_deleted / created_time / updated_time / deleted_time | — | 同框架契约 | 审计与软删 |
**聚合语义**:同一 clone 经嫁接扩繁产生多株 `tree`,其表型是同一基因型的重复观测;统计前按 `tree.clone_id` 聚合为该 clone 的重复测量,EBV 随机效应估在 `breeding_clone` 级(`clone_id`),`tree` 仅作重复测量单元。此点取代原 `tree.germplasm_id → germplasm 级 EBV` 的聚合口径(§4/§5 同步修订)。**(v2.2/A1** 实生苗入选前无 clone_id,其童期观测按 `tree_id` 聚合(门禁键此阶段退化为 tree_id,见 §3.16/F3);入选建 clone 后再切换到 clone 级聚合。
### 3.1 breeding_trait(性状字典,P0
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| trait_code | varchar(64) | UNIQUE, NOT NULL | 如 `brix``fruit_weight``bloom_date` |
| trait_name | varchar(128) | NOT NULL | 中文名:可溶性固形物、单果重… |
| category | varchar(32) | NOT NULL | fruit/flower/plant/disease/phenology/yield/quality/rootstock(业务类别) |
| stage | varchar(16) | NOT NULL | **v2.0**:性状分段 `juvenile`(童期)/ `evaluation`(评价段),与 `category` **正交并存、不混用**;童期采集→间接早选,评价段采集→clone 级 EBV |
| data_type | varchar(16) | NOT NULL | numeric / categorical / date / boolean |
| unit | varchar(32) | NOT NULL | g、%、°Brix、mm、date**v2.0**:导入/观测时**强校验**,值单位须匹配,不符**整行拒收**(数据质量门禁,§3.17) |
| method | varchar(256) | | 测定方法自由文本(如折射仪、游标卡尺) |
| method_uri | varchar(256) | | **v2.2/G3**:受控词表方法 URICrop Ontology / MIAPPE Method),与 `method` 自由文本并存互补——`method` 供人读、`method_uri` 供 BrAPI/国际仓储对接;可空(合并 §6 路线图曾提的 method_uri,消除双字段漂移) |
| scale_json | jsonb | | 量表/选项(categorical 时存选项数组;numeric 时存 min/max/step |
| ontology_uri | varchar(256) | | **v1.4**Crop Ontology / Trait Ontology / MIAPPE 受控词表 term URI(如 `CO_356:0000041`),供 BrAPI 适配层与国际合作仓储对接;可空 |
| valid_min | numeric(12,4) | | **v1.7**:生物学合理下限(自定义阈值),数据质量校验/异常值自动标记用;可空(专册 3.3.2 数据质量监控) |
| valid_max | numeric(12,4) | | **v1.7**:生物学合理上限,同上;可空 |
| direction | varchar(16) | NOT NULL DEFAULT 'desc' | **v2.3 已落地**:性状方向 `desc`=越大越好(默认)/ `asc`=越小越好(**低优性状**:裂果率、病害级别、酸度——若目标是低酸)。选择指数(zsum/smith_hazel)、EBV 排行、决策预览、轮次对比均按此翻转贡献符号/排序方向,杜绝"高 EBV=优"隐含假设把低优性状选反 |
| into_ebv | varchar(1) | NOT NULL DEFAULT '1' | **v2.3 已落地**:是否选种目标 `1`=进 EBV/指数/决策候选(默认)/ `0`=仅记录(**仅从选种相关候选剔除**——指数候选/EBV 排行/决策预览/ABLUP 下拉;describe/correlation/trait_values 不受影响) |
| default_h2 | double precision | | **v2.3 已落地**:先验遗传力 h²(桃经典先验,可在性状字典修改);指数无实测 h² 时兜底(zsum/smith_hazel 均兜底,两者皆无才 409 拒绝) |
> **valid_min/max 局限说明(v2.2/H1**:本字段为**全局单值**,但果重/糖度等的生物学合理区间随**成熟期/年份/砧木**变化,全局阈值可能误标或漏标。一期口径:**接受全局阈值 + 人工复核**(门禁本就对异常值走人工复核,见 §3.16),不强制按 stage 分档;后续如需精细化,可在 `scale_json` 内按 stage 追加分档区间,不改表结构。
| is_preset | bool | default false | 是否系统内置(种子数据) |
| remark | varchar(512) | | |
| created_time / updated_time / is_deleted | 标准 | | 来自 ModelMixin |
> **BrAPI 映射简化说明(v1.4**BrAPI `ObservationVariable = Trait + Method + Scale` 三元组,本系统将 method/scale **内联合并**进 `trait`(桃单作物、方法稳定,避免三表 join 复杂度)。适配层导出 BrAPI 时需按此三元组拆分;`ontology_uri` 提供受控词表引用,满足 MIAPPE/Crop Ontology 可引用性。
**种子数据来源**`doc\果树所\育种\yz.sql``pa_four`(~40 字段:单果重/果形/果核/可溶性固形物/成熟期/离粘核/风味…)与物候类变量,导入为 `is_preset=true` 的桃专用性状字典。
> **枚举归属决策(v1.92026-07-29,方案A 已定)**:性状的**量表选项/范围**是性状定义的一部分,单一真相内联在 `scale_json`categorical 存 `options` 数组、numeric 存 `min/max/step`),**不进 `sys_dict`**`sys_dict` 仅承载"实体状态/分类枚举"(如 §9 的 `breeding_stage`/`breeding_generation`、`tree.status`、`germplasm_type` 等,非被测变量)。二者语义不同——性状=ObservationVariable(有 method/unit/obs_year/重复测量);分类枚举=实体一次设定属性,无测定方法/单位——**不得混用**。BrAPI 导出时 `scale_json`→Scale 三元组,无需 join `sys_dict`。这一定位与"方便统计分析"无关:统计引擎只读 `data_type`+实测值,选项清单存哪不影响计算;A 的真正收益是元数据自包含、防双源漂移、BrAPI 干净导出。
### 3.2 breeding_observation(通用观测,P0
> 采用**显式可空外键**`tree_id` / `plot_id` / `combination_id`),**不采用** `(unit_type, unit_id)` 多态——多态会破坏引用完整性、无法真正联表、且令现有 `_build_conditions` 数据权限注入(依赖已知 FK 列)失效。三者至多一个非空。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| tree_id | int FK→breeding_tree | 可空 | 观测单元=单株 |
| plot_id | int FK→breeding_plot | 可空 | 观测单元=小区 |
| combination_id | int FK→breeding_cross_combination | 可空 | 观测单元=杂交组合(如组合级表型) |
| trait_id | int FK→breeding_trait | NOT NULL | 测了哪个性状 |
| value_numeric | numeric(12,4) | | data_type=numeric 时 |
| value_text | varchar(512) | | categorical / boolean 存此 |
| value_date | date | | data_type=date 时 |
| obs_year | int | | 观测年份(MET 聚合键) |
| obs_date | date | | 具体日期 |
| site_id | int FK→breeding_site | | 观测地点(冗余便于聚合;亦可由 tree→plot→site 推导) |
| person_id | int FK→breeding_personnel | | 观测人 |
| trial_study_id | int FK→breeding_trial_study | 可空 | 区分「试验观测」vs「果园日常观测」;试验观测可参与 BLUP |
| status | varchar(16) | default "draft" | **v1.4**:数据质量态 `draft`(草稿)/`validated`(已校验);批量导入/多人观测下隔离脏数据,统计前按 validated 筛选 |
| issue_status | varchar(16) | default "normal" | **v2.2/C2**:门禁质量标记 `normal`(正常)/`pending`(待补录)/`rejected`(拒收);与 `status` 配合驱动状态机(§3.16/C3),不新建 issue 表 |
| validated_by | int FK→breeding_personnel | | **v1.6**:校验人(status=validated 时记录) |
| validated_date | date | | **v1.6**:校验日期 |
| unit | varchar(32) | | **v1.6**:本次观测值单位(冗余自 trait.unit,便于核对与单位换算);批量导入时按 trait.unit 校验/换算 |
| remark | varchar(512) | | |
**索引**`(trait_id, obs_year)``(tree_id)``(plot_id)``(combination_id)``(trial_study_id)`
**语义(v2.2/F1+F2 重定职责)**:本表**仅承载 plot/combination 级观测 + 物候时序观测**(如花期/果实发育期时序、小区级/组合级群体表型),**不再承载 tree 级果实鉴定性状**——后者一律走 §3.2b `breeding_trait_observation`(挂 evaluation)。两表职责按"**是否喂 EBV**"正交切分:`breeding_trait_observation` 喂 EBV(clone 级取数主路径),`breeding_observation` **不喂 EBV**。**plot 级果实均值不在本表落值**,由统计 VIEW 从 `breeding_trait_observation` 聚合派生(§8.4),杜绝双写与重复计数。原"核心性状走 `tree_evaluation` 固定列"表述作废(F1,见 §4/§8.4)。**v1.6B8**:本系统 tree/plot/block 对应 BrAPI `observationLevels`plant/plot/block),观测单元层级即观测的 FK 类型(tree_id/plot_id/combination_id)。
### 3.2b breeding_trait_observation(单株鉴定明细长表,P0,v2.2 正式登记)
> **命名说明(v2.2/F2)**:本表已在代码落地(模块/URL/权限名 `trait_observation`,模型 `TraitObservationModel`**物理表名 `breeding_trait_observation`** 与全项目 `breeding_*` 前缀一致),此前文档漏登记("代码有、文档无"缺口)。此处补记**既有表**,非新建。
> **职责(F1+F2**:承载**单株(tree 级)每次鉴定的性状明细**——童期性状 + 评价段果实性状,是 clone 级 EBV 的**取数主路径**。与 §3.2 `breeding_observation`plot/combination + 物候)按"是否喂 EBV"正交:本表**喂 EBV**。取代初稿 `tree_evaluation` 固定列(F1)。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int | PK | |
| evaluation_id | int | FK→breeding_tree_evaluation NOT NULL | 所属鉴定主记录(一次鉴定=一主记录+N 明细) |
| tree_id | int | FK→breeding_tree NOT NULL | 观测单元=单株(可经 evaluation 推导,冗余便于按株聚合/判重,F4) |
| trait_id | int | FK→breeding_trait NOT NULL | 测了哪个性状(`breeding_trait` 驱动长表) |
| value_numeric | numeric(12,4) | | data_type=numeric 时(统计 pivot 取此列) |
| value_text | varchar(512) | | categorical / boolean |
| value_date | date | | data_type=date 时 |
| category | varchar(32) | | 归属标签页(基本鉴定/果实外观/果皮/果实大小/果肉/果核/其它),驱动前端分组录入 |
| issue_status | varchar(16) | default "normal" | **v2.2/C2**:门禁标记 normal/pending/rejected(同 §3.2 |
| unit | varchar(32) | | 本次观测值单位(冗余自 trait.unit,导入校验用) |
| remark | varchar(512) | | |
| uuid / is_deleted / created_time / updated_time / deleted_time | — | 同框架契约 | **鉴定类表:禁物理删、UPDATE 强制 audit(§3.10/G2** |
**索引**`(evaluation_id)``(tree_id, trait_id)``(trait_id)`
**统一性状值视图**:统计管线由 DB **普通 VIEW**`trait_code` pivot 本表(+ 必要时 union `breeding_observation`)生成宽表供 BLUP,保证 fresh;看板/报表可另建 **物化视图 MV**(定时刷新),但 **MV 不得作为 BLUP 输入**(§8.4)。
### 3.3 breeding_field_operation(农事操作,P0
> 同样改显式 FK`tree_id` / `plot_id`),弃 `(unit_type, unit_id)` 多态,理由同 §3.2。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| op_type | varchar(32) | NOT NULL | 施肥/灌溉/植保/除草/修剪/病害防治/其他 |
| tree_id | int FK→breeding_tree | 可空 | 作用对象=单株 |
| plot_id | int FK→breeding_plot | 可空 | 作用对象=小区 |
| op_date | date | NOT NULL | 操作日期 |
| material | varchar(128) | | 药剂/肥料名 |
| dosage | varchar(64) | | 用量 |
| method | varchar(128) | | 方式(叶面/根施…) |
| operator_id | int FK→breeding_personnel | | 操作人 |
| site_id | int FK→breeding_site | | 定位 |
| remark | varchar(512) | | |
**索引**`(tree_id)``(plot_id)``(op_date)`
**BrAPI 映射修正**field_operation **不映射为 `/events`**BrAPI 无顶层 Event);改为映射到 `/observations`(带 `op_type`),或自定义只读端点(见 §8.2-C)。
### 3.4 breeding_trial + breeding_trial_study(多年多点试验,P1
**breeding_trial**
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| trial_code | varchar(64) UNIQUE | 试验编号 |
| trial_name | varchar(128) NOT NULL | |
| target_id | int FK→breeding_breeding_target | 关联育种目标 |
| design_type | varchar(32) | 取值见 §9rcbd/augmented/contrast/split_plot/unreplicated|
| description | varchar(512) | |
| years | varchar(64) | 跨年计划,如 2026-2028 |
| remark | varchar(512) | |
**breeding_trial_study**Trial×Location×Year
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| trial_id | int FK→breeding_trial | |
| site_id | int FK→breeding_site | 试验点 |
| year | int | 年份 |
| replicate_count | int | 重复次数(原 `replicate` |
| block_count | int | **区组数(v1.3 补)**;与 `tree.block_no` 对应,是 BLUP 的 block 随机效应来源 |
| design_type | varchar(32) | 取值见 §9.4(便于 study 级覆盖 trial 默认设计) |
| control_germplasm_id | int FK→breeding_germplasm | 对照品种 |
| layout_json | jsonb | 田间种植图(小区排布坐标) |
| season | varchar(32) | | **v1.6**:季节/播期分组(如 `2026_dry` 旱季),MIAPPE/BrAPI season 概念,关联 year 的细粒度环境聚合 |
| remark | varchar(512) | |
> **试验隶属链路(v1.3 彻底补全,原稿断裂)**:观测单元(tree)经两条显式 FK 挂到试验——
> - `breeding_planting.trial_study_id`(定植时把这批树挂到某 trial_study,运营钩子)
> - `breeding_tree.trial_study_id`(从 planting 同步,BLUP 直接消费)+ `breeding_tree.block_no`(该树所属区组/重复)
> - `breeding_plot.block_no`(小区级试验时;tree 未填 block_no 则继承 plot
>
> 这样任意 `tree_evaluation`/`observation` 记录 → tree → `trial_study`(environment=site×year) + `block_no` → 混合模型 `y = genotype + block + environment + G×E` 的 block 项不再缺失。布局图由前端可视化 + 轻量排布算法生成。
**breeding_trial_study_entry**(试验 entry 清单,v1.4 补,对标 BrAPI Study 的 entry / ObservationUnit
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| trial_study_id | int FK→breeding_trial_study | 所属试验 |
| germplasm_id | int FK→breeding_germplasm | 参试无性系/品系的**种质溯源**(保留,v2.2/D3 |
| clone_id | int FK→breeding_clone | **v2.2/D3**:参试落 **clone 级**(entry 直指遗传身份,与 BLUP/EBV 聚合层一致);germplasm_id 仅作种质溯源 |
| entry_number | int | **entry 编号**(该 study 内唯一;BrAPI `entryNumber`BLUP 设计矩阵聚合键) |
| planned_reps | int | 计划重复/区组数 |
| n_plants | int | 计划株数 |
| is_control | bool | 是否对照 entry |
| remark | varchar(512) | |
> **为何需要 entry 抽象(v1.4**v1.3 让 `tree` 直接带 `germplasm_id + trial_study_id + block_no`,假设一株=一个观测单元。但一个无性系在某 study 内常**重复多株/多区组**,且需"entry 编号"聚合设计效应。BrAPI 的 `ObservationUnit = germplasm × entryNumber × replicate × blockNumber × position`,本表即此 entry 层;`tree` 通过 `entry_id`(或冗余 `germplasm_id`)挂回,统计层按 `entry_number` 聚合后再估 genotype 效应。
>
> **⚠ 单写点纪律(v1.5 强化)**`tree.trial_study_id` / `tree.block_no` / `tree.entry_id` **均派生自 `planting`**(定植时 planting 一次性写入 `trial_study_id` / `block_no` / `entry_id`tree 创建时由 service 从所属 planting 复制并锁定;后续修改只能改 `planting` 并级联同步 tree)。严禁两处各自手填,否则 BLUP 输入静默错配。
> - **`tree.trial_study_id` 仅记「定植所属 study」**(来自 planting 的单次定植),多年生树跨年/跨点观测**不**改 tree 自身,而是落到 `observation.trial_study_id` + `obs_year`(观测级表达),统计按 observation 的 study 聚合,tree 只是观测单元。
> - **两类 tree 区分(v1.5**`planting.entry_id` 非空 ⇒ 这是**参试无性系**批次,定植时 `germplasm_id` 必须等于 `trial_study_entry.germplasm_id`(入试即定,禁待晋升);`planting.entry_id` 为空 ⇒ **杂种实生苗**批次,`germplasm_id` 待晋升流程写入(晋级纪律管)。单写点 + entry 有无即可区分两类 tree,无需新增类型字段。
> - 写树校验:`tree.trial_study_id = planting.trial_study_id`、`tree.entry_id = planting.entry_id`、`tree.germplasm_id` 与 entry 一致性按上述规则。
### 3.5 breeding_group + breeding_group_member(分组/标签,P1
**breeding_group**
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| group_name | varchar(128) NOT NULL | |
| group_type | varchar(32) | 取值见 §9project/family/category/temporary_set/custom|
| target_id | int FK | 关联育种目标(可选) |
| description | varchar(512) | |
**breeding_group_member**
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| group_id | int FK→breeding_group | |
| germplasm_id | int FK→breeding_germplasm | 或成员种质 |
| clone_id | int FK→breeding_clone | **v2.2/H3**:或成员克隆(入选群体/决选批以 clone 为成员,呼应 D 组 clone 居中);三者(germplasm/clone/tree)按分组用途择一 |
| tree_id | int FK→breeding_tree | 或成员单株 |
| note | varchar(256) | |
> group_type 取值已定(§9):project(育种项目) / family(家系·杂交组合群) / category(种质类别群) / temporary_set(临时选系集) / custom(自定义)。为避免与 `target`(育种目标) 语义重叠,不设 objective 维度。
> **family / category 冗余消减(v1.3**`group_type=family` 本质是"某 `cross_combination` 的后代集合",可由 `tree.combination_id` **动态推导**,不必存静态成员 → 建议 family 做成**虚拟分组(查询)**,不在 `group_member` 落成员;`group_type=category`(油桃/蟠桃/观赏桃)与 `germplasm.variety_type` 字典**重叠**,直接复用 `variety_type`,不在 group 里另起炉灶。故 `group_member` 主要服务于 project/temporary_set/custom 三类。
### 3.6 breeding_report(统计报表配置,P2
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| report_name | varchar(128) NOT NULL | 报表名 |
| report_type | varchar(32) | 育种进度/世代汇总/杂交组合统计/材料库存/MET分析 |
| query_json | jsonb | 报表查询参数(保存配置,便于复用) |
| created_by | varchar(64) | |
| output_format | varchar(16) | | **v1.7**:报告输出格式 `docx` / `pdf` / `view`(看板实时聚合);默认 `docx` |
> **v1.7 确认进一期(原 v1.4 标记延后)**:V2.11 方案书 3.3.1 要求「年度育种进展 Word/PDF 报告」。故一期提供**报告生成服务**(基于 `report_type` 模板 + `query_json` 渲染),支持 docx/pdf 导出,不再仅限于只读聚合端点;看板类走 `view` 实时聚合,归档类走 docx/pdf 落盘。
**配套**
- 报告生成服务:`POST /breeding/statistics/report/generate`(按配置渲染 docx/pdf,可由 cron 触发年度归档)
- 只读聚合端点:
- `GET /breeding/statistics/progress` 育种进度
- `GET /breeding/statistics/generation-summary` 世代汇总
- `GET /breeding/statistics/cross-stats` 杂交组合统计
- `GET /breeding/statistics/inventory` 材料库存
- `GET /breeding/statistics/met` 多年多点分析(钩子,V1.1 R 引擎)
### 3.7 分子基因型层(V2.0,地基先建)
**breeding_marker**(标记/位点)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| marker_name | varchar(64) UNIQUE | 如 SNP_Chr01_123456 |
| chromosome | varchar(16) | 染色体 |
| position | int | 物理位置 |
| marker_type | varchar(16) | SSR / SNP / InDel |
| panel | varchar(32) | **v1.4**:所属标记面板/芯片版本(如 `PeachSNP170K` / `GBSv1`),用于区分不同基因组集、GS 时需一致 |
| assembly_version | varchar(32) | | **v1.6**:参考基因组版本(如 `Peach_v2.0`/`Peach_v2.1`),GS 拼接须同版本坐标,不同版本不可混;对齐 BrAPI marker.referenceGenome |
| remark | varchar(512) | |
**breeding_genotyping_dataset**(基因分型数据集,v1.4 补,GS 训练/预测群体分组)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| dataset_name | varchar(128) NOT NULL | 如 "2026_Brix_GS_train" |
| platform | varchar(32) | GBS / PeachSNP170K / 测序 |
| panel | varchar(32) | 与 marker.panel 对应 |
| purpose | varchar(16) | train(训练群体)/ predict(预测群体)/ reference |
| run_date | date | 分型日期 |
| lab | varchar(128) | 检测单位 |
| remark | varchar(512) | |
> 关联:`genotype_sample.dataset_id` FK→genotyping_dataset(标记某样品属于哪个分型集)。GS 训练时按 dataset(purpose=train) 取 sample→call 矩阵,避免每次手工挑样品。
**breeding_genotype_sample**(基因型样品)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| dataset_id | int FK→breeding_genotyping_dataset | **v1.4**:所属分型数据集 |
| source_type | varchar(16) | germplasm / tree |
| source_id | int | 来源 id |
| sample_type | varchar(16) | DNA / leaf |
| sample_date | date | |
| method | varchar(64) | 测序/芯片(GBS / PeachSNP170K |
| lab | varchar(128) | 检测单位 |
| remark | varchar(512) | |
**breeding_genotype_call**(基因型调用)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| sample_id | int FK→breeding_genotype_sample | |
| marker_id | int FK→breeding_marker | |
| allele | varchar(32) | 基因型编码(AA/AT/TT 或 0/1/2);**v1.6**:遵循 VCF/GP 编码约定(Breedbase 走 VCF 导入),0/1/2 = 纯合ref/杂合/纯合alt |
| remark | varchar(256) | |
**索引**`(sample_id, marker_id)` 复合唯一。
### 3.8 breeding_propagation(克隆扩繁/苗圃,P1,已定纳入一期)
> 桃主繁殖方式为嫁接/芽接扩繁(非种子实生)。打通 **入选株(tree) → 克隆种质(germplasm) → 扩繁批次(propagation) → 新定植树(tree)** 闭环;现有 `seedling`/`seed_treatment` 仍管种子实生苗,二者互补。
**breeding_propagation**(扩繁批次)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| batch_code | varchar(64) UNIQUE | 扩繁批次号 |
| scion_source_type | varchar(16) | germplasm / tree(被扩繁的克隆来源) |
| scion_source_id | int | 来源 id(入选株或其对应种质) |
| produced_clone_id | int FK→breeding_clone | **v2.2/A2 澄清**:本次扩繁**所繁殖的原克隆**(嫁接扩繁沿用同一 clone,**不新建 clone**);产出的新 tree 直接 `tree.clone_id = produced_clone_id`。原"产出的克隆"措辞易误读为新建,特此澄清。取代原 `produced_germplasm_id`→germplasm |
| rootstock_id | int FK→breeding_rootstock | **v2.2/A3**:砧木字典(§3.17);不再 FK→germplasm。`germplasm.is_rootstock` 仅作"可作砧木"标记 |
| method | varchar(16) | 嫁接/芽接/扦插 |
| graft_date | date | 嫁接日期 |
| nursery_site_id | int FK→breeding_site | 苗圃地点 |
| operator_id | int FK→breeding_personnel | 操作人 |
| scion_count | int | 接穗/芽数 |
| grafted_count | int | 嫁接株数 |
| survival_count | int | 成活株数(后续登记) |
| destination | varchar(32) | 出圃/定植/入库 |
| remark | varchar(512) | |
> `survival_count` 与 `grafted_count` 可派生成活率;产出苗木经 `planting`(带 `rootstock_id`→breeding_rootstock)成为新 `tree`,新 tree 的 `clone_id` = `produced_clone_id`**沿用原 clone,不新建**A2),完成闭环(**v2.0clone 级晋升,取代原 germplasm 级**)。
### 3.9 breeding_environment_condition(环境因子,P1G×E 地基)
> 多年多点分析的核心是 G×E 互作。无 site×year 的环境协变量(需冷量/积温/降水),BLUP 只能粗估。本表提供每个试验点每年的环境背景。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| site_id | int FK→breeding_site | NOT NULL | 试验点 |
| year | int | NOT NULL | 年份 |
| chilling_hours | numeric(8,1) | | 需冷量(小时) |
| growing_degree_days | numeric(8,1) | | 积温(GDD |
| rainfall_mm | numeric(8,1) | | 降水量 |
| temp_avg | numeric(6,1) | | 年均温 |
| soil_moisture | numeric(6,1) | | 土壤墒情(可选) |
| source | varchar(32) | | 气象站/人工记录/遥感 |
| remark | varchar(512) | | |
**索引/唯一**`(site_id, year)` 唯一,确保每点每年一条。可复用 `yz.sql` 的"天气"字段做种子。
### 3.10 breeding_audit_log(审计日志,P1
> 晋级审批、全程可追溯需"谁/何时/改了什么"轨迹,现有仅 `updated_time` 粒度不足。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| entity_type | varchar(32) | 实体(tree/selection_result/cross_combination…) |
| entity_id | int | 实体 id |
| action | varchar(32) | create/update/delete/select/approve |
| field_name | varchar(64) | 变更字段(可空,批量时为 null) |
| old_value | varchar(512) | 旧值 |
| new_value | varchar(512) | 新值 |
| operator_id | int FK→breeding_personnel | 操作人 |
| created_time | 标准 | 时间戳 |
**索引**`(entity_type, entity_id)``(created_time)`。建议作为现有 14 域的**通用切面**(在 Service 写操作时统一落审计),而非逐表加列。
> **审计覆盖范围(v2.2/G2,落实操作手册"记录不可删只能改、改要留痕"铁律)**:
> - **鉴定类表**`breeding_tree_evaluation` / `breeding_trait_observation` / `breeding_observation`):**禁止物理删除**,且**禁用软删**`is_deleted` 不对外开放);淘汰/作废走**状态变更**`status`/`issue_status`)而非删除。
> - 上述表的**每次 UPDATE 必须写 `breeding_audit_log`**field_name/old_value/new_value 逐字段),由 Service 切面强制,不可绕过。
> - 其余业务表沿用框架软删;`selection_result`/`cross_combination`/`tree` 等关键决策表的 update/select/approve 一并纳入审计切面。
### 3.11 breeding_selection_rule(选择阈值规则,P1,决策地基)
> RosBREED 的 DNA-informed 选择靠**指数阈值**(如 Brix≥12 且单果重≥200g)自动 flagged。`selection_result` 只记晋级/淘汰,缺"标准"实体,决策支撑会退化为纯人工勾选。本表把"选择标准"显式建模。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| rule_name | varchar(128) | NOT NULL | 规则名(如"鲜食品系晋级线" |
| target_id | int FK→breeding_breeding_target | | 适用育种目标(可选) |
| stage | varchar(32) | | 适用选择阶段(§9.1,如 ap 复选) |
| conditions_json | jsonb | NOT NULL | 阈值条件数组,如 `[{"trait_code":"brix","op":">=","value":12},{"trait_code":"fruit_weight","op":">=","value":200}]` |
| logic | varchar(8) | default "and" | 多条件组合 and/or |
| action | varchar(16) | | flag(标记)/select(自动晋级)/eliminate(自动淘汰) |
| priority | int | | 规则优先级 |
| enabled | bool | default true | |
| remark | varchar(512) | | |
> 决策支撑(§5.4):前端按规则对 `tree_evaluation`/观测值求布尔,自动 flag/晋级;规则与 `trait` 字典通过 `trait_code` 关联,新增性状自动可被规则引用。
>
> **v2.3 已落地)方向感知**`conditions_json` 的 `op` 缺省按性状 `direction`desc→`>=`asc→`<=`);`rank_top_n` 按方向取**最优前 N**asc 取 EBV 最小前 Ndesc 取最大前 N);`into_ebv='0'` 性状不参与决策候选。**兼容性提醒**:既有规则对 asc 性状**显式写了** `>=` 的仍字面执行(可能选反),上线后人工复核。
### 3.12 breeding_prediction(育种值:值表 V1.1 持久化 / GS 模型训练 V2.0
> **v1.7 时序拆分(关键)**v1.6 曾把整张 `breeding_prediction` 标 V2.0,与分子层同期。但 V1.1 统计引擎(R `sommer`/`lme4` 做 ABLUP/EBLUP)会产出育种值(EBV),而「年遗传趋势图(专册 2.6.3)」「EBV 双轨选择(§5 B10)」「亲本/单株决策(专册 3.1/3.2)」都依赖 **EBV 持久化读取**——若不建值表,V1.1 一接入即断链。**v1.7 拆分**:
> - **值存储表 `breeding_prediction_value` 前移 V1.1**:与 V1.1 引擎同期建表并写入,持久化 EBV/预测值,供趋势图与决策读(**硬缺口①闭环**)。
> - **GS 模型训练(基因型→育种值)留 V2.0**:依赖分子层(§3.7 `genotype_call`);其产出的 GBLUP/EBV 同样写入同一 `breeding_prediction_value` 表。
**主表** `breeding_prediction`(模型/批次元数据):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| model_name | varchar(128) | 模型名(如"2026_Brix_ABLUP" / "2027_Brix_GS" |
| trait_id | int FK→breeding_trait | 预测的性状 |
| method | varchar(32) | ABLUP(系谱) / gBLUP / rrBLUP / GBLUP / BayesV1.1 先填 ABLUPGS 类 V2.0 |
| accuracy | numeric(5,3) | 模型精度(交叉验证) |
| heritability | numeric(5,3) | **v2.2/B1+B2**:本次 BLUP × 该性状的**加性(狭义)遗传力 h²**(一次预测=一个 h²,故落**主表**而非明细)。落库口径取**克隆均值遗传力** h² = V_clone /V_clone + V_e/k̄),k̄=各 clone 平均重复株数;PA 上限 PA≤√h² 用此值。**注**:术语正名——ABLUP 产出的是加性/狭义 h²,非"广义遗传力"(后者含显性/上位,clonal 数据虽可估广义,但本系统选择决策用加性 h²) |
| train_n | int | 训练样本数 |
| predict_date | date | 预测日期 |
| note | varchar(512) | |
**明细** `breeding_prediction_value`(个体预测值,**V1.1 建表**):`prediction_id` / **`clone_id`(FK→breeding_clone,个体锚点,v2.1/R1 与 EBV 聚合层一致)** / `tree_id`(可选重复测量)/ `predicted_value` / `reliability` / `rank`EBV 排名)。**v2.2/B1** `heritability` 已上移主表 `breeding_prediction`(一次 BLUP × 一性状 = 一个 h²,不应在每条明细重复),明细仅存个体级 clone/value/reliability/rank。V1.1 引擎每次跑 BLUP 在主表落 h²、明细落各 clone 的 EBV,同批次持久化。
> **v2.3 已落地)rank 语义 + h² 兜底**`breeding_prediction_value.rank` 是**写时快照**——读时(EBV 排行/轮次对比)按性状当前 `direction` 重新推导优度序(`ebv_ranking` 读时重排、`compare_predictions` 方向感知),性状事后改方向**不需重跑批次**。主表 `heritability` 实测缺失时,指数/排行可用 `breeding_trait.default_h2` 先验兜底(两者皆无才拒绝)。
### 3.13 breeding_seed_lot(种子批·库存,P1,与 MET 一并建模)
> v1.1/§8.3 曾把库存"延后"。v1.3 复审:MET 与**选择强度**都依赖 "种子→播种→定植→入选" 链,故把 `seed_lot` 作为**批记录**提前进一期(仍非完整事务性出入库台账,后者延后)。与 §3.4 的 trial_study 链路共同拼出完整育种流程。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| combination_id | int FK→breeding_cross_combination | NOT NULL | 所属杂交组合 |
| lot_code | varchar(64) | UNIQUE, NOT NULL | 种子批号 |
| harvest_year | int | | 收获年份 |
| seed_count | int | | 收获粒数(选择强度源头) |
| used_count | int | default 0 | **v1.5/v1.6**:已从该批**取用的粒数**(在 seedling/播种环节按粒累加,非定植株数),由 planting/seedling 写操作维护;`remaining = seed_count - used_count` 派生「剩余可播种量」,选强链前段(获种→已用)可量化,不再依赖手工孤值 |
| germination_rate | numeric(5,2) | | 发芽率 %(活力) |
| storage_type | varchar(16) | | 种子库/离体/DNA |
| storage_location | varchar(128) | | 存放位置 |
| test_date | date | | 活力检测日期 |
| remark | varchar(512) | | |
**链接(选择强度链)**
- `breeding_seedling.seed_lot_id` FK→seed_lot(追溯幼苗来源批)
- `breeding_planting.seed_lot_id` FK→seed_lot(可选;种子来源定植)
- **`used_count` 维护(v1.5/v1.6**:每次从某 `seed_lot` 取种(建 seedling / planting 引用该 lot)时由 service 按**粒**累加 `used_count``remaining = seed_count - used_count` 实时可查,避免手工维护 `seed_count` 与实际消耗脱节(注意粒度:粒≠株,used_count 记粒数)。
> **选择强度贯通(v1.5/v1.6**`seed_lot.seed_count`(获种数)→ `seed_lot.used_count`(已用/播种粒数,派生 remaining)→ `COUNT(seedling WHERE seed_lot_id)`(成苗)→ `COUNT(tree WHERE planting.seed_lot_id)`(定植数)→ `COUNT(selection_result 入选)`(入选数)→ 各级**选择强度/选择率**可算,且 "每组合在某试验点种了多少" 与 MET 的 `trial_study` 直接挂钩。前段「获种→已用」因 `used_count` 派生而不再失真。
---
### 3.14 breeding_treatment(试验因子/处理,P1v1.5 提进一期)
> **背景**:§9.4 `design_type` 含 `split_plot`(砧木×接穗两因子)。若只记 design_type 而不结构化 factor/level,BLUP 无法估因子主效应与互作,设计等于白支持。BrAPI 有 `Treatment`(factor + level) 实体;MIAPPE 要求 `ExperimentalFactor`。本表把"试验处理"显式建模,使裂区/析因设计的统计效应可估。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| trial_study_id | int FK→breeding_trial_study | NOT NULL | 所属试验 |
| factor | varchar(32) | NOT NULL | 因子名(如 `rootstock` 砧木 / `scion` 接穗 / `fertilizer` 肥料) |
| level | varchar(32) | NOT NULL | 因子水平(如 `GF677` / `Maotao` / `N0` |
| description | varchar(256) | | 处理说明 |
| remark | varchar(512) | | |
**索引/唯一**`(trial_study_id, factor, level)` 唯一。统计层按 `treatment.factor×level` 估主效应与互作,与 `block` / `environment` 一并进入混合模型 `y = genotype + block + treatment + genotype×env(+空间)`
### 3.15 breeding_planting_treatment(定植-处理关联,P1v1.6 落地 A3)
> **背景(A3v1.6**:§3.14 的 `treatment` 需落到具体定植批次才能进统计。一个 block 级 `planting` 批次常同时接受一组处理(如 rootstock=GF677 + scion=Maotao),故建多对多关联表。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int PK | | |
| planting_id | int FK→breeding_planting | NOT NULL | 定植批次(block 级) |
| treatment_id | int FK→breeding_treatment | NOT NULL | 接受的处理(factor×level |
| remark | varchar(512) | | |
**索引/唯一**`(planting_id, treatment_id)` 唯一。统计层按 `planting→treatment` 把 factor×level 挂到该批次全部 tree,与 `block`/`environment` 一并进入混合模型。
---
### 3.16 数据质量门禁(quality gateP0,作用在 breeding_trait_observation / breeding_observation 入库前)
> **v2.2/C1** 门禁作用于长表 `breeding_trait_observation`(单株鉴定明细)与 `breeding_observation`plot/物候),**不再作用于已废弃的 `tree_evaluation` 固定列**F1);单位/阈值一律从 `breeding_trait` 对齐(valid_min/valid_max/unit)。
| 门禁项 | 规则 | 处置 |
|---|---|---|
| 缺失值标记 | 关键**单元键**缺失(**入选前实生苗=`tree_id`**;入选后=`clone_id`,F3)+ 年份 + 性状值 | 标记 `issue_status=pending`(待补录),**不进分析池** |
| 异常值 | 数值性状按 `trait.valid_min/valid_max` 越界 | 标记 `issue_status=pending`,人工复核(H1:全局阈值 + 人工) |
| 单位混用 | 值单位 ≠ `trait.unit` | **整行拒收** `issue_status=rejected`(§3.1 unit 强校验) |
| 重复记录 | 按 **`(tree_id, 年份, 性状, obs_date)`** 判重(**含 tree_idF4**) | 去重(保留最新 / 人工选择) |
> **(v2.2/F4)判重与重复测量的命门区分**:同一 clone 经扩繁的**多株 tree** 在同点同年的观测是**合法重复测量(clonal replicates**,正是 reliability 的来源,**绝不可当"重复记录"删**。故判重键必须**含 `tree_id`/株号**——只有"同一株、同年、同性状、同日期"多条才是真重复;clone 级多株是"重复测量"而非"重复记录"。原 v2.1 按 `(clone_id,地点,年份,性状)` 判重(会把 clonal replicates 删到只剩一条 → reliability 崩、自由度虚低)**作废**。
> **(v2.2/F3)实生苗阶段单元键退化**:入选晋升前实生苗无 clone_id,门禁单元键退化为 `tree_id`(童期观测按株入库),入选建 clone 后切换 clone_id;否则童期采集会被全部判"缺失键"打回。
> **(v2.2/C3)门禁 × 状态机衔接**:门禁拒收 → `issue_status=rejected` 且记录停留 `status=draft`;门禁标记异常/缺失 → `issue_status=pending`,须人工修正后方可置 `status=validated`**仅 `issue_status=normal` 且 `status=validated` 的记录进 BLUP 分析池**。
### 3.17 breeding_rootstock(砧木字典,P0 数据治理地基)
> 阶段0 建砧木字典(砧木名称/类型/来源),**只挂 observation 层**tree/planting 的 `rootstock_id`),与 `germplasm.is_rootstock`(亲本种质属性)**区分用途**`germplasm.is_rootstock` 标记"该种质可作砧木"`breeding_rootstock` 才是观测层实际使用的砧木清单。砧木**绝不进 A 矩阵**(建模铁律,§5.x)。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int | PK | 自增主键 |
| code | varchar(32) | UNIQUE NOT NULL | 砧木编码 |
| name | varchar(64) | NOT NULL | 砧木名称(如毛桃/山桃/GF677…) |
| type | varchar(32) | | 砧木类型(乔化/矮化/本砧…) |
| source | varchar(128) | | 来源(自繁/引进) |
| remark | varchar(512) | | |
### 3.18 breeding_pedigree(独立系谱表,P0 数据治理地基,v2.1)
> **v2.1 修订(R2**:系谱从"clone 内联 female/male_parent_id + germplasm.pedigree 自由文本"升级为**独立系谱表**。原因:① clone 父本指向 germplasm,而 germplasm 父级是自由文本 → A 矩阵递归到父本级断裂;② 自选系作亲本时递归立刻崩。独立表让 `dam`/`sire` 也指向本表,递归闭环。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | int | PK | 自增主键 |
| individual_type | varchar(16) | NOT NULL | `clone` / `germplasm`(个体类型,两类共用本表) |
| individual_id | int | NOT NULL | 指向 breeding_clone.id 或 breeding_germplasm.id(由 individual_type 决定) |
| dam_id | int | FK→breeding_pedigree.id | 母本(指向本表,递归闭环;引进种可为 NULL) |
| sire_id | int | FK→breeding_pedigree.id | 父本(指向本表;引进种可为 NULL) |
| rel_type | varchar(16) | | 关系类型(biological / 可选) |
| combination_id | int | FK→breeding_cross_combination 可空 | 来源杂交组合(clone 型时有意义) |
| remark | varchar(512) | | |
> `breeding_clone.female_parent_id/male_parent_id` 降为**冗余直查列**(§3.0),权威系谱以本表为准;`germplasm.pedigree`(自由文本)**移除**,改由本表承载(§4 germplasm 行同步修订)。
> **v2.2/A4)A 矩阵系谱唯一权威**:构造遗传关系 A 矩阵的系谱**以本表 `breeding_pedigree`dam_id/sire_id 递归闭环)为唯一权威**`cross_combination` 的父/母本仅作 clone 系谱行的**自动派生源**(新建 clone 时据组合父母本自动生成本表一行),**不作为 A 矩阵的独立系谱来源**,避免"combination 父母本"与"pedigree dam/sire"双源不一致。§5.8 同步修订。
## 4. 现有模块字段调整(非新增模块)
| 模块 | 新增字段 | 说明 |
|---|---|---|
| germplasm | accession_no(varchar UNIQUE)、stage(varchar 选择阶段)、generation(varchar 遗传世代,可空)、storage_type(varchar 田间/离体/种子/DNA)、is_rootstock(bool)、rootstock_id(int FK 自关联)、**护照块(v1.4,FAO-MCPD): institute_code(varchar 保存单位)、country_origin(varchar 起源国)、collection_site(varchar 采集地)、acquisition_date(date 引种日期)、biological_status(varchar 生物状态:wild/landrace/breeding_line)、breeding_program(varchar 所属育种计划,v1.6 暂自由文本,后续可升级 FK breeding_program 顶层)** | 种质档案补全 + 桃特有维度 + **国际种质资源护照(Genesys/FAO 对齐)**;**系谱不再内联**(v2.1:移除 `pedigree` 自由文本,改由 §3.18 `breeding_pedigree` 独立表承载,避免 A 矩阵递归断裂) |
| cross_combination | cross_type(varchar 杂交/自交/开放)、parent_combination_id(int 自链 FK)、reason(varchar 选配理由)、stage | 系谱链 + 选配理由 |
| pollination | bagging_date(date 套袋)、emasculation_date(date 去雄)、**female_tree_id(int FK→breeding_tree,可空)、male_tree_id(int FK→breeding_tree,可空)(v1.4,杂交圃父/母本树指定)** | 田间杂交登记补全 + **控制杂交父/母本树追溯(crossing block** |
| seedling | seed_lot_id(int FK→breeding_seed_lot) | 追溯幼苗来源批(选择强度链,§3.13) |
| planting | rootstock_id(int FK→breeding_rootstockv2.2/A3)、**entry_id(int FK→breeding_trial_study_entry,可空,v1.5 单写点补 entry)**、**trial_study_id(int FK→breeding_trial_study,可空,单写点)**、**block_no(int,该批树所属区组,单写点)**、**seed_lot_id(int FK→breeding_seed_lot,可空)**、**propagation_id(int FK→breeding_propagation,可空,v1.6 来源双路径)** | **粒度=block 级批次(v1.6 明确:同一 entry 跨多 block 须建多个 planting**;砧木–接穗建模 + **试验隶属(MET 链路唯一写入口;entry_id 非空=参试无性系批次,germplasm_id 入试即定;为空=杂种实生苗批次,germplasm_id 待晋升)** + 库存链接(seed_lot.used_count 派生剩余)+ 来源双路径(种子批/扩繁批二选一) |
| tree | **clone_id(int FK→breeding_clone**可空**;杂种实生苗定植可空、入选晋升时建 clone 回填,参试无性系定植必填,v2.2/A1 取代原"定植必填/1树=1clone";扩繁后 1 clone↔N tree,§3.0 聚合锚点)**、stage(varchar 选择阶段)、generation(varchar 遗传世代,冗余自 combination)、rootstock_id(int FK→breeding_rootstockv2.2/A3)、**germplasm_id(int FK→breeding_germplasm,晋升时回填、定植时留空,禁手填;v2.0:定植即定 clonegermplasm 仅当 clone 晋升为种质时写入)**、**entry_id(int FK→breeding_trial_study_entry,可空,v1.5 派生自 planting,区分两类 tree)**、**trial_study_id(int FK→breeding_trial_study,可空,v1.5 仅记「定植所属 study」,派生自 planting;跨年/跨点观测走 observation.trial_study_id+obs_year)**、**block_no(int,派生自 plantingBLUP block 效应来源)** | **clone 聚合锚点(R1 修正:tree 必带 clone_idEBV 经 tree.clone_id 聚合到 breeding_clone,否则链路断)** + 阶段/世代标记 + 克隆晋升链路(4.x 全流程 + GS 拼接依赖)+ **MET 观测单元归属(派生,单写点=planting;两类 tree 以 entry_id 有无区分)** |
| site | soil_type(varchar 土壤类型)、**latitude(numeric 坐标)、longitude(numeric)、elevation(int 海拔)(v1.4,空间 BLUP/MIAPPE 环境描述)** | 试验地块补全 + **地理定位** |
| selection_result | **clone_id(int FK→breeding_clonev2.2/D1,决选落 clone 级)**、对齐 stage 晋级流转(建议加 from_stage/to_stage + approved_by)、**rule_id(int FK→breeding_selection_rule,可空,v1.4,记录触发晋级的规则,决策闭环)**、tree_id(保留作溯源) | 晋级审批流 + **选择决策溯源(决选粒度=clone,tree_id 溯源到具体单株)** |
| tree_evaluation | **(v2.2/F1:已删果实性状固定列,改为"一次鉴定主记录",性状明细全落 §3.2b `breeding_trait_observation`** trial_study_id(int FK→breeding_trial_study,可空,环境键)、evaluate_date(调查时间)、breeding_personnel_id(评价人)、overall_score(总评)、**crop_load(varchar 坐果量评级 1/2/3,可空,作果实性状协变量降环境误差——**作鉴定主记录字段,每次鉴定一值**)** | 鉴定主记录 + 环境键 + **负载量协变量(专册 1.3:坐果量评级吸收单株负载造成的生理/环境误差,提升 EBV 与选择指数精度)** |
**tree_evaluation 定位(v2.2/F1 裁定:单一长表,废弃固定列)**`tree_evaluation` **已删除所有果实性状固定列**,降为**一次鉴定的主记录**tree_id + evaluate_date + 评价人 + overall_score + crop_load 等每次鉴定级字段),性状明细**全部迁往 §3.2b `breeding_trait_observation` 长表**`breeding_trait` 字典驱动)。原 v1.3「按 `pa_four` 扩 ~30–40 固定列」口径**作废**——已落地代码(2026-07-29)删固定列、统计 service 改从 `breeding_trait_observation` pivot 取数。**报表/SQL 聚合的补偿**:由 DB 视图(统计用普通 VIEW / 看板用 MV)按 `trait_code` pivot 顶上(§8.4),不回退固定列。*原则回归:§0「性状与观测分离」恢复为「字典定义 + 值全部长表」,不再是「固定列 + EAV 双轨」。*
> **v1.6 补(A1/ v2.2 修订**`tree_evaluation`(鉴定主记录)加 `trial_study_id`(可空,按该年 `observation.trial_study_id` 推导或直填),使该次鉴定的所有性状明细(经 evaluation_id 关联的 `breeding_trait_observation`)都继承环境键,纳入 MET 环境效应估计(原"固定列层漏环境键"的裂痕在长表下由主记录统一承载)。
**统一性状值视图(v1.3 补 / v2.2 F1 重定义,统计层关键)**:性状值一律经 `trait_id``trait` 字典关联(长表天然带键,无固定列漂移问题)。在统计/GS 层定义**统一性状值视图 `v_trait_value`**DB **普通 VIEW**),把 `breeding_trait_observation`(单株鉴定明细,喂 EBV)+ 必要时 union `breeding_observation`plot/物候)按 `(unit_key, trait_code, obs_year)` pivot 归一为宽/长表,供 V1.1 BLUP 与 V3.0 决策消费——**普通 VIEW 保证 fresh,不会有过期数据污染 EBV**。看板/报表另建**物化视图 MV**(定时刷新换性能),**MV 不得作为 BLUP 输入**。种子初始化只需把 `pa_four` 写入 `trait` 字典(`is_core=true`),不再向任何固定列写值;新增核心性状只加字典行,不改表结构。
> **v1.6 补(A6/ v2.0 修订**:视图/引擎须把 `tree_evaluation`/`observation` 的观测按 `tree.clone_id`**v2.0:由 `tree.germplasm_id` 改为 `tree.clone_id`→`breeding_clone`**,详见 §3.0)聚合为 clone 的**重复测量**(同一 clone 经扩繁多株 tree 是重复而非独立个体),EBV 随机效应估在 `breeding_clone` 级(`clone_id`),tree 作重复;否则 V1.1 会误把每株当独立个体高估自由度。
---
## 5. 统计分析与决策地基(关键要求)
用户明确要求"统计分析与决策,需要基础能够支持"。数据模型须满足:
1. **任意性状可聚合**:统一性状值视图(§4 末尾,v2.2/F1 由 `breeding_trait_observation` + `breeding_observation` 长表 pivot)使「按性状×年份×地点×阶段」切片聚合无需改表——这是 ABLUP/EBV 与选择指数的输入。
2. **MET 结构就绪(v1.3v1.5 补全)**`tree.trial_study_id`**v1.5 仅记「定植所属 study」**,派生自 planting+ `tree.block_no`(区组随机效应)+ `trial_study.block_count` + **`trial_study_entry`entry_number 设计矩阵聚合键)** + **`treatment`factor×levelv1.5 提进一期,支撑 split_plot 等因子效应)** 提供完整试验设计维度;跨年/跨点观测经 `observation.trial_study_id + obs_year` 表达(树自身不跨 study)。`site` 经纬度/海拔支持 **空间 BLUPsommer 空间项)**。V1.1 混合模型 `y = rootstock + site + year + block + treatment + environment + genotype(clone) + clone×year(随机互作) + G×E(+空间)` 各效应项齐备(**v2.2/F5`rootstock` 作固定效应显式入模,与 §5.x 铁律一致,否则 EBV 被砧木注水**;**v2.1/R9:桃多年生、同 clone 跨年观测是重复测量,须含 `clone×year` 随机互作,否则单年运气被当遗传进展**),可输出 clone 级 EBV。
> **sommer 基线公式(v2.2/B3,供 R 脚本落地)**`mmer(y ~ rootstock + site + year + block, random = ~ vsr(clone, Gu=Amat) + vsr(clone:year), rcov = ~ units, data=...)`,其中 `clone` 走 A 矩阵(`Amat` 由 §3.18 `breeding_pedigree` 构造),`rootstock/site/year/block` 为固定效应扣除系统偏差。lme4 退化版:`lmer(y ~ rootstock + site + year + block + (1|clone) + (1|clone:year))`(无 A 矩阵时)。
>
> > **v2.3 已落地)G×E 交互引擎**`run_ablup` 已支持 `gxe=True` + `gxe_env=site/year``method=GXEBLUP`);site→自动固定效应 `trial_study`、year→自动固定效应 `year`;σ²gxe/gxe_ratio/n_cross_env 落 `breeding_prediction.note` JSON**不可辨识门禁**(无跨环境重复 / 单元内无重复)→409「G×E 不可辨识」;同 clone 多株**坍缩为基因型节点 `c{clone}`**(EBV 一致,重复测量聚合);异步 `StatisticsJobModel` job_type=GXE/ABLUP + SUCCESS/FAILED。落地台账见 §8.11 与 `桃育种系统统计引擎实施记录.md`。
3. **选择指数可计算**:统一性状值视图(表型) + `genotype_call`(基因型) → 多维选择指数(RosBREED DNA-informed 思路),按 `stage` 分层筛选;`selection_rule`(§3.11)把阈值显式化,支持自动 flag/晋级。
4. **选择强度可算(v1.3 补)**`seed_lot.seed_count`→成苗→定植→入选 四级计数贯通(§3.13),育种效率/选择压力可量化,且与 MET 的"每组合在某点种了多少"挂钩。
5. **决策支撑**`selection_result`(晋级/淘汰) + `stage` 流转 + EBV 排名 + `selection_rule` 自动标记 → 前端决策视图(哪些株晋级/淘汰、依据 EBV 与哪条规则)。
6. **溯源闭环**`tree→combination→父/母本 germplasm` + `observation/field_operation/pollination` 全 FK → 任意品系反向追溯(需求 7.1)。
7. **重复测量聚合(v1.6A6 / v2.0 修订)**:同一 clone 经扩繁产生多株 tree,其表型是同一基因型的重复观测;统计前按 `tree.clone_id``breeding_clone` 聚合为 clone 重复(**v2.0:取代原 `tree.germplasm_id`→germplasm 级聚合**),EBV 随机效应估在 `breeding_clone` 级(`clone_id`),避免自由度虚高。
8. **系谱 A 矩阵(v1.6B9 / v2.0 明确 / v2.2 A4 修订)**:除基因组 G 矩阵(来自 `genotype_call`)外,BLUP 可并入系谱 A 矩阵;A 矩阵系谱**以 §3.18 `breeding_pedigree`dam_id/sire_id 递归闭环)为唯一权威**v2.2/A4),供 `sommer` 递归构造;`cross_combination` 的父/母本仅作 clone 系谱行的**自动派生源**(建 clone 时据组合父母本自动生成 pedigree 行),不作独立系谱来源,避免双源不一致。`breeding_clone.female/male_parent_id` 仅为冗余直查列。**砧木(`breeding_rootstock`)绝不进 A 矩阵**(建模铁律,§5.x)——砧木改表型不改遗传身份。
9. **EBV 驱动选择(v1.6B10 / v2.2 B4 修订)**`selection_rule`(§3.11)的 `conditions_json` 除引用 `trait_code`(表型阈值)外,应允许引用 `prediction_value`(EBV 排名阈值),实现 RosBREED「表型 + EBV」双轨选择。**v2.2/B4)双轨统一在 clone 级判定**:表型侧先按 `tree.clone_id` 聚合到 clone 均值,再与 clone 级 EBV 按同一规则比较,避免"表型按株、EBV 按 clone"粒度错配。
10. **负载量协变量(v1.7,硬缺口②)**`tree_evaluation.crop_load`(坐果量评级 1/2/3)作为果实性状混合模型协变量,吸收单株负载造成的环境/生理误差(专册 1.3),提升 EBV/选择指数精度;V1.1 引擎须支持该协变量项。
11. **超期预警/通知(v1.7,软缺口⑤,工程项)**:专册 3.3.2「树 N 年未决策预警」由定时任务(cron)扫描 `selection_result`/`tree.stage` 实现,结合 `selection_rule` 触发通知;不阻塞一期数据模型,属前端/调度工程项。
### 5.x 砧木建模铁律(遗传评估不可动摇规则,v2.0 2026-07-30 锁定)
> 适用于所有落地:数据字典、R 脚本(sommer/lme4fixed 公式、observation 层字段、质量门禁。
1. **记录层**:砧木只记在 observation 层(`tree`/`planting``rootstock_id``breeding_rootstock` 字典,§3.17);`breeding_clone` 系谱层**无砧木**。
2. **A 矩阵(遗传随机关系)**:**绝不进**——砧木改表型不改遗传身份,进 A 矩阵会污染 clone 的 EBV。
3. **BLUP 固定效应**:砧木**必须进**,与 `地点 / 年份 / 定植批次` 并列扣除系统偏差;否则残差被污染、clone 的 EBV 被砧木注水。
> 关键澄清:"不进 A 矩阵" ≠ "不进模型"——砧木不进随机遗传关系,但**必须进固定效应**。这一字之差直接决定 EBV 是否被砧木注水,是建模正确性的命门。
### 5.y 间接早选(indirect early selectionv2.0
| 分期 | 内容 | 阶段 |
|---|---|---|
| 童期采集 | `trait.stage=juvenile` 性状采集(tree 视角,2–3 年) | **一期必做** |
| r_G 早选模型 | 基于遗传相关 r_G 的早选(童期性状预测评价段性状) | 排**二期** |
| 一期过渡 | 用历史"晋级/淘汰"标签训练**监督分类器(过渡)** | 一期 |
### 5.z 模型健康监控(v2.1R4
> "模型还准不准"的命门。每次 BLUP 重跑后扫描并与上一轮对比:
> - **h² 连年突降**:某性状 h² 较上一轮跌幅超阈值 → 告警(疑似数据质量/环境突变)。
> - **clone EBV 排名大幅翻转**:排名 delta / 排序相关性骤降 → 告警(疑似录入错误或模型设定漂移)。
> - 输出进现有告警/定时任务通道(§5 第11点),与"树 N 年未决策"并列。
>
> **(v2.3 已落地)方向感知**:轮次对比 `compare_predictions` 已按性状当前 `direction` 排序(asc 时 rank 1 = 最低 EBV 优);h²/相关/翻转位移量对反转不变量不变,仅展示 rank 列不再把最差株显示为第 1。
---
## 6. 实施路线(建议)
| 阶段 | 内容 |
|---|---|
| **第0阶段 数据治理(占40%、前置,v2.0/v2.1/v2.2** | 盘点5年历史数据 + **breeding_clone 系谱表(§3.0** + **breeding_pedigree 独立系谱表(§3.18,A 矩阵唯一权威)** + **breeding_rootstock 砧木字典(§3.17** + **trait_observation 单株鉴定明细长表(§3.2b,v2.2 补登记既有表)** + `trait``stage`(§3.1+ 字段规范 + **数据质量门禁(§3.16**garbage in garbage out,决定后续 EBV 可信度 |
| 地基(先做) | trait(含 ontology_uri) + observation(含 status) + **trait_observation 单株鉴定明细长表(§3.2b,v2.2 补登记既有表)** + 现有模块 stage/rootstock/accession_no/pedigree 字段;数据权限/options 沿用现有生成器 |
| P0 | field_operation |
| P1 | trial(+study+**study_entry**,§3.4)、**treatment(试验因子/处理,§3.14,v1.5 提进一期)**、**planting_treatment(§3.15,v1.6)**、group(+member,§3.5)、propagation(克隆扩繁,§3.8)、seed_lot(种子批,§3.13,**v1.5/v1.6 used_count 派生剩余**)、environment_condition(环境因子,§3.9)、audit_log(审计,§3.10)、selection_rule(选择阈值,§3.11,**v1.6 支持 EBV 阈值**)、**site 坐标 + germplasm 护照块 + pollination 父/母本树 + selection_result.rule_id(v1.4)+trial_study_id(v1.6) + planting.entry_id(v1.5)+propagation_id(v1.6)+block级粒度 + tree 两类区分 + tree_evaluation.trial_study_id(v1.6) + tree_evaluation.crop_load(v1.7) + tree_photo.observation_id(v1.6)(§4 字段调整)** + trial_study.season(v1.6) + marker.assembly_version(v1.6) + trait.method_uri/scale_uri(v1.6) + observation.validated_by/date/unit(v1.6) + kinship A矩阵(v1.6) |
| P2 | statistics 聚合端点(含 selection_rule 驱动的自动 flag/晋级预览) |
| **延后(v1.4 标记,v1.7 调整)** | **experiment_factorMIAPPE 受控试验因子,先用 field_operation 近似)、breeding_program 顶层(BrAPI Programtarget 暂代)** |
| **批量表型导入(v1.3 补,规划)** | `observation` 是 EAV(性状×单元×值),主数据入口是**成千上万条观测的批量进表**(设备/ sheet 导出),与现有"一行一实体"行式导入机制不同,需单列导入通道(含 trait_code 校验、单位换算、单元解析 tree_id/plot_id |
| 字典类型扩展 | breeding_dict.sql 增 breeding_stage/breeding_generation/breeding_group_type/breeding_design_type 四类(英码+中文),接入下拉与 Excel 导入翻译(DictLabelResolver) |
| V2.0 | marker + genotype_sample + genotype_call(地基先建表,分析后置)+ **GS 模型训练**(§3.12,值表已 V1.1 前移) |
| V1.1 | R 统计引擎接入统一性状值视图 + trial 做 BLUP/EBV |
| V3.0 | AI 决策(Agno + DeepSeek)消费 EBV/选择指数 |
| BrAPI 适配层 | 只读 `/brapi/v2/*` 端点(germplasm/crosses/trials/studies/observations/observationvariables/lists/samples/markers/calls/programs**field_operation 映射为 `/observations`(带 op_type) 而非 `/events`**),对接 Breedbase/Flapjack/国际交换(§0 原则 7 |
**工程约定(生成器机制待拍板)**:新模块用**系统内置代码生成器**`module_generator/gencode`DB-first,产物落 `app/plugin/`,自动建菜单)还是**续用自定义 `_gen_*.py`**(落 `app/api/v1/module_breeding/`,与现有 14 域一致)仍待用户定 A/B/C(见记忆「建表/生成器坑」)。无论哪条,改字段后跑 `deploy.bat migrate``fix_breeding_columns.py`)再重启后端。
---
## 7. 待确认项(收口)
v1.7–v1.8 已闭环统计/决策地基与团队隔离;**v1.9 已收口"枚举归属 A/B"(性状量表选项→`scale_json`、不进 `sys_dict`,详见 §3.1 / §0 原则1)**。剩余**唯一未拍板项 = 生成器机制 A/B/C**(注意:此 A/B/C 与"枚举归属 A/B"是两回事,勿混):
1. **生成器机制 A/B/C(唯一未拍板)**:新模块落 `app/plugin/`(内置 gencode 式)/ 续用自定义 `_gen_*.py`(与老 14 一致)/ 全迁 plugin 式。其余规格(含 v1.7 全部字段、v1.9 枚举归属)均已锁定,实施时据此生成即可。
> 文档进入"v1.9 枚举归属定稿版"。除生成器 A/B/C 外,待用户明确"做/搞吧"后实施,不先行编码。
---
## 8. 复审补充:遗漏与替代思路(2026-07-28 复审)
> 本节为第一稿(§0–§7)的批判性复审结论,针对"还有哪些遗漏 / 不同思路"自省。改变范围的项标注「待拍板」。
### 8.1 原稿遗漏的关键项
1. **`generation`(遗传世代)与 `selection_stage`(选择阶段)混为一谈**:桃虽以无性选择为主,但回交转育(BC1/BC2)、自交分离(F2)仍是真实遗传世代,与"选到第几轮"是两回事。建议拆字段:`generation`F1/BC1/BC2…,跟 `cross_type` 联动)+ `selection_stage`(实生苗/初选株/复选株/品系/区试/新品种)。
2. **缺"树→种质"晋升链路(克隆生命周期)**:入选株应晋升为 clone/accessiongermplasm)被命名扩繁。需 `tree.germplasm_id`,否则基因型(测在 germplasm)与表型(测在 tree)无法在 GS 中拼接。
3. **原清单 1.4「按团队权限隔离」→ 改用 `sys_dept` 承载课题组隔离(v1.8 定稿)**:经讨论,team 仍**不建独立模块、不加 `owner_team` 字段**;但启用 FastApiAdmin 框架**已有**的"部门(dept)数据范围"能力承载课题组隔离——把"课题组"建模为 `sys_dept` 节点,给角色配"本部门及子部门"数据范围,`Permission._permission_condition()` 即按创建者所在部门自动隔离,breeding 表零改动。
**隔离边界(关键业务决策)**
| 数据域 | 隔离策略 | 理由 |
|---|---|---|
| 性状字典、选择规则 | **跨组共享** | 全所统一观测标准与选择阈值 |
| 种质资源、系谱 | **跨组共享** | 所级资源库,亲本须被各课题组选配 |
| 试验基地、地块、育种人员 | **按课题组隔离** | 各组自有基地/地块与人员花名册 |
| 育种流程(杂交→评价) | **按课题组隔离** | 各组私有作业数据 |
| 统计分析(数据集/计算/育种值/指数/报告) | **按课题组隔离** | 各组独立遗传评估与决策 |
**局限**:隔离靠"创建者部门"推断(谁建的归哪组);若要"跨组协作同一条数据"需升级显式 `owner_team` + 多对多协作,留待单独立项。
**范围说明(2026-07-29 澄清)**:当前实际仅「桃育种课题组」在用,多课题组为**未来扩展**预留。隔离机制**先就位**——建 `sys_dept` 课题组节点 + 给角色配"本部门及子部门"数据范围即可,无需改任何 breeding 代码;无多组时所有用户同属一组,效果等同无隔离,不影响现有使用。未来新增课题组只需加 dept 节点并迁移用户 `dept_id`,即可自然隔离。
**落地(配置级、非代码,需先确认真实课题组清单)**:① `sys_dept` 建课题组节点 ② 用户 `dept_id` 归属 ③ 育种员等角色配数据范围"本部门及子部门"ADMIN/SUPER_ADMIN 看全部)④ 验证普通用户仅见本组数据。
4. **"材料库存"被弱化成纯报表**:库存是事务性的(种子批/ lot、在圃株数、离体/DNA 管数、活力)。应加 `germplasm_stock`/`seed_lot` 表(数量、批次、位置、活力、出入库),报表只是视图。【待拍板】
5. **缺环境/气象数据(G×E 统计地基)**:多年多点分析核心是基因型×环境互作,无环境协变量(site×year 的需冷量/积温/降雨)BLUP 只能粗估。建议加 `environment_condition`site×year),可复用 `yz.sql` 的"天气"字段。
6. **分子层缺"预测模型"表(GS 反馈环断裂)**:RosBREED 是闭环(表型+基因型→训练模型→输出 EBV→指导下轮选配)。需 `breeding_prediction`(模型/性状/精度 accuracy/预测日期/被预测个体)。
7. **克隆繁殖/苗圃 → 已定纳入一期(§3.8)**:现有 `seedling`/`seed_treatment` 仅种子实生苗;桃入选后主要靠嫁接/芽接扩繁,补 `breeding_propagation`(接穗来源→成活→出圃),打通 入选株→克隆种质→扩繁→新定植树 闭环。
8. **统一修改日志/审计缺失**:晋级审批、全程可追溯需"谁/何时/改了什么"轨迹,现有仅 `updated_time`。建议轻量 `breeding_audit_log`(或接系统操作日志)。
9. **小遗漏**`tree_photo` 应可关联 `observation`(某次测量的果实照片,为 CV/AI 预留);`observation` 应可挂 `trial_study_id`(区分试验观测 vs 果园日常观测);编号生成策略未定义(`accession_no`/`combination_code`/`tree_no`/`trial_code` 需统一自动编号服务)。
### 8.2 替代思路与推荐
- **A. EAV 纯通用 vs 混合固定列 → ~~推荐混合固定列~~(v2.2/F1 已推翻,改为单一长表,详 §8.4)**。~~理由:桃果实质性状稳定且高频、报表是核心需求、现有 tree_evaluation 已在工作。~~ **v2.2 更新**:代码 2026-07-29 已删 `tree_evaluation` 固定列、全迁 `breeding_trait_observation` 长表,故最终裁定走单一长表;原"报表性能"顾虑改由 DB 视图 pivot(统计 VIEW / 看板 MV)解决,不再保留固定列。
- **B. 分组 vs 标签 → 建议并行**:`group`(正式项目组/品系群)+ 自由 `tag`(多对多,如"抗褐腐""高Brix""区试备选")。
- **C. 直接对齐 BrAPI API → 已采纳(见 §0 原则 7)**:不仅"铺路",而是正式承诺实现 BrAPI 兼容只读适配层。建议首批暴露端点(映射我们的模块):
- `/brapi/v2/germplasm``/brapi/v2/germplasm/{id}/pedigree` ← germplasm + cross_combination 系谱链
- `/brapi/v2/programs` ← target`/brapi/v2/crosses` ← cross_combination
- `/brapi/v2/trials``/brapi/v2/studies` ← trial / trial_study
- `/brapi/v2/observationvariables` ← trait`/brapi/v2/observations` ← observation
- `/brapi/v2/lists` ← group`/brapi/v2/observations`(带 op_type) ← field_operation(注:BrAPI 无顶层 Event,不映射 `/events`
- `/brapi/v2/samples``/brapi/v2/markers``/brapi/v2/calls` ← 分子层
- 适配层为**只读适配器**(读我们现有表,映射成 BrAPI JSON),不重复实现写操作;UI 仍走 `/breeding/*`
- **D. MIAPPE 合规 → 已采纳(见 §0 原则 8**Investigation=target、Study=trial_study、ObservationUnit=tree/plot、Variable=trait 对齐;作为数据导出/共享到国际仓储时的一致性检查基线。
### 8.3 复审后模块清单(原 21 模块基础上)
- 新增(一期):`environment_condition`site×year 环境因子,G×E 统计地基,§3.9)、`propagation`(克隆扩繁/苗圃,§3.8)、`breeding_audit_log`(审计,§3.10)、`breeding_selection_rule`(选择阈值,§3.11)、`breeding_seed_lot`(种子批/库存链,§3.13,v1.3 从延后**提前进一期**与 MET 一并建模);`breeding_prediction`(GS 模型/育种值,V2.0 与分子层同期,§3.12);`breeding_trial_study_entry`(试验 entry 清单,v1.4,MET 设计矩阵);`breeding_genotyping_dataset`(分型数据集,v1.4,GS 训练群体)。
- **字段强化(v1.4**`trait.ontology_uri`Crop Ontology 对接);`observation.status`(数据质量);`site` 经纬度/海拔(空间 BLUP);`germplasm` 护照块(FAO-MCPD);`pollination` 父/母本树(crossing block);`selection_result.rule_id`(决策闭环);`tree.entry_id`entry 聚合);`marker.panel`(芯片版本);`genotype_sample.dataset_id`
- **不建 `team` 模块**(v1.8 定稿):团队隔离由 `sys_dept` + 角色数据范围实现,breeding 表不加 `owner_team` 字段;公共基础数据跨组共享、育种流程与统计按组隔离(见 §8.1 第 3 点)。
- **仍延后(v1.4 标记)**:完整事务性出入库台账(`germplasm_stock` 等,`seed_lot` 已精简进一期);`experiment_factor`(MIAPPE 受控试验因子,先用 field_operation 近似);`breeding_report` 配置表(先用只读端点);`breeding_program` 顶层(BrAPI Programtarget 暂代)。
- 字段细化:`tree.germplasm_id` + `generation``tree.trial_study_id` + `block_no`**派生自 planting,单写点纪律**v1.4);`planting.trial_study_id` + `block_no` + `seed_lot_id``observation.trial_study_id` + 显式 FKv1.3);`tree_photo.observation_id`;统一编号生成服务。
- 物候期仍走 `observation`(时序,非固定列);系谱树仍靠 `cross_combination.parent_combination_id` 自链 + 前端树图。
### 8.4 长表决策详述(对应 §4 tree_evaluationv2.2/F1 改写)
**结论:单一长表(废弃"混合固定列")。** v1.0v2.1 曾定"混合固定列(Hybrid",但代码 2026-07-29 已删 `tree_evaluation` 固定列、全迁长表,统计 service 改从长表 pivot 取数;文档据此裁定改为单一长表:
- **单株鉴定明细层 = `breeding_trait_observation`**(挂 `evaluation_id`,tree 级):承载童期 + 评价段的所有单株性状(含原 `pa_four` 的 ~40 个核心果实/农艺性状),是 clone 级 EBV 的取数主路径,**喂 EBV**。
- **plot/物候层 = `breeding_observation`**:仅承载 plot/combination 级观测 + 物候期时序,**不喂 EBV**。
- **两表按"是否喂 EBV"正交切分**plot 级果实均值**不落表**,由统计视图从 `breeding_trait_observation` 聚合派生(§3.2/§3.2b),杜绝双写。
- **报表/SQL 聚合补偿(原固定列的唯一收益)**:由 DB 视图 pivot 顶上——**统计管线用普通 `VIEW`(实时 pivot、保 fresh、喂 BLUP****看板/报表用物化视图 `MV`(定时刷新换性能),但 MV 不得作 BLUP 输入**,避免过期数据污染 EBV/reliability。
- **防双源规则**:同一性状值只存一处(tree 级果实性状→`breeding_trait_observation`;物候/plot→`breeding_observation`),禁两表重复记录;`trait.is_core` 仅作"是否纳入统计核心指标"标志,**不再决定"存固定列还是 EAV"**。
- **代价**:报表需经视图 pivot(一次性建视图,非每次改表);换来"新增性状零表结构变更"与代码/文档一致。原"新增核心性状需 migrate 改表"的代价消除。
### 8.5 二次复审(v1.32026-07-28)— §8 遗留项处置
针对 §8.1–§8.3 的遗留与本人深度复盘,本轮一次性落档,要点:
| # | 议题(源自 §8 / 复盘) | v1.3 处置 |
|---|---|---|
| 1 | **MET 链路断裂(最致命)** | 彻底补全:`trial_study.block_count` + `planting.trial_study_id` + `tree.trial_study_id`/`block_no` + `plot.block_no`(§3.4/§4)。block 随机效应不再缺失,混合模型可估 |
| 2 | **库存与选择强度** | `seed_lot` 从"延后"提前进一期(§3.13),与 MET 拼出 seed_lot→seedling→planting→tree→trial_study 选择强度链;完整 ledger 仍延后 |
| 3 | **§0 原则1 与混合模型自相矛盾** | 已修订 §0 原则1 措辞,与 §4/§8.4 一致(字典一处定义、值可固定可扩展) |
| 4 | **observation/field_operation 多态反模式** | 改显式可空 FKtree_id/plot_id/combination_id),保引用完整 + 数据权限 `_build_conditions` 可用(§3.2/§3.3 |
| 5 | **三模块只有名字无规格** | 已补 `environment_condition`(§3.9)、`audit_log`(§3.10)、`prediction`(§3.12);并额外补 `selection_rule`(§3.11) |
| 6 | **tree_evaluation "保留"误述** | 改为"按 pa_four 扩 ~40 列",并补**统一性状值视图**消除 trait↔固定列双源漂移(§4) |
| 7 | **选择阈值规则缺失** | 新增 `breeding_selection_rule`(§3.11),决策支撑可自动化 |
| 8 | **批量表型导入未规划** | 已单列规划(§6),EAV 主数据入口区别于行式导入 |
| 9 | **tree_photo.observation_id 未落地** | 已纳入 §4 字段调整(todo 与正文对齐) |
| 10 | **group family/category 冗余** | family 改虚拟分组(由 combination_id 推导)、category 复用 `variety_type`(§3.5 |
| 11 | **BrAPI `/events` 不标准** | field_operation 改映射 `/observations`(op_type)(§3.3/§8.2-C |
| 12 | **文档计数过期** | §2 改为显式清单,不再钉"21" |
| 13 | **生成器机制** | 标注为待拍板 A/B/C(§6 工程约定),不再默认续用 `_gen_*.py` |
> 本轮为**纯文档定稿**,未触碰任何代码。待用户就 §7 minor 项(尤其生成器 A/B/C)确认后即可实施。
### 8.6 三轮复审(v1.42026-07-28)— 国际基准(BrAPI/Breedbase/RosBREED/MIAPPE/Crop Ontology/FAO-MCPD/Genesys
对照国际先进做法再扫一遍,把"正经育种程序该有、v1.3 仍缺"的落档:
| # | 议题(国际基准) | v1.4 处置 |
|---|---|---|
| 1 | **缺试验 entry 清单 / entry_number**BrAPI ObservationUnit = germplasm×entryNumber×rep×block | 新增 `breeding_trial_study_entry`(§3.4),`tree.entry_id` 挂回,BLUP 设计矩阵按 entry 聚合 |
| 2 | **缺 site 地理坐标**(空间 BLUP / MIAPPE 环境 / 积温插值) | `site``latitude/longitude/elevation`(§4 |
| 3 | **缺观测校验态**Breedbase 数据质量) | `observation.status`draft/validated)(§3.2),统计前按 validated 筛 |
| 4 | **trait 缺本体引用**Crop Ontology / MIAPPE 受控词表) | `trait.ontology_uri`(§3.1);注明 method/scale 内联简化、BrAPI 适配层拆分三元组 |
| 5 | **tree↔planting 双写漂移风险**(v1.3 隐患) | 明确**单写点=planting**`tree.trial_study_id/block_no` 为**派生**service 写树校验一致(§3.4 注) |
| 6 | **germplasm 缺护照描述符**FAO-MCPD / Genesys | germplasm 补 `institute_code/country_origin/collection_site/acquisition_date/biological_status/breeding_program`(§4 |
| 7 | **缺 genotyping_dataset**GS 训练群体分组) | 新增 `breeding_genotyping_dataset`(§3.7),`genotype_sample.dataset_id``marker.panel`(芯片版本) |
| 8 | **selection_result 未关联规则**RosBREED 决策闭环) | `selection_result.rule_id`(§4 |
| 9 | **缺 crossing block 父/母本树**(桃控制杂交) | `pollination.female_tree_id/male_tree_id`(§4 |
| 10 | **受控试验因子未结构化**MIAPPE ExperimentalFactor | 标记延后,先用 `field_operation` 近似(§6 |
| 11 | **breeding_report 配置表过早** | 标记延后,先用只读端点(§6) |
| 12 | **target 映射 BrAPI Program 略偏** | 标记延后,target 暂代 Program,后续可加 `breeding_program` 顶层(§6 |
| 13 | **tree.germplasm_id 多路径派生漂移** | 明确 `germplasm_id` 非空且由晋升流程写入、禁手填(§4) |
> 本轮为**纯文档定稿(v1.4)**,未触碰任何代码。文档进入"国际基准对齐版",待 §7 minor(尤其生成器 A/B/C)确认后实施。
### 8.7 四轮复审(v1.52026-07-28)— 用户拍板的 v1.4 自洽修复
用户就第四轮复审(§8 末尾 16 点)拍板:只要合理全部采纳以下 5 点,并生成新版:
| # | 议题(v1.4 自洽/国际盲点) | v1.5 处置 |
|---|---|---|
| 1 | `planting` 单写点却无 entry`tree.entry_id` 无法派生 | `planting``entry_id`(§3.4/§4);`tree.entry_id`/`block_no`/`trial_study_id` 全派生自 planting |
| 2 | 多年生 `tree` 与单值 `trial_study_id` 冲突(跨年观测归属丢失) | `tree.trial_study_id` **仅记「定植所属 study」**;跨年/跨点观测改由 `observation.trial_study_id + obs_year` 表达,不引入中间表,保单写点纪律 |
| 3 | 试验树 `germplasm_id` 时序张力(入试即需已知 vs 晋升才写) | 区分两类 tree:`planting.entry_id` 非空 ⇒ 参试无性系(`germplasm_id` 入试即定 = `entry.germplasm_id`);为空 ⇒ 杂种实生苗(待晋升)。以 entry 有无区分,无需新类型字段 |
| 4 | `split_plot` 设计已支持但 `experiment_factor/treatment` 延后 | `breeding_treatment`(factor+level) **提进一期(§3.14**,混合模型增 `treatment` 项,可估因子主效应与互作 |
| 5 | `seed_lot` 非事务致「获种数」源头不可靠 | `seed_lot``used_count`,派生 `remaining = seed_count - used_count`,选强链前段(获种→已用)可量化 |
> 本轮为**纯文档定稿(v1.5)**,未触碰任何代码。文档进入「v1.5 自洽修复版」,待 §7 minor(尤其生成器 A/B/C)确认后实施。
### 8.8 五轮复审(v1.62026-07-28)— 用户拍板"全部采纳"第五轮复审
用户就第五轮复审拍板"全部采纳",落档 v1.6(同时补齐 v1.5 因替换异常遗漏的 §3.14/treatment 行/used_count):
| # | 议题 | v1.6 处置 |
|---|---|---|
| A1 | 核心性状固定列(tree_evaluation)缺 trial_study_id 环境键 | tree_evaluation 加 `trial_study_id`(按年 observation 推导/直填),使核心性状纳入 MET 环境效应(修复 v1.5 裂痕) |
| A2 | planting 粒度未定义 | 明确 planting=block 级批次;同 entry 跨多 block 建多 planting |
| A3 | treatment 关联字段未落地 | 新增 `breeding_planting_treatment`(§3.15planting×treatment 多对多) |
| A4 | seed_lot.used_count 单位未定义 | 明确=已从该批取用**粒数**(播种环节按粒累加,非定植株数) |
| A5 | tree_photo.observation_id 文档自述已改但 §4 无行 | §4 补 `tree_photo` 行(observation_id |
| A6 | EBV 估 germplasm 级但 tree↔germplasm 重复测量未建模 | 明确 tree_evaluation/observation 按 `tree.germplasm_id` 聚合为 clone 重复,EBV 随机效应在 germplasm |
| B1 | marker 缺 assembly_version | marker 加 `assembly_version` |
| B2 | 基因型编码标准 | genotype_call.allele 声明 VCF/GP 编码(0/1/2=纯合ref/杂合/纯合alt |
| B3 | season 概念 | trial_study 加 `season` |
| B4 | observation 缺审核人/时间 | observation 加 `validated_by`/`validated_date` |
| B5 | 单位校验+批量换算 | observation 加 `unit`(冗余自 trait),导入服务做换算 |
| B6 | method/scale 受控词表 URI | trait 加 `method_uri`/`scale_uri` |
| B7 | planting 来源双路径 | planting 加 `propagation_id`(种子批/扩繁批二选一) |
| B8 | observationUnit level | 文档标注 tree/plot/block 对应 BrAPI observationLevels |
| B9 | kinship/A 矩阵 | §5 补系谱 A 矩阵(pedigree 解析) |
| B10 | selection_rule 支持 EBV | conditions_json 允许引用 prediction_valueEBV 阈值) |
| B11 | breeding_program 自由文本说明 | 文档标注 germplasm.breeding_program 暂自由文本、后续可升级 FK |
| C1 | selection_result 跨年晋级关联 | selection_result 加 `trial_study_id`(可空) |
| C2 | 新表数据权限接入 | 文档约束新模块须用 CRUDBase 自动注入数据权限 |
> 本轮为**纯文档(v1.6)**,未触碰任何代码。此后 v1.7(统计决策闭环)、v1.8(团队隔离收口)均为纯文档演进,未触碰任何 breeding 业务表/接口/代码。文档进入「v1.8 团队隔离定稿版」,待生成器 A/B/C 拍板后实施。
### 8.9 V2.11 方案书统计/决策支撑对照(v1.72026-07-28
用户要求评估《桃育种数字化项目方案书_V2.11》中「统计分析与决策支持」(专册 2.1–2.8 方法 / 3.13.4 决策)能否被 v1.6 支撑。结论:**方法面全部可支撑**(数据地基 / MET 维度 / 统计引擎接口齐备);发现 3 硬 + 2 软缺口,v1.7 全部闭环:
| # | 缺口 | v1.7 处置 | 类型 |
|---|---|---|---|
| ① | EBV 持久化时序冲突(值表标 V2.0,但趋势图 / 双轨选择 / 亲本单株决策需读持久化 EBV) | `breeding_prediction_value` 值表前移 V1.1,与统计引擎同期写入;GS 模型训练留 V2.0 | 硬 |
| ② | 负载量协变量未建模(专册 1.3 要求坐果量评级降果实性状环境误差) | `tree_evaluation.crop_load`(评级 1/2/3)作混合模型协变量 | 硬 |
| ③ | `breeding_report` 延后(专册 3.3.1 年度 Word/PDF 报告) | 用户确认一期必须:进 P2,补 `output_format` + 报告生成服务(docx/pdf 导出) | 硬/软(用户拍板"必须" |
| ④ | 数据质量自定义生物学阈值无落点 | `breeding_trait.valid_min/valid_max` 承载合理范围,供异常标记 | 软 |
| ⑤ | 超期预警/通知机制(专册 3.3.2 树 N 年未决策预警) | 列为工程项:cron + `selection_rule`/`selection_result` 触发通知,不阻塞数据模型 | 软 |
> 本次为**纯文档(v1.7)**,未触碰任何代码。文档进入「v1.7 统计/决策闭环版」,仅余生成器 A/B/C 待拍板。
---
### 8.10 深度复审 AH 全量落地(v2.2,2026-07-30,用户逐条确认 + F1/F2 拍板)
**变更索引**(每项均已在正文对应 § 落字):
| 编号 | 问题 | 裁决 | 落点 |
|---|---|---|---|
| A1 | `tree.clone_id` 定植必填与"clone=入选克隆"矛盾 | 实生苗定植可空、入选晋升才建 clone 回填;参试无性系必填 | §3.0/§4 tree |
| A2 | `produced_clone_id` 命名易读作"新建克隆" | 澄清=被扩繁原 clone、沿用不新建 | §3.8 |
| A3 | `rootstock_id` FK 三处打架 | 全文统一 FK→`breeding_rootstock`germplasm.is_rootstock 仅标记 | §1/§3.8/§4/§5.x |
| A4 | A 矩阵系谱来源双源 | 以 `breeding_pedigree` 为唯一权威,combination 仅派生源 | §3.18/§5.8 |
| B1 | h² 落在明细每行 | 上移主表 `breeding_prediction`(一次 BLUP×一性状=一 h²) | §3.12 |
| B2 | "广义遗传力"误称 | 正名加性(狭义) h²,落库取克隆均值 h²=V_clone/(V_clone+V_e/k̄) | §3.12 |
| B3 | 缺 sommer 基线公式 | 补 `mmer(y~rootstock+site+year+block, random=~vsr(clone,Gu=A)+vsr(clone:year))` | §5.2 |
| B4 | 双轨选择粒度错配 | 统一 clone 级判定(表型先聚合到 clone 均值) | §5.9 |
| C1 | 门禁作用于固定列 | 改作用于 `breeding_trait_observation` 长表 | §3.16 |
| C2 | 缺质量标记字段 | 加 `issue_status`normal/pending/rejected),不新建表 | §3.2/§3.2b |
| C3 | 门禁与状态机脱节 | 拒收→rejected+draft;异常→pendingnormal+validated 才进池 | §3.16 |
| D1 | selection_result 无 clone 级 | 加 `clone_id`tree_id 留溯源) | §4 |
| D2 | clone 无世代 | 加 `generation`(可由 combination 派生) | §3.0 |
| D3 | entry 未落 clone | `trial_study_entry``clone_id` | §3.4 |
| D4 | tree↔clone 状态流转缺矩阵 | 补状态流转矩阵(下) | §8.10 |
| F1 | 固定列 vs 长表三方打架 | **裁定单一长表、废固定列、报表用视图** | §0/§3.2/§4/§8.4 |
| F2 | 两长表命名/职责重叠 | 保留两张、按"是否喂 EBV"正交;补登记 `breeding_trait_observation` | §2/§3.2/§3.2b |
| F3 | 门禁键含 clone_id 拒收实生苗 | 实生苗阶段单元键退化为 tree_id | §3.16 |
| F4 | 判重键删合法 clonal replicates | 判重键含 tree_id | §3.16 |
| F5 | §5.2 公式漏 rootstock | 公式补 rootstock 固定效应 | §5.2 |
| G1 | 编号服务未定义 + 序号位宽不足 | 定义统一编号服务(下)、clone 序号≥4 位 | §3.0/§8.10 |
| G2 | 手册"不可删只留痕"落点缺 | 鉴定类表禁物理删+UPDATE 强制 audit | §3.10 |
| G3 | method 文本 vs method_uri 受控 | 合并声明两字段并存 | §3.1 |
| H1 | valid_min/max 全局单值 | 接受全局+人工复核,可 scale_json 分档 | §3.1 |
| H2 | environment 与 site/year 共线 | environment=具体气象协变量,非再建 site×year 层 | §5.2/§3.9 |
| H3 | group_member 挂 tree/clone 未定 | 加 clone_id 成员 | §3.5 |
**G1 · 统一编号生成服务(定义)**:集中式编号服务按前缀 + 顺序号生成,全局唯一、可追溯,并发下加行锁/序列保证不重号:
- `accession_no`(种质):`GP-{组来源}-{6位序}``combination_no`(组合):`CC-{年}-{4位序}``tree_no`(单株):`{combination_no}-{4位株序}`(定植时生成);`clone_id`(克隆):`{combination_no}-{≥4位单株序}`(**入选晋升时**由服务生成,非定植时,A1);`trial_code``TR-{年}-{3位序}`
- clone 序号扩至 **≥4 位**(容纳单组合数千株,解决原 3 位=999 上限,G1)。
**D4 · tree ↔ clone 状态流转矩阵**
| 阶段 | tree.status | 是否建 clone | breeding_clone.status | selection_result | 说明 |
|---|---|---|---|---|---|
| 定植(杂种实生苗) | 入选(默认) | 否(clone_id 空) | — | — | 童期观测按 tree_id 聚合 |
| 初选晋升 | 初选 | **是(建 clone、回填 clone_id** | 入选/初选 | 写一行(clone_id+tree_id | 门禁键切 clone_id、启用 A 矩阵 |
| 复选/重点 | 重点 | 沿用 | 重点 | 追加流转 | clone 级 EBV 多年重复 |
| 保存 | 保存 | 沿用 | 保存 | 追加 | 资源保留 |
| 淘汰 | 淘汰 | 沿用(状态变更非删除) | 淘汰 | 追加淘汰记录 | **禁物理删/软删,G2** |
| 参试无性系(entry 批) | 入选 | 定植即有 clone | 入选 | — | 定植即 clone 级 |
**F2 · 命名对照(消除"代码有、文档无"**:模块/URL/权限 = `trait_observation`;模型类 = `TraitObservationModel`**物理表 = `breeding_trait_observation`**(与全项目 `breeding_*` 前缀一致)。文档指物理表用后者,指模块用前者。
---
### 8.11 统计引擎两轮 P0 代码落地台账(v2.32026-08-03/04,代码级)
> 本规格自 v2.0 起为**方案态**(待"做"落地)。2026-08-03/04 将其中两条统计地基从方案推进到**代码落地 + e2e 验证**。本节为落地台账摘要,完整明细(含文件清单/备份/复跑命令)见 `桃育种系统统计引擎实施记录.md`。
**① G×E 交互引擎(2026-08-03**——对应 §5.2「G×E」互作项落地:
| 规格点 | 落地 |
|---|---|
| G×E 随机互作 | `run_ablup(gxe=True, gxe_env=site/year)``method=GXEBLUP``gxe=False` 回归纯 ABLUP |
| 环境维度 | `site`→自动固定效应 `trial_study``year`→自动固定效应 `year`(调用方可显式追加 `fixed_effects` |
| 交互量 | σ²gxe / gxe_ratio / n_cross_env 落 `breeding_prediction.note` JSON |
| 可辨识性门禁 | 无跨环境重复 / 单元内无重复 → 409「G×E 不可辨识:…」 |
| 克隆坍缩 | 同 clone 多株坍缩为基因型节点 `c{clone}`record_map 全映射),同 clone EBV 一致 |
| 异步任务 | `StatisticsJobModel` job_type=GXE/ABLUPSUCCESS/FAILED + error_msg(门禁失败亦落) |
| 验证 | `e2e_gxe_20260803.py` 5 场景全过(spy 捕获 fixed/record_map kwargs |
**② 性状方向标注(2026-08-04**——对应 §3.1 / §5.9 / §5.z 落地:
| 规格点 | 落地 |
|---|---|
| 三字段 | `breeding_trait.direction/into_ebv/default_h2`(幂等 ALTER `weld_trait_direction.sql` + 种子 43 行 ON CONFLICT 含新列) |
| 指数翻转 | zsum 对 asc 性状 z 取负、smith_hazel 对 asc 元素 a 取负 → 统一"越大越优",低优性状不选反 |
| into_ebv | `'0'` 从指数候选/EBV 排行/决策预览/ABLUP 下拉剔除(`extra.dropped` 提示);describe/correlation/trait_values 不受影响 |
| default_h2 兜底 | 指数无实测 h² 用先验兜底(zsum/smith_hazel 均兜底,两者皆无才 409 |
| 排行方向 | `run_ablup` 写时按方向排序;`ebv_ranking` **读时重排**(结构性 bug 修复);`clone_ranking` 方向感知 |
| 轮次对比 | `compare_predictions` 方向感知(结构性 bug 修复) |
| 前端 | statistics `selTraits` 解耦(与 describe/correlation 共享列表分离)+ trait 表单三字段 + selection_rule 说明 |
| 验证 | `e2e_direction_20260804.py` 7 组全过(4 性状 × 4 批次 × 12 株 EBV 基线) |
---
## 9. 已决策取值汇总(v1.2,本人敲定)
> 下列枚举由本人依据 RosBREED 桃无性选育流水线 + 现有 14 域敲定(用户授权"你来定")。全部作为 `sys_dict` 新增字典类型,落库英码、前端显中文,并接入 Excel 导入翻译(DictLabelResolver)。
### 9.1 breeding_stage(选择阶段)
| code | 中文 | 主要适用实体 | 说明 |
|---|---|---|---|
| germplasm | 种质资源 | germplasm | 基础材料/引入种 |
| parent | 亲本 | germplasm | 用于杂交的亲本 |
| seedling | 实生苗/群体植株 | tree | 杂交实生群体、未入选 |
| sp | 初选株 | tree | Single Plant,田间初选 |
| ap | 复选株 | tree | Advanced,跨年跨点复选 |
| line | 品系 | germplasm | 克隆扩繁、系统观察 |
| regional_trial | 区试品系 | germplasm | 区域试验 |
| released | 新品种/审定 | germplasm | 命名/登记/审定 |
> tree 用 seedling/sp/apgermplasm 用 germplasm/parent/line/regional_trial/released`selection_result` 记录 from_stage→to_stage 晋级流转。
### 9.2 breeding_generation(遗传世代)
| code | 中文 | 说明 |
|---|---|---|
| F1 | 杂交集 | 首次杂交产生的分离群体(桃主要选种群体) |
| F2 | 自交/互交分离世代 | F1 自交或 F1×F1 |
| BC1 | 回交 1 代 | 导入性状(如抗病)回交 |
| BC2 | 回交 2 代 | |
| BC3 | 回交 3 代 | |
> 引入种质/地方品种 `generation` 留空。权威存 `cross_combination.generation`(与 `cross_type` 联动:回交→BCn,自交→F2),`tree`/`germplasm` 冗余拷贝便于筛选。
### 9.3 breeding_group_type(分组维度)
| code | 中文 | 说明 |
|---|---|---|
| project | 育种项目 | 正式项目集合 |
| family | 家系/杂交组合群 | 同 cross_combination 的后代集合 |
| category | 种质类别群 | 油桃/蟠桃/观赏桃等类别 |
| temporary_set | 临时选系集 | 临时任务选系集 |
| custom | 自定义 | 用户自由定义 |
> 不设 objective 维度(与 `target` 育种目标语义重叠)。
### 9.4 breeding_design_type(试验设计)
| code | 中文 | 说明 |
|---|---|---|
| rcbd | 随机区组 | 高级 trial 常用,区组+重复+对照 |
| augmented | 增广设计 | 多品系少重复+对照重复,**早期选种最适用** |
| contrast | 对比试验 | 少量材料与对照比较 |
| split_plot | 裂区设计 | 砧木×接穗等两因子 |
| unreplicated | 观察圃/简约 | 无重复,初步观察 |
### 9.5 propagation 纳入一期(§3.8
打通 入选株(tree) → 克隆种质(germplasm) → 扩繁批次(propagation) → 新定植树(tree) 闭环。
### 9.6 字典落地
`breeding_dict.sql` 增补 `breeding_stage`/`breeding_generation`/`breeding_group_type`/`breeding_design_type` 四类(英码+中文),并接入对应 service 的 Excel 导入翻译(DictLabelResolver)与前端下拉。
---
**定稿状态(v2.22026-07-30**:历经 v1.0→…→v1.9 + **v2.0 架构决策锁定** + **v2.1 review 修订(R1R9** + **v2.2 深度复审 A–H 全量落地(含 F1/F2 架构拍板:单一长表 + 两长表职责正交 + 统计 VIEW/看板 MVA1 clone 建于入选 / A3 砧木 FK 统一字典 / A4 pedigree 唯一权威 / B1-B4 统计口径 / C1-C3 门禁重构 / D1-D4 clone 居中 / F3-F5 门禁与公式修正 / G1-G3 编号·审计·method / H1-H3 打磨,详见 §8.10**。所有模块、字段、枚举、建模铁律、互操作映射均已规格化。**仍为决策锁定、方案态**:除生成器 A/B/C 外,待用户明确"做/搞吧"后据此实施,不先行编码。