# 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-H12；384 时只允许 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=A，column=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 常用 cM，Physical 常用 Mb/bp |
| `crop_id`          | 所属作物                       | 从 crop 选择       | Crop 选择器       | 必选                                       |

### 录入建议

- 图谱命名应能体现是 consensus map、mapping population map、reference genome map 还是 pan-genome map。
- 图谱类型和单位必须匹配：Genetic + cM，Physical + 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_position，marker_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-H12；plate_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. 已导入的基因型结果建议支持版本化或作废，不建议直接物理删除。

