fix:sample/plate 之前的开发

This commit is contained in:
彭帅
2026-05-28 11:56:17 +08:00
parent fc36bc83e3
commit 8b65de36b8
367 changed files with 57752 additions and 947 deletions

View File

@@ -0,0 +1,890 @@
# Genotyping 模块专业数据录入需求文档 V2
## 1. 文档目的
本文档用于指导 Genotyping 基因型模块的前端页面、后端接口、字段校验、文件导入、矩阵展示和测试验收设计。本文档不只描述数据库表关系,而是从真实基因型检测业务出发,解释每个对象和字段的业务意义、录入方式、控件建议、校验规则和上下游影响。
## 2. 模块定位
Genotyping 模块描述从田间或实验对象取样,到实验室检测,再到导入基因型结果矩阵的完整流程。
它的核心业务不是“录 allele_call 表”,而是:
```text
从哪个 study / observation_unit 取样
样本放在哪块 plate 的哪个 well
检测结果基于哪个 reference_set
结果文件包含哪些 variantset / variant
每个 sample 在每个 variant 上的 genotype 是什么
这些位点是否还映射到 genome_map / linkage_group
```
## 3. 核心业务主线
Genotyping 有三条主线:
```text
样本线study / observation_unit -> plate -> sample -> callset
位点线reference_set -> reference -> reference_bases -> variantset -> variant
结果线callset + variant -> allele_call
图谱线crop -> genome_map -> linkage_group -> marker_position -> variant
```
### 3.1 样本线
样本线回答:
```text
从哪个材料、哪个 plot、哪株植物或哪个样本来源取样
样本叫什么?
谁采的?什么时候采的?
放在哪块样本板哪个孔?
```
对应核心表:
```text
plate
sample
callset
```
### 3.2 位点线
位点线回答:
```text
检测结果基于哪个参考基因组?
参考序列有哪些 chromosome / scaffold / contig
检测了哪些 SNP / Indel / SV 位点?
这些位点属于哪个 variantset
```
对应核心表:
```text
reference_set
reference
reference_bases
variantset
variant
```
### 3.3 结果线
结果线回答:
```text
某个 sample 在某个 variant 上的 genotype 是什么?
测序深度是多少?
是否 phased
是否有 likelihood
```
对应核心表:
```text
callset
allele_call
```
### 3.4 图谱线
图谱线回答:
```text
某个位点在遗传图谱或物理图谱上的位置是什么?
它属于哪个 linkage group / chromosome / scaffold
单位是 cM 还是 Mb
```
对应核心表:
```text
genome_map
linkage_group
marker_position
```
---
# 4. 推荐业务流程
```text
1. 准备 Core / Phenotyping 上游数据crop、program、trial、study、observation_unit
2. 从 observation_unit 或 study 批量生成 sample
3. 创建 plate并把 sample 分配到 well / row / column
4. 送检或接收实验室结果文件
5. 创建 reference_set维护 reference / reference_bases
6. 创建 variantset导入 variant
7. 为 sample 生成 callset
8. 绑定 callset 与 variantset
9. 导入 allele_call形成 sample × variant 基因型矩阵
10. 如有遗传图谱,创建 genome_map / linkage_group / marker_position
11. 做结果质控缺失率、重复位点、重复样本、read depth、genotype 格式、reference 一致性
```
---
# 5. 推荐页面形态
## 5.1 Genotyping 工作台
建议以 study 或 genotyping project 为入口组织页面:
```text
Genotyping 工作台
├─ 样本管理sample 列表、从 observation_unit 生成 sample
├─ 样本板plate 列表、96/384 孔位布局
├─ 参考基因组reference_set、reference、reference_bases
├─ 变异集合variantset、variant、analysis、format
├─ 检测结果callset、allele_call、genotype matrix
├─ 遗传图谱genome_map、linkage_group、marker_position
├─ 导入导出sample 模板、VCF/Hapmap/CSV、allele matrix
└─ 质控:缺失率、重复率、深度、位点过滤、样本过滤
```
## 5.2 Plate 孔位布局页
样本板不建议只做普通 CRUD应提供 96 孔 / 384 孔布局视图:
```text
Plate-96-001
01 02 03 04
A SAMPLE-001 SAMPLE-002 SAMPLE-003 SAMPLE-004
B SAMPLE-013 SAMPLE-014 SAMPLE-015 SAMPLE-016
C SAMPLE-025 SAMPLE-026 EMPTY EMPTY
...
```
用户在孔位上放置 sample系统保存
```text
sample.plate_id
sample.well
sample.plate_row
sample.plate_column
```
## 5.3 Genotype Matrix 结果页
`allele_call` 是基因型矩阵中的一个格子:
| sample / callset | SNP001 | SNP002 | SNP003 |
| ---------------- | ------ | ------ | ------ |
| SAMPLE-001 | A/G | C/C | T/G |
| SAMPLE-002 | A/A | C/T | T/T |
| SAMPLE-003 | ./ . | C/C | T/G |
导入时:
```text
样本列 / 样本行 -> sample / callset
位点列 / 位点行 -> variant
单元格 genotype -> allele_call.genotype
```
---
# 6. 字段级专业录入需求
## 6.1 plate 样本板
### 业务说明
`plate` 用于管理承载样本的样本板或样本容器组。真实业务里,它通常是一块 96 孔板、384 孔板也可能是一组试管或实验室提交批次。plate 的核心价值是支持实验室送样、扫码、孔位追踪和结果回填。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------------------- | ----------------------------------------------- | ------------------------------ | ----------------- | -------------------------------------------- |
| `id` | 样本板主键,系统内部唯一标识 | 系统生成;导入可指定 | 隐藏/只读 | 必填、唯一;编辑不可修改 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许前端手填 |
| `client_plate_barcode` | 客户侧或外部实验室给出的板条码 | 用户录入/扫码/导入 | 文本框/扫码框 | 可选;建议唯一 |
| `client_plate_db_id` | 客户侧系统中的 plate ID | 用户录入/导入 | 文本框 | 可选;用于外部系统对接 |
| `plate_barcode` | 本系统样本板条码 | 系统生成/扫码录入 | 文本框/扫码框 | 可选;建议唯一 |
| `plate_format` | 样本板规格,如 96、384 | 用户选择 | 下拉框 | 可选;若填写,应限制为系统支持规格 |
| `plate_name` | 样本板名称,如 Plate-2026-001 | 用户录入/系统生成 | 文本框 | 与 barcode 至少一个必填 |
| `sample_submission_format` | 样本提交格式,如 DNA、tissue、seed、tube、plate | 用户选择 | 下拉框 | 可选;建议枚举化 |
| `sample_type` | 该板默认样本类型 | 用户选择 | 下拉框 | 可选;可作为 sample 默认值 |
| `status_time_stamp` | 样本板状态更新时间 | 系统自动写入 | 只读日期时间 | 可选;状态变化时自动更新 |
| `program_id` | 所属项目 | 从 program 选择或由 study 带出 | 项目选择器/只读 | 可选;若 study 已选,应与 study.program 一致 |
| `study_id` | 所属 study | 从 study 选择 | Study 选择器 | 可选;若选择则带出 trial/program |
| `submission_id` | 外部 vendor submission 或送检单 ID | 用户录入/选择 | 选择器/文本框 | 可选;用于实验室送检对接 |
| `trial_id` | 所属 trial | 从 trial 选择或由 study 带出 | Trial 选择器/只读 | 可选;若 study 已选,应与 study.trial 一致 |
### 录入建议
- 创建 plate 时,用户先选择 `plate_format`,系统生成孔位矩阵。
- 如果从 study 工作台创建,`program_id``trial_id``study_id` 自动带出。
- 如果通过实验室返回文件创建,应优先用 `plate_barcode``client_plate_barcode` 匹配。
### 验收标准
1. `plate_name``plate_barcode` 至少填写一个。
2. 同一系统中 `plate_barcode` 不应重复。
3. 选择 study 后trial/program 自动带出且保持一致。
4. plate_format 为 96 时,只允许 A01-H12384 时只允许 A01-P24。
---
## 6.2 sample 样本
### 业务说明
`sample` 是 genotyping 流程的样本入口表示从田间、温室、实验室或库存材料中取出的一个物理生物样本例如叶片、种子、DNA、组织、提取液等。sample 应尽可能关联 observation_unit这样才能把表型和基因型打通。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | ------------------------------------ | -------------------------------------- | ---------------------- | --------------------------------------------------------- |
| `id` | 样本主键,系统内部唯一标识 | 系统生成;导入可指定 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `concentration` | 样本浓度,如 DNA 浓度 50 ng/µL | 用户录入/仪器导入 | 数字+单位输入 | 可选;建议拆分数值和单位,当前字段可暂存文本 |
| `plate_column` | 样本在 plate 中的列号 | 孔位选择自动生成 | 数字输入/孔位控件 | 绑定 plate 时必填或由 well 解析;范围受 plate_format 限制 |
| `plate_row` | 样本在 plate 中的行号 | 孔位选择自动生成 | 下拉/孔位控件 | 绑定 plate 时必填或由 well 解析;范围受 plate_format 限制 |
| `sample_barcode` | 样本条码 | 扫码/系统生成/导入 | 文本框/扫码框 | 可选;建议唯一 |
| `sample_description` | 样本说明 | 用户录入 | 多行文本 | 可选 |
| `sample_group_db_id` | 样本组 ID用于批次、送检组或处理组 | 用户选择/导入 | 选择器/文本框 | 可选 |
| `sample_name` | 样本名称,如 SAMPLE-001 | 用户录入/系统生成 | 文本框 | 必填;同一 study 下建议唯一 |
| `samplepui` | 样本永久唯一标识 | 用户录入/系统生成 | 文本框/URL 输入框 | 可选;若填写建议唯一 |
| `sample_timestamp` | 采样时间 | 用户录入/设备带出 | 日期时间选择器 | 可选;建议必填 |
| `sample_type` | 样本类型,如 tissue、DNA、seed、leaf | 用户选择 | 下拉框 | 可选;建议枚举化 |
| `taken_by` | 采样人 | 用户选择/登录用户带出 | 人员选择器/文本框 | 可选 |
| `tissue_type` | 组织类型,如 leaf、root、grain、stem | 用户选择/录入 | 下拉框/文本框 | 可选;样本为组织时建议填写 |
| `volume` | 样本体积,如 50 µL | 用户录入/仪器导入 | 数字+单位输入 | 可选;当前字段可暂存文本 |
| `well` | 孔位,如 A01、H12 | 孔位布局选择 | 孔位选择器 | 绑定 plate 时建议必填;同一 plate 内唯一 |
| `observation_unit_id` | 来源观测单元 | 从 observation_unit 选择或批量生成带出 | ObservationUnit 选择器 | 可选但强烈建议填写;必须存在 |
| `plate_id` | 所属样本板 | 从 plate 选择 | Plate 选择器 | 可选;若填写需校验孔位唯一 |
| `program_id` | 项目上下文 | 由 observation_unit/study 带出 | 只读/隐藏 | 可选但建议保存;需与 study 一致 |
| `study_id` | 所属 study | 由 observation_unit 带出 | Study 选择器/只读 | 可选但建议保存;若有 observation_unit 必须一致 |
| `taxon_id_id` | 分类单元 ID | 从 taxon 选择 | Taxon 选择器 | 可选 |
| `trial_id` | 所属 trial | 由 observation_unit/study 带出 | Trial 选择器/只读 | 可选但建议保存 |
### 录入建议
- 推荐从 observation_unit 批量生成 sample一行 observation_unit 生成一个或多个 sample。
- 如果样本放入 plate应通过孔位布局页设置 well不建议手填 A01。
- `well``plate_row``plate_column` 应保持一致well=A01则 row=Acolumn=1。
- sample 是物理样本,不是 genotype 结果;结果必须进入 callset / allele_call。
### 验收标准
1. `sample_name` 必填。
2. 同一 plate 中 `well` 不允许重复。
3. 绑定 observation_unit 时study/trial/program 自动带出。
4. 绑定 plate 时well 必须符合 plate_format。
5. 样本已有 callset 时,不允许物理删除。
---
## 6.3 reference_set 参考集
### 业务说明
`reference_set` 表示一个参考基因组集合,也就是一套 reference genome assembly。它定义 variant 坐标体系。不同参考基因组版本之间的位点坐标不可随意混用。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------------------- | ---------------------------------------------- | ------------------ | ----------------- | ---------------------------- |
| `id` | 参考集主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `assemblypui` | 参考组装永久标识,如 DOI、INSDC accession、URI | 用户录入/导入 | 文本框/URL 输入框 | 可选;建议唯一 |
| `description` | 参考集说明 | 用户录入 | 多行文本 | 可选 |
| `is_derived` | 是否由其他参考集派生 | 用户选择 | 开关 | 可选 |
| `md5checksum` | 参考集校验值 | 用户录入/文件计算 | 文本框 | 可选;若填写应符合 MD5 格式 |
| `reference_set_name` | 参考集名称,如 IRGSP-1.0、B73 RefGen_v5 | 用户录入 | 文本框 | 必填;建议唯一 |
| `sourceuri` | 参考集来源 URI 或下载地址 | 用户录入 | URL 输入框 | 可选;校验 URL |
| `species_ontology_term` | 物种本体术语名称 | 用户录入/选择 | 文本框/本体选择器 | 可选 |
| `species_ontology_termuri` | 物种本体 URI | 用户录入/本体带出 | URL 输入框 | 可选;校验 URL |
| `source_germplasm_id` | 参考基因组来源材料 | 从 germplasm 选择 | Germplasm 选择器 | 可选;必须引用存在 germplasm |
### 录入建议
- reference_set 是 variantset 和 variant 的上游,不能随意改。
- 如果导入 VCF必须先明确该 VCF 的 reference_set。
- 同一 crop 可能存在多个 reference_set应在页面上清楚显示版本和来源。
---
## 6.4 reference 参考序列
### 业务说明
`reference` 是 reference_set 中的一条参考序列,例如 chromosome、contig、scaffold。variant 的坐标通常是基于某条 reference 的位置。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------- | --------------------------------------------- | --------------------- | ------------------- | ------------------------------- |
| `id` | 参考序列主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `length` | 序列长度 | 用户录入/FASTA 导入 | 数字输入框 | 必填或建议必填;非负整数 |
| `md5checksum` | 单条 reference 的 MD5 校验值 | 用户录入/文件计算 | 文本框 | 可选;若填写应符合 MD5 格式 |
| `reference_name` | 参考序列名称,如 chr1、1、Chr01、scaffold_001 | 用户录入/FASTA 导入 | 文本框 | 必填;同一 reference_set 内唯一 |
| `source_divergence` | 与来源序列的差异程度 | 用户录入/导入 | 数字输入框 | 可选;范围建议 0-1 或按业务定义 |
| `reference_set_id` | 所属 reference_set | 从 reference_set 选择 | ReferenceSet 选择器 | 必选 |
### 录入建议
- 建议通过 FASTA 索引文件批量导入 chromosome / contig。
- 同一 reference_set 下 reference_name 必须唯一。
- variant 导入时,文件中的 CHROM 必须能匹配 reference.reference_name。
---
## 6.5 reference_bases 参考片段
### 业务说明
`reference_bases` 保存 reference 的序列片段或分页。通常不建议人工录入,而是由 FASTA 导入或接口生成。对于大型基因组,不建议把完整序列全部塞入普通业务表,除非系统确实需要序列查询。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------- | ------------------ | ------------------- | --------------------- | --------------------------------------- |
| `id` | 参考片段主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `bases` | 碱基序列片段 | FASTA 导入/接口生成 | 多行文本/只读 | 必填;只能包含合法碱基字符 A/C/G/T/N 等 |
| `page_number` | 分页编号 | 系统生成 | 数字输入/只读 | 必填;非负整数;同一 reference 下唯一 |
| `reference_id` | 所属 reference | 由导入带出 | Reference 选择器/隐藏 | 必选 |
### 录入建议
- 不建议前端做手工新增入口,只提供查看和导入。
- 每页 bases 长度应固定或可配置,例如 2KB、10KB、100KB。
- 导入时校验页码连续性和字符合法性。
---
## 6.6 variantset 变异集合
### 业务说明
`variantset` 是一批 variant 和相关 call 的集合,通常对应一个 VCF 文件、一个 SNP 芯片结果、一个测序分析批次或一个 study 的基因型数据集。它必须明确 reference_set否则 variant 坐标无意义。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------ | ---------------------------------------------- | --------------------- | ------------------- | ----------------------------------------- |
| `id` | 变异集合主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `variant_set_name` | 变异集合名称,如 Rice-2026-SNPSet、VCF-Run-001 | 用户录入/文件名带出 | 文本框 | 必填;建议唯一 |
| `reference_set_id` | 使用的参考集 | 从 reference_set 选择 | ReferenceSet 选择器 | 必选 |
| `study_id` | 关联 study | 从 study 选择 | Study 选择器 | 可选;若填写,应与样本来源 study 保持一致 |
### 录入建议
- 导入 VCF/CSV 前必须先选择 reference_set。
- 如果 variantset 来源于某次 study 的样本检测,应填写 study_id。
- variantset 详情页应展示variant 数量、callset 数量、分析信息、文件格式、导入状态。
---
## 6.7 variant 变异位点
### 业务说明
`variant` 表示一个遗传序列上的位点或区间,可以是 SNP、INDEL、SV也可以是传统 marker。它通常由 reference_set、reference_name、start/end、reference_bases、alternate_bases 共同定义。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------ | ------------------------------------ | ------------------------------------- | ------------------------ | ------------------------------------------------ |
| `id` | 变异主键 | 系统生成/导入 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `created` | 创建时间 | 系统默认/文件导入 | 日期时间只读 | 可选;默认当前时间 |
| `variant_end` | 变异结束位置 | 文件导入/用户录入 | 数字输入框 | 可选;非负整数;不小于 start |
| `filters_applied` | 是否执行过过滤 | 文件导入/系统写入 | 开关/只读 | 可选 |
| `filters_passed` | 是否通过过滤 | 文件导入/系统写入 | 开关/只读 | 可选 |
| `reference_bases` | 参考等位基因或参考碱基 | 文件导入/用户录入 | 文本框 | 可选;合法碱基字符 |
| `variant_start` | 变异起始位置 | 文件导入/用户录入 | 数字输入框 | 必填;非负整数 |
| `svlen` | 结构变异长度 | 文件导入/用户录入 | 数字输入框 | 可选SV 类型时建议填写 |
| `updated` | 更新时间 | 系统自动写入 | 只读日期时间 | 自动更新 |
| `variant_name` | 变异名称,如 SNP001、chr1_123456_A_G | 用户录入/自动生成 | 文本框 | 必填或由位置自动生成;同一 variantset 下建议唯一 |
| `variant_type` | 变异类型,如 SNP、INDEL、SV、marker | 用户选择/文件导入 | 下拉框 | 可选;建议枚举化 |
| `reference_set_id` | 所属参考集 | 从 reference_set 选择/variantset 带出 | ReferenceSet 选择器/隐藏 | 必选;需与 variantset.reference_set 一致 |
| `variant_set_id` | 所属变异集合 | 从 variantset 选择 | VariantSet 选择器/隐藏 | 必选 |
### 录入建议
- 大量 variant 应通过 VCF、HapMap、CSV 批量导入,不建议手工录入。
- 如果当前表缺少 alternate_bases、reference_name 字段,应在导入逻辑或扩展表中补齐,否则变异定义不完整。
- variant 的唯一性建议使用:`reference_set_id + reference_name + start + reference_bases + alternate_bases`
---
## 6.8 callset 调用集合
### 业务说明
`callset` 表示某个 sample 参与一次测序、芯片或分析事件后形成的一组 genotype calls。多数情况下一个 sample 对应一个 callset但如果同一个 sample 多次送检或使用不同分析流程,则可以有多个 callset。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------- | -------------------------------- | ----------------------- | ------------- | ---------------------------- |
| `id` | CallSet 主键 | 系统生成/导入 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `call_set_name` | 调用集合名称,如 SAMPLE-001_Run1 | 用户录入/系统生成 | 文本框 | 必填;同一 sample 下建议唯一 |
| `created` | 创建时间 | 系统默认/导入 | 日期时间 | 默认当前时间 |
| `updated` | 更新时间 | 系统自动写入 | 只读日期时间 | 自动更新 |
| `sample_id` | 所属样本 | 从 sample 选择/导入匹配 | Sample 选择器 | 必选 |
### 录入建议
- 从 genotype 文件导入时,可以按样本列自动创建 callset。
- callset 需要通过 `callset_variant_sets` 绑定它覆盖的 variantset。
- sample 详情页应展示 callset 列表和每个 callset 的 variantset、call 数量、导入时间。
---
## 6.9 callset_variant_sets 调用集合与变异集合关系
### 业务说明
`callset_variant_sets` 表示某个 callset 覆盖哪些 variantset。它是一次检测结果和一批位点集合之间的关系。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ----------------- | -------- | ------------------------------- | ---------------------- | -------- |
| `call_sets_id` | 调用集合 | 从 callset 选择/导入自动创建 | CallSet 选择器/隐藏 | 必选 |
| `variant_sets_id` | 变异集合 | 从 variantset 选择/导入自动绑定 | VariantSet 选择器/隐藏 | 必选 |
### 录入建议
- 从 variantset 导入 genotype matrix 时,系统应自动绑定所有新建 callset 到该 variantset。
- 同一 callset + variantset 不允许重复。
---
## 6.10 allele_call 基因型结果
### 业务说明
`allele_call` 是最终基因型事实数据,表示某个 callset 在某个 variant 上的 genotype 结果。它是 genotype matrix 的一个格子。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | --------------------------------------------------------- | ------------------------ | --------------------- | ------------------------------ |
| `id` | 基因型结果主键 | 系统生成/导入 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `genotype` | genotype 结果,如 A/G、0/1、0 | 1、AA、./. | 文件导入/少量手工修正 | 文本框/基因型控件 |
| `genotype_likelihood` | genotype likelihood表示不同 genotype 的可能性或置信信息 | 文件导入 | 数字输入框 | 可选;范围和含义按导入格式定义 |
| `phase_set` | phase set用于 phased genotype 分组 | 文件导入 | 文本框 | 可选phased 数据时使用 |
| `read_depth` | 测序深度 | 文件导入/用户录入 | 数字输入框 | 可选;非负整数 |
| `call_set_id` | 所属 callset | 从 callset 选择/导入匹配 | CallSet 选择器/隐藏 | 必选 |
| `variant_id` | 对应 variant | 从 variant 选择/导入匹配 | Variant 选择器/隐藏 | 必选 |
### 录入建议
- allele_call 不建议大量手工新增,主入口应该是 VCF/HapMap/CSV 文件导入。
- 同一 `call_set_id + variant_id` 不应重复。
- `genotype` 需要兼容常见格式:
- Allele 格式A/G、C/C、T/G
- VCF 编码0/0、0/1、1/1、0|1
- 缺失:./.、NA、N、--,具体缺失字符串由 variantset_format 配置。
- 导入后应支持按 sample/callset 或 variant 两种视角查询。
---
## 6.11 variantset_analysis 变异集合分析信息
### 业务说明
`variantset_analysis` 记录 variantset 的分析流程、软件、版本、参数、时间等信息。它是数据可追溯的重要来源。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ---------------- | ------------------------------------------------------------ | ------------------ | ---------------------- | -------------- |
| `id` | 分析记录主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `analysis_name` | 分析名称,如 GATK SNP Calling Run 2026-01 | 用户录入/导入带出 | 文本框 | 必填 |
| `created` | 创建时间 | 系统默认 | 日期时间 | 默认当前时间 |
| `description` | 分析说明,如软件版本、过滤参数 | 用户录入 | 多行文本 | 可选,建议填写 |
| `type` | 分析类型,如 SNP calling、imputation、filtering、chip genotyping | 用户选择/录入 | 下拉框/文本框 | 可选 |
| `updated` | 更新时间 | 系统自动写入 | 只读日期时间 | 自动更新 |
| `variant_set_id` | 所属 variantset | 从 variantset 选择 | VariantSet 选择器/隐藏 | 必选 |
### 录入建议
- 导入结果文件时,应生成或要求填写 analysis 信息。
- 推荐记录:软件名称、版本、参数、过滤阈值、执行人、执行日期。
---
## 6.12 variantset_format 变异集合文件格式
### 业务说明
`variantset_format` 描述 variantset 数据文件格式,例如 VCF、HapMap、CSV、TSV、DArTSeq 等。它影响 genotype 的解析方式、缺失值、phased/unphased 分隔符等。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------------- | --------------------------------------------- | ------------------- | ---------------------- | ------------------------ |
| `id` | 格式记录主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `data_format` | 数据内部结构,如 VCF、HapMap、DArTSeq、matrix | 用户选择/文件识别 | 下拉框 | 可选;建议枚举化 |
| `expand_homozygotes` | 是否展开纯合 genotype例如 A -> A/A | 用户选择 | 开关 | 可选 |
| `file_format` | 文件 MIME 或外层格式,如 csv、tsv、zip、excel | 用户选择/文件识别 | 下拉框 | 可选 |
| `fileurl` | 原始结果文件链接 | 上传后生成/用户填写 | URL 输入框 | 可选URL 格式校验 |
| `sep_phased` | phased genotype 分隔符,如 `|` | 用户录入/默认 | 文本框 | 可选;通常为 `|` |
| `sep_unphased` | unphased genotype 分隔符,如 `/` | 用户录入/默认 | 文本框 | 可选;通常为 `/` |
| `unknown_string` | 缺失值字符串,如 `./.`、NA、-- | 用户录入/默认 | 文本框 | 可选;导入时用于缺失识别 |
| `variant_set_id` | 所属 variantset | 从 variantset 选择 | VariantSet 选择器/隐藏 | 必选 |
### 录入建议
- 文件上传时应自动识别 file_format 和 data_format。
- 缺失值字符串必须参与 allele_call 导入解析。
- 如果格式是 VCF应支持 phased/unphased 分隔符。
---
## 6.13 genome_map 遗传图谱
### 业务说明
`genome_map` 描述遗传图谱或物理图谱。遗传图谱通常单位为 cM物理图谱通常单位为 Mb 或 bp。它用于把 variant / marker 映射到 linkage group 上。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------ | ------------------------------ | ------------------ | ----------------- | ------------------------------------------ |
| `id` | 图谱主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `comments` | 图谱备注 | 用户录入 | 多行文本 | 可选 |
| `documentationurl` | 图谱说明文档或论文链接 | 用户录入 | URL 输入框 | 可选URL 格式校验 |
| `map_name` | 图谱名称 | 用户录入 | 文本框 | 必填;建议唯一 |
| `mappui` | 图谱永久唯一标识 | 用户录入 | 文本框/URL 输入框 | 可选;若填写建议唯一 |
| `published_date` | 发布时间 | 用户录入 | 日期选择器 | 可选 |
| `scientific_name` | 物种学名 | 用户录入 | 文本框 | 可选 |
| `type` | 图谱类型,如 Genetic、Physical | 用户选择 | 下拉框 | 可选;建议枚举 |
| `unit` | 图谱单位,如 cM、Mb、bp | 用户选择 | 单位选择器 | 可选Genetic 常用 cMPhysical 常用 Mb/bp |
| `crop_id` | 所属作物 | 从 crop 选择 | Crop 选择器 | 必选 |
### 录入建议
- 图谱命名应能体现是 consensus map、mapping population map、reference genome map 还是 pan-genome map。
- 图谱类型和单位必须匹配Genetic + cMPhysical + Mb/bp。
---
## 6.14 linkage_group 连锁群
### 业务说明
`linkage_group` 是 genome_map 中的分组。它可能对应 chromosome、scaffold、contig 或传统遗传连锁群。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | -------------------------------------- | ------------------ | --------------------- | ---------------------------- |
| `id` | 连锁群主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `linkage_group_name` | 连锁群名称,如 Chr1、LG1、scaffold_001 | 用户录入/导入 | 文本框 | 必填;同一 genome_map 下唯一 |
| `max_marker_position` | 该连锁群最大 marker 位置 | 用户录入/导入计算 | 数字输入框 | 可选;非负数 |
| `genome_map_id` | 所属 genome_map | 从 genome_map 选择 | GenomeMap 选择器/隐藏 | 必选 |
### 录入建议
- 在 genome_map 详情页维护。
- 支持从 marker_position 文件批量导入时自动创建 linkage_group。
- 若填写 max_marker_positionmarker_position.position 不得超过该值。
---
## 6.15 marker_position 图谱位置
### 业务说明
`marker_position` 把 variant 映射到某个 linkage_group 上的位置。它用于遗传图谱定位、QTL、marker 辅助选择和图谱展示。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------ | --------------------------------- | --------------------- | ------------------- | ---------------------------------------- |
| `id` | 图谱位置主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `position` | variant 在 linkage_group 上的位置 | 用户录入/文件导入 | 数字输入框 | 必填;非负;不得超过 max_marker_position |
| `linkage_group_id` | 所属 linkage_group | 从 linkage_group 选择 | LinkageGroup 选择器 | 必选 |
| `variant_id` | 对应 variant | 从 variant 选择 | Variant 选择器 | 必选 |
### 录入建议
- 不建议逐条手工录入,优先通过 map 文件批量导入。
- 同一 genome_map 下,同一 variant 不应重复映射,除非业务允许多图谱位置。
---
# 7. 跨表联动规则
| 场景 | 联动规则 |
| ------------------------------- | ------------------------------------------------------------ |
| 从 observation_unit 生成 sample | 自动带出 study、trial、program可带出 germplasm 信息用于展示 |
| 给 sample 分配 plate | 选择 well 后自动生成 plate_row、plate_column |
| 创建 plate | 选择 study 后自动带出 trial/program |
| 创建 variantset | 必须先选择 reference_set |
| 导入 variant | variant.reference_set 必须与 variantset.reference_set 一致 |
| 创建 callset | 必须选择 sample可按 sample_name 自动生成 call_set_name |
| 导入 allele_call | 先匹配 callset再匹配 variant匹配不到时进入错误报告 |
| 绑定 callset_variant_sets | 导入 genotype matrix 时自动绑定 callset 与 variantset |
| 创建 genome_map | 必须选择 crop |
| 创建 marker_position | variant 与 linkage_group 最好来自同一 crop/reference 背景 |
---
# 8. 删除和停用规则
| 对象 | 删除限制 |
| --------------- | ------------------------------------------------------- |
| plate | 已有 sample 时不可删除 |
| sample | 已有 callset 时不可删除 |
| reference_set | 已有 reference、variantset、variant 时不可删除 |
| reference | 已有 reference_bases 或 variant 引用时不可删除 |
| variantset | 已有 variant、callset 绑定或 allele_call 结果时不可删除 |
| variant | 已有 allele_call 或 marker_position 时不可删除 |
| callset | 已有 allele_call 时不可删除 |
| allele_call | 原始检测结果原则上不建议物理删除,应支持作废或版本化 |
| genome_map | 已有 linkage_group 时不可删除 |
| linkage_group | 已有 marker_position 时不可删除 |
| marker_position | 可删除,但需记录操作日志 |
---
# 9. 批量导入要求
## 9.1 Sample 导入模板
必需列建议:
```text
sample_name
study_id 或 study_name
```
强烈建议列:
```text
observation_unit_id 或 observation_unit_name
sample_barcode
sample_type
tissue_type
sample_timestamp
taken_by
plate_name
well
```
导入规则:
1. 如果提供 observation_unit系统自动带出 study/trial/program。
2. 如果提供 plate + well需校验同板孔位唯一。
3. 如果 plate 不存在,可根据配置自动创建或报错。
## 9.2 Plate 导入模板
```text
plate_name
plate_barcode
plate_format
study_name
sample_name
well
```
导入规则:
1. plate_format 决定合法 well 范围。
2. 同一 plate + well 不允许重复。
3. sample_name 不存在时,可配置是否自动创建 sample。
## 9.3 Variant 导入模板
建议支持 VCF / HapMap / CSV。
CSV 必需列建议:
```text
variant_name
reference_name
variant_start
reference_bases
alternate_bases
variant_type
variant_set_name
reference_set_name
```
导入规则:
1. 必须先选择或创建 reference_set。
2. CHROM / reference_name 必须能匹配 reference。
3. variant_start 必须非负。
4. alternate_bases 不能为空,除非只是导入传统 marker。
## 9.4 Genotype Matrix / Allele Call 导入模板
推荐矩阵格式:
```text
variant_name,SAMPLE-001,SAMPLE-002,SAMPLE-003
SNP001,A/G,A/A,./.
SNP002,C/C,C/T,C/C
SNP003,T/G,T/T,T/G
```
导入规则:
1. 每个样本列必须能匹配 sample 或 callset。
2. 每个 variant 行必须能匹配 variant。
3. 每个非空 genotype 单元格生成一条 allele_call。
4. 缺失值按 variantset_format.unknown_string 处理。
5. 同一 callset + variant 已存在时,根据导入策略选择覆盖、跳过或报错。
## 9.5 Genome Map 导入模板
```text
map_name
linkage_group_name
variant_name
position
unit
```
导入规则:
1. map_name 不存在时可配置自动创建 genome_map。
2. linkage_group 不存在时可配置自动创建。
3. variant 必须存在。
4. position 必须非负且不超过 max_marker_position。
---
# 10. 后端接口建议
## 10.1 主数据接口
```text
GET /plates
POST /plates
GET /plates/{id}
PUT /plates/{id}
GET /plates/{id}/layout
POST /plates/{id}/assign-samples
GET /samples
POST /samples
POST /samples/batch-from-observation-units
GET /samples/{id}
PUT /samples/{id}
GET /samples/{id}/callsets
GET /reference-sets
POST /reference-sets
GET /reference-sets/{id}
GET /reference-sets/{id}/references
POST /reference-sets/{id}/references
GET /references
POST /references
GET /references/{id}/bases
POST /references/{id}/bases/import
GET /variantsets
POST /variantsets
GET /variantsets/{id}
GET /variantsets/{id}/variants
POST /variantsets/{id}/variants/import
GET /variantsets/{id}/formats
POST /variantsets/{id}/formats
GET /variantsets/{id}/analyses
POST /variantsets/{id}/analyses
GET /variants
POST /variants
GET /variants/{id}
GET /callsets
POST /callsets
GET /callsets/{id}
POST /callsets/{id}/variantsets
GET /allele-calls
POST /allele-calls/import
GET /allele-matrix
GET /genome-maps
POST /genome-maps
GET /genome-maps/{id}/linkage-groups
POST /genome-maps/{id}/linkage-groups
POST /marker-positions/import
```
## 10.2 选择器接口
```text
GET /selectors/plates?studyId=&keyword=
GET /selectors/samples?studyId=&plateId=&keyword=
GET /selectors/reference-sets?cropId=&keyword=
GET /selectors/references?referenceSetId=&keyword=
GET /selectors/variantsets?referenceSetId=&studyId=&keyword=
GET /selectors/variants?variantSetId=&referenceName=&start=&end=&keyword=
GET /selectors/callsets?sampleId=&variantSetId=&keyword=
GET /selectors/genome-maps?cropId=&keyword=
GET /selectors/linkage-groups?genomeMapId=&keyword=
```
---
# 11. 测试验收清单
1. 创建 plate 时plate_name 和 plate_barcode 至少填写一个。
2. plate_barcode 重复时提示唯一性冲突。
3. plate_format=96 时,只允许 A01-H12plate_format=384 时,只允许 A01-P24。
4. sample_name 必填。
5. sample 绑定 plate 时,同一 plate + well 不允许重复。
6. sample 绑定 observation_unit 后study/trial/program 自动带出。
7. reference_set_name 必填。
8. reference_name 在同一 reference_set 内不允许重复。
9. reference.length 必须为非负整数。
10. reference_bases.bases 只能包含合法碱基字符。
11. variantset 必须选择 reference_set。
12. variant.reference_set_id 必须与 variantset.reference_set_id 一致。
13. variant_start 必须非负。
14. variant_end 不得小于 variant_start。
15. variant_name 为空时系统能按 reference + position + allele 自动生成。
16. callset 必须绑定 sample。
17. 同一 sample 下 call_set_name 不建议重复。
18. callset + variantset 关系不允许重复。
19. allele_call 必须绑定 callset 和 variant。
20. 同一 callset + variant 不允许重复,除非系统支持版本化。
21. read_depth 必须为非负整数。
22. genotype 必须符合导入格式规则。
23. 缺失 genotype 必须按 unknown_string 统一处理。
24. 导入 genotype matrix 时,无法匹配的 sample、variant 必须返回错误报告。
25. 导入失败报告必须包含行号、列名、错误原因、建议修复方式。
26. genome_map 必须选择 crop。
27. linkage_group_name 在同一 genome_map 内不允许重复。
28. marker_position.position 必须非负,且不超过 max_marker_position。
29. 已有关联下游数据的 sample、variant、callset、variantset 不允许物理删除。
30. 所有导入操作必须记录导入批次、上传人、上传时间和原始文件链接。
---
# 12. 开发实现重点
1. `sample` 是物理样本,不是基因型结果。
2. `callset` 是 sample 参与一次检测/分析形成的结果集合。
3. `allele_call` 才是某个 sample/callset 在某个 variant 上的 genotype 结果。
4. `variantset` 必须绑定 reference_set否则位点坐标没有意义。
5. 大量 variant 和 allele_call 不应手工录入,主入口必须是文件导入。
6. plate 必须做孔位布局,不要只做普通表单。
7. genotype matrix 页面必须支持按 sample 和按 variant 两种方向查看。
8. VCF/HapMap/CSV 的解析规则要独立成导入服务,不要散落在页面逻辑里。
9. reference_set、variantset、callset、analysis、format 都是结果可追溯的关键上下文。
10. 已导入的基因型结果建议支持版本化或作废,不建议直接物理删除。