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

550 lines
43 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 + `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 扩列"+ 统一性状值视图 ⑥ 补「选择阈值规则」+「批量表型导入」规划 ⑦ 文档计数/枚举对齐修正 |
---
## 0. 设计原则(本规格的宪法)
1. **性状字典与测量值分离 + 混合存储(对标 BrAPI `ObservationVariable` + `Observation`**`trait` 是唯一的性状字典(代码/类型/单位/量表),**新增桃性状只加字典、不动核心表结构**;测量值分两层存——① 核心高频性状(桃稳定 ~30–40 个,源自 `yz.sql` `pa_four`)以**固定列**落在 `tree_evaluation`(报表/SQL 聚合主路径)② 物候时序与临时/新增性状(`is_core=false`)走 **EAV** `observation`。二者经"统一性状值视图/服务"在统计层归一(§8.4)。这是与初稿最大的修正:不再追求纯 EAV,而是"字典一处定义、值可固定可扩展"。
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 |
| 自交系 | 桃为**克隆(无性繁殖)**,入选株 = 待审定克隆,需砧木关联 | germplasm.is_rootstock / tree.rootstock_id |
| 随机区组 / 间比试验 | 桃果园株数少,简化为 **区组 + 重复 + 对照**轻量设计 | 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 地基 |
| observation(通用观测) | breeding_observation | Observation | P0 地基 |
| field_operation(农事操作) | breeding_field_operation | Observation(op_type) | P0 |
| trial(多年多点试验) | breeding_trial + breeding_trial_study | Trial / Study | 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,决策地基) |
| 分子基因型层 | breeding_marker / breeding_genotype_sample / breeding_genotype_call | Sample / Calls / Marker | V2.0(地基先建) |
| predictionGS 育种值) | breeding_prediction | — | 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.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 |
| data_type | varchar(16) | NOT NULL | numeric / categorical / date / boolean |
| unit | varchar(32) | | g、%、°Brix、mm、date |
| method | varchar(256) | | 测定方法(如折射仪、游标卡尺) |
| scale_json | jsonb | | 量表/选项(categorical 时存选项数组;numeric 时存 min/max/step |
| is_preset | bool | default false | 是否系统内置(种子数据) |
| remark | varchar(512) | | |
| created_time / updated_time / is_deleted | 标准 | | 来自 ModelMixin |
**种子数据来源**`doc\果树所\育种\yz.sql``pa_four`(~40 字段:单果重/果形/果核/可溶性固形物/成熟期/离粘核/风味…)与物候类变量,导入为 `is_preset=true` 的桃专用性状字典。
### 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 |
| remark | varchar(512) | | |
**索引**`(trait_id, obs_year)``(tree_id)``(plot_id)``(combination_id)``(trial_study_id)`
**语义**:物候期时序观测 + `is_core=false` 的扩展性状走这张表;核心性状仍走 `tree_evaluation` 固定列(见 §4/§8.4)。统计层经「统一性状值视图」把两者归一(§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 | 田间种植图(小区排布坐标) |
| 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 项不再缺失。布局图由前端可视化 + 轻量排布算法生成。
### 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 | 成员种质 |
| 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) | |
**配套**:只读聚合端点(不建大表):
- `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 |
| remark | varchar(512) | |
**breeding_genotype_sample**(基因型样品)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| 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 |
| 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_germplasm_id | int FK→breeding_germplasm | 本次扩繁产出的克隆种质(晋升链路,`tree.germplasm_id` 同源) |
| rootstock_id | int FK→breeding_germplasm | 砧木(is_rootstock=true 的种质) |
| 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`)成为新 `tree`,新 tree 的 `germplasm_id` = `produced_germplasm_id`,完成闭环。
### 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 写操作时统一落审计),而非逐表加列。
### 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` 关联,新增性状自动可被规则引用。
### 3.12 breeding_predictionGS 育种值,V2.0 占位规格)
> 与分子层(§3.7)同期。RosBREED 闭环:表型+基因型→训练模型→输出 EBV→指导下轮选配。此处先定表结构,分析引擎后置。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int PK | |
| model_name | varchar(128) | 模型名(如"2026_Brix_GS" |
| trait_id | int FK→breeding_trait | 预测的性状 |
| method | varchar(32) | gBLUP/rrBLUP/GBLUP/Bayes |
| accuracy | numeric(5,3) | 模型精度(交叉验证) |
| train_n | int | 训练样本数 |
| predict_date | date | 预测日期 |
| note | varchar(512) | |
**明细** `breeding_prediction_value`(个体预测值):`prediction_id` / `germplasm_id``tree_id` / `predicted_value` / `reliability`
### 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 | | 收获粒数(选择强度源头) |
| 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(可选;种子来源定植)
> **选择强度贯通**`seed_lot.seed_count`(获种数)→ `COUNT(seedling WHERE seed_lot_id)`(成苗)→ `COUNT(tree WHERE planting.seed_lot_id)`(定植数)→ `COUNT(selection_result 入选)`(入选数)→ 各级**选择强度/选择率**可算,且 "每组合在某试验点种了多少" 与 MET 的 `trial_study` 直接挂钩。
---
## 4. 现有模块字段调整(非新增模块)
| 模块 | 新增字段 | 说明 |
|---|---|---|
| germplasm | accession_no(varchar UNIQUE)、pedigree(varchar 系谱串)、stage(varchar 选择阶段)、generation(varchar 遗传世代,可空)、storage_type(varchar 田间/离体/种子/DNA)、is_rootstock(bool)、rootstock_id(int FK 自关联) | 种质档案补全 + 桃特有维度 |
| cross_combination | cross_type(varchar 杂交/自交/开放)、parent_combination_id(int 自链 FK)、reason(varchar 选配理由)、stage | 系谱链 + 选配理由 |
| pollination | bagging_date(date 套袋)、emasculation_date(date 去雄) | 田间杂交登记补全 |
| seedling | seed_lot_id(int FK→breeding_seed_lot) | 追溯幼苗来源批(选择强度链,§3.13) |
| planting | rootstock_id(int FK→germplasm)、**trial_study_id(int FK→breeding_trial_study,可空)**、**block_no(int,该批树所属区组)**、**seed_lot_id(int FK→breeding_seed_lot,可空)** | 砧木–接穗建模 + **试验隶属(MET 链路运营钩子)** + 库存链接 |
| tree | stage(varchar 选择阶段)、generation(varchar 遗传世代,冗余自 combination)、rootstock_id(int FK→germplasm)、germplasm_id(int FK→breeding_germplasm 晋升的克隆种质)、**trial_study_id(int FK→breeding_trial_study,可空,从 planting 同步)**、**block_no(int,该树所属区组/重复,BLUP block 效应来源)** | 阶段/世代标记 + 克隆晋升链路(4.x 全流程 + GS 拼接依赖)+ **MET 观测单元归属** |
| site | soil_type(varchar 土壤类型) | 试验地块补全 |
| selection_result | 对齐 stage 晋级流转(建议加 from_stage/to_stage + approved_by | 晋级审批流 |
**tree_evaluation 定位(复审定稿:混合模型)**`tree_evaluation` **不是"原样保留",而是按 `yz.sql``pa_four` 扩列**为承载桃稳定高频 ~30–40 个核果实/农艺性状的固定列评分卡(一树一年一行),这是 90% 报表与 SQL 聚合的主路径;`observation` 仅作为**扩展层**承载物候期时序观测 + 字典中标记为 `is_core=false` 的新增/临时性状。详见 §8.4。*原则修订:§0「性状与观测分离」对单作物程序过严,改为「核心性状固定列 + 扩展性状 EAV」。*
**统一性状值视图(v1.3 补,统计层关键)**`tree_evaluation` 列与 `trait` 字典**无键关联**(仅靠 `trait.is_core` 人脑约定,易漂移)。故在统计/GS 层定义**统一性状值视图**(DB 视图 `v_trait_value` 或 service),把"固定列(tree_evaluation 按 trait_code 拍平) + EAV(observation)"按 `(unit, trait_code, obs_year)` 归一为单一宽/长表,供 V1.1 BLUP 与 V3.0 决策消费。种子初始化时须**同时**把 pa_four 写入 `trait(is_core=true)``tree_evaluation` 列,新增核心性状走 migrate 扩列 + 同步字典。
---
## 5. 统计分析与决策地基(关键要求)
用户明确要求"统计分析与决策,需要基础能够支持"。数据模型须满足:
1. **任意性状可聚合**:统一性状值视图(§4 末尾)把固定列 + EAV 归一,使「按性状×年份×地点×阶段」切片聚合无需改表——这是 ABLUP/EBV 与选择指数的输入。
2. **MET 结构就绪(v1.3 已彻底补全)**`tree.trial_study_id`(环境=site×year+ `tree.block_no`(区组随机效应)+ `trial_study.block_count` 提供完整试验设计维度。V1.1 混合模型 `y = genotype + block + environment + G×E` 各效应项齐备,可输出单株 EBV。
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)。
---
## 6. 实施路线(建议)
| 阶段 | 内容 |
|---|---|
| 地基(先做) | trait + observation + 现有模块 stage/rootstock/accession_no/pedigree 字段;数据权限/options 沿用现有生成器 |
| P0 | field_operation |
| P1 | trial(+study,§3.4)、group(+member,§3.5)、propagation(克隆扩繁,§3.8)、seed_lot(种子批,§3.13)、environment_condition(环境因子,§3.9)、audit_log(审计,§3.10)、selection_rule(选择阈值,§3.11)、breeding_report |
| P2 | statistics 聚合端点(含 selection_rule 驱动的自动 flag/晋级预览) |
| **批量表型导入(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(地基先建表,分析后置)+ prediction(§3.12) |
| 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.3 复审后**剩余 minor 项**,均不阻塞模块落地,实施时一并确认即可:
1. **trait 字典首批字段**:建议直接以 `yz.sql``pa_four` ~40 字段为种子(真实桃性状),category 按 §3.1 划分。*本人建议采纳。*
2. **自由标签 tag 系统**:§8.2-B 建议 group + tag 并行,tag 模型待定(可复用 group_member 思路或独立 tag 表)。
3. **prediction 纳入时点**breeding_prediction 留 V2.0(与分子层同期),规格已占位(§3.12)。
4. **编号生成策略**accession_no/combination_code/tree_no/trial_code/lot_code 统一自动编号服务实现方式。
5. **生成器机制 A/B/C(关键待拍板)**:内置 `module_generator` vs 续用 `_gen_*.py` vs 全迁 plugin(见 §6 工程约定与记忆)。
> v1.3 **已将 §8 二次复审的合理项全部落档**:MET 链路彻底补全 + 库存 seed_lot 一并建模、observation/field_operation 改显式 FK、补 environment_condition/audit_log/selection_rule 规格、tree_evaluation 明确扩列 + 统一性状值视图、补批量表型导入与选择阈值规则。文档自此进入"深度复审定稿"状态,待上述 minor 项(尤其 5)点头后即可实施。
---
## 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「按团队权限隔离」→ 不建 team 模块(已决策)**:用户判定 team 仅用于数据隔离、当前不需要。故**不新增 `team` 模块、不加 `owner_team` 字段**;数据权限维持现有 RBAC + `_build_conditions``created_id` 过滤即可。若未来确有跨团队隔离需求,再单独立项。
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 混合固定列 → 推荐混合固定列**(详 §8.4)。理由:桃果实质性状稳定且高频(yz.sql 已验证 40 固定字段沿用多年)、报表是核心需求(固定列 SQL 聚合极快)、现有 `tree_evaluation` 已在工作——纯 EAV 会牺牲报表性能并浪费已建代码。
- **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)。
- **不建**`team` 模块(用户判定仅用于数据隔离、不需要,保留 RBAC + created_id 过滤即可)。
- **仍延后**:完整事务性出入库台账(`germplasm_stock` 等);`seed_lot` 已以"批记录"精简版进一期,满足选择强度与 MET 链接,完整 ledger 后续另行立项。
- 字段细化:`tree.germplasm_id` + `generation``tree.trial_study_id` + `block_no`METv1.3);`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 EAV 决策详述(对应 §4 tree_evaluation
**结论:混合固定列(Hybrid)。**
- **固定列层 = `tree_evaluation`**:承载桃稳定高频的 ~30–40 个核心果实质/农艺性状(单果重、果形、果核、可溶性固形物、成熟期、离粘核、风味、硬度…,源自 `yz.sql` `pa_four`)。一树一年一行,表单/报表直读,SQL 聚合无需 pivot。
- **EAV 扩展层 = `observation`**:仅承载①物候期时序观测(萌芽/开花/坐果/成熟,一树多期,天然时序)②`trait` 字典中 `is_core=false` 的新增/临时性状。
- **防双源规则**`trait.is_core` 标志——核心性状只存固定列,非核心只存 observation,禁止同一性状两处重复记录。
- **对统计引擎(V1.1)**:读取两者——核心性状走固定列、扩展性状走 observation,统计层归一化后做 BLUP/EBV。
- **对 GS/决策**:表型来自固定列 + observation,基因型来自 `genotype_call`,经 `tree.germplasm_id` 桥接,由 `breeding_prediction` 输出育种值。
- **代价**:新增核心性状需改表(但低频,且走 `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)确认后即可实施。
---
## 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)与前端下拉。
---
**定稿状态(v1.32026-07-28**:历经 v1.0→v1.2→v1.3 三轮(初稿 / 取值决策 / 二次复审),文档进入"深度复审定稿"状态。所有模块、字段、枚举、互操作映射均已规格化。**确认(尤其生成器 A/B/C)后据此实施,不先行编码。**