## Context `docs/sql/zkxw.sql`(全库导出基线)已包含 `biz_customer`、`biz_cell_sample_type`、`biz_collection_region`、`biz_collection_hospital`、`biz_collection_protocol_no`、`biz_sample_code` 等表;需求文档 `docs/中科兴皖需求V0.3.md` 2.2.1~2.2.5 描述了字段与交互。后端 `app/models` 与路由中尚未覆盖上述业务主数据的完整 CRUD;Web 管理端缺少对应页面。 **与需求文档的差异(以 DDL 为准)**:2.2.3 文案提到「医院名称逗号分隔」;当前 schema 为地区表 + 医院子表 1:N,实现 SHALL 以子表为准,弹窗内维护医院行,避免双写。 **现有代码模式参考:** - 后端:`openspec/changes/dict-management` 与 `crud/tenant.py` 类独立函数、`api/admin.py` 路由风格;租户 `tenant_no`、软删 `del_flag`、列表默认排序 `create_time DESC`(见 engineering-standards)。 - 前端:标准列表 `views/system/unit/index.vue`;复杂子表弹窗可参考字典「字典数据配置」或订单模块弹窗;API 封装于 `src/api/*.ts`。 ## Goals / Non-Goals **Goals:** - 五类主数据在租户范围内的分页列表、详情(可选)、创建、更新、软删除。 - 客户身份证去重(同租户、非空身份证、未删除记录唯一);样本类型编码、协议号、样本编码在租户内唯一。 - 地区与医院:主列表为地区;「地区医院配置」弹窗内对 `biz_collection_hospital` 增删改查(按 `region_id`)。 - Web UI 符合 `docs/web-admin-ui-spec-fresh-mint.md` 与 `.cursor/rules/web-admin-crud-dialog.mdc`。 - 菜单与权限 SQL 或初始化说明写入 `docs/sql/`(与仓库惯例一致)。 **Non-Goals:** - `biz_customer_follow` 客户随访(2.2.1 未在本次菜单范围单独展开时可列为后续)。 - 小程序端维护上述主数据。 - 协议号/样本编码的「下发」与下游业务流程联动(仅维护 `issued` 字段与展示)。 - 批量导入导出、复杂审批流。 ## Decisions ### D1: 后端路由组织 **选择**:新增独立路由模块(例如 `app/api/basic_info.py` 或按域拆分为 `customer.py` + 聚合少量路由的文件),在 `app/api/__init__.py` 与 `app/main.py` 注册;路径前缀与现有 `/api` + admin 子前缀保持一致(如 `/web/admin/...` 或与 `dict` 同级命名空间)。 **理由**:五组资源边界清晰,避免单个 `admin.py` 过度膨胀;仍属同一业务域「基础信息」。 **替代方案**:全部写入 `admin.py` → 可行但不利于评审与合并冲突控制。 ### D2: SQLAlchemy 模型与 CRUD **选择**:在 `app/models/models.py`(或按项目惯例的拆分文件)增加与 DDL 一致的 ORM 模型;`app/crud/` 下每域独立模块或 `basic_info` 包内多文件,函数命名 `list_*`、`get_*`、`create_*`、`update_*`、`soft_delete_*`。 **理由**:与现有 tenant、dict 等模式一致,满足 database-conventions 公共字段与软删查询约定。 ### D3: 客户身份证唯一校验 **选择**:创建与更新时若 `id_card_no` 非空,则查询同租户下是否存在其他未删除记录占用相同证件号;存在则返回 4xx 与明确业务文案(与需求「不要重复创建…提醒」一致)。 **理由**:表上已有 `idx_customer_idcard`;应用层给出可读错误信息。 ### D4: 前端信息架构 **选择**:五个菜单入口(或二级菜单「基础信息」下五项),每页一个标准列表 + 表单弹窗;地区页主表 + 「地区医院配置」子弹窗(内嵌表格 + 分页)。 **理由**:与需求操作描述及工程 UI 模板一致。 ### D5: 初始化数据(样本类型) **选择**:可选 SQL 种子插入三种需求既定编码(wcqzxgxb、qdjczgxb、tpyqngxb),若环境已手动录入则脚本需幂等(`INSERT IGNORE` 或先判存)。 **理由**:需求 2.2.2 明确当前三种类型。 ## Risks / Trade-offs - **[需求与 DDL 不一致]**:2.2.3 逗号分隔 vs 子表 → **缓解**:以 DDL 为准,在 proposal/design 中写明,避免实现回退到反范式存储。 - **[唯一索引与软删]**:`uk_sample_type` 等包含 `del_flag` → 删除后再建同编码可能冲突 → **缓解**:软删后「复活」走更新 `del_flag=0` 或换编码;接口文档说明。 - **[权限与菜单遗漏]** → **缓解**:tasks 中单列菜单 SQL 与路由权限码登记。 ## Migration Plan - 无破坏性 schema 变更前提:部署顺序为 DB 已执行 V0.3 DDL → 后端 → 前端;回滚为下线路由与菜单,不物理删数据。 - 若某环境缺表:以 `docs/sql/zkxw.sql` 为基线导入/对齐,或从其中摘取对应 `CREATE TABLE` 段落执行。 ## Open Questions - Web 菜单父级挂载在「Demo」下还是正式「业务/基础信息」根节点:建议与产品确认后写入 `docs/sql` 初始化脚本。 - `biz_customer_follow` 是否与本迭代一并提供只读/编辑入口:默认本变更 Non-Goal,若需可追加 capability。