修复演示恢复默认模板覆盖逻辑

- 新增后端默认模板服务,集中维护腹腔镜胆囊切除术和头颈部CT分割的权威分类树、颜色、maskid 和层级定义。

- 演示恢复出厂设置时强制恢复系统默认模板,缺失模板会重建,已修改或删减的默认语义分类树会覆盖回默认状态。

- 清理 main.py 中重复的默认模板定义,让启动 seed 复用同一套服务逻辑,避免后续默认模板定义漂移。

- 扩展管理员恢复出厂设置测试,覆盖头颈部CT模板被改坏和腹腔镜模板缺失后的恢复结果。

- 更新 AGENTS、README 和需求/API/测试/前端审计文档,明确恢复出厂设置会权威恢复系统默认模板。
This commit is contained in:
2026-05-03 17:54:19 +08:00
parent 7f8722410c
commit cadacef04d
10 changed files with 185 additions and 129 deletions

View File

@@ -184,7 +184,27 @@ def test_demo_factory_reset_leaves_admin_and_parsed_demo_dicom(client, db_sessio
assert db_session.query(ProcessingTask).count() == 0
assert db_session.query(Template).filter(Template.owner_user_id.is_not(None)).count() == 0
preserved_templates = db_session.query(Template).filter(Template.owner_user_id.is_(None)).all()
assert [template.name for template in preserved_templates] == ["头颈部CT分割"]
templates_by_name = {template.name: template for template in preserved_templates}
assert set(templates_by_name) == {"腹腔镜胆囊切除术", "头颈部CT分割"}
head_neck_classes = templates_by_name["头颈部CT分割"].mapping_rules["classes"]
lap_classes = templates_by_name["腹腔镜胆囊切除术"].mapping_rules["classes"]
assert [item["name"] for item in head_neck_classes] == [
"肿瘤/结节 (Tumor/Nodule)",
"下颌骨 (Mandible)",
"甲状腺 (Thyroid)",
"气管 (Trachea)",
"颈椎 (Cervical Spine)",
"颈动脉 (Carotid Artery)",
"颈静脉 (Jugular Vein)",
"腮腺 (Parotid Gland)",
"下颌下腺 (Submandibular Gland)",
"舌骨 (Hyoid Bone)",
"待分类",
]
assert [item["maskId"] for item in head_neck_classes] == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]
assert len(lap_classes) == 36
assert lap_classes[-1]["name"] == "待分类"
assert lap_classes[-1]["maskId"] == 0
assert db_session.query(AuditLog).count() == 1
assert db_session.query(AuditLog).first().action == "admin.demo_factory_reset"