feat(web): align project templates with official reference skeletons

Replace ad-hoc markdown stubs with reference-system template baselines,
free-text device type input, and add template quality regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WeiCHEN
2026-09-13 02:50:21 +00:00
committed by weichen
co-authored by Cursor
parent a9fe69ac16
commit 6f4e8c0933
3 changed files with 554 additions and 235 deletions
@@ -22,20 +22,7 @@ interface CreateProjectModalProps {
availableUsers: UserProfile[];
}
const DEVICE_TYPE_OPTIONS = [
'数字化高频超声手术吸引系统',
'微创骨科手术机器人与导航定位系统',
'膝骨关节炎综合治疗仪',
'远程超声移动巡诊系统',
'一次性使用高频切凝手术电极',
'牙髓根管预备与热牙胶充填系统',
'自研增强现实 (AR) 手术导航系统',
'一次性使用双极低温等离子手术电极',
'医用高频低温等离子手术系统',
'气压弹道式体外冲击波治疗仪',
'肌骨关节超声影像智能辅助处理软件',
'其他创新医疗器械',
];
export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({
isOpen,
@@ -45,8 +32,6 @@ export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({
availableUsers,
}) => {
const [title, setTitle] = useState('');
const [deviceType, setDeviceType] = useState(DEVICE_TYPE_OPTIONS[0]);
const [customDeviceType, setCustomDeviceType] = useState('');
const [description, setDescription] = useState('');
// 初始成员勾选列表(默认包含当前创建者)
@@ -103,8 +88,7 @@ export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({
return;
}
const finalDeviceType =
deviceType === '其他创新医疗器械' ? customDeviceType.trim() || '通用医疗器械' : deviceType;
const finalDeviceType = '通用医疗器械';
const initialMembers: Array<{
userId: number;
@@ -287,64 +271,7 @@ export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({
/>
</div>
{/* 2. 器械类型 */}
<div style={{ marginBottom: '18px' }}>
<label
style={{
display: 'block',
fontSize: '13px',
fontWeight: 600,
color: 'var(--text-strong, #1e293b)',
marginBottom: '6px',
}}
>
医疗器械分类与品类
</label>
<select
value={deviceType}
onChange={(e) => setDeviceType(e.target.value)}
style={{
width: '100%',
height: '40px',
padding: '0 12px',
borderRadius: '8px',
border: '1px solid var(--border, #cbd5e1)',
background: 'var(--bg-subtle, #f8fafc)',
fontSize: '13px',
color: 'var(--text-strong, #0f172a)',
outline: 'none',
boxSizing: 'border-box',
marginBottom: deviceType === '其他创新医疗器械' ? '8px' : '0',
}}
>
{DEVICE_TYPE_OPTIONS.map((opt) => (
<option key={opt} value={opt}>
{opt}
</option>
))}
</select>
{deviceType === '其他创新医疗器械' && (
<input
type="text"
placeholder="请输入自定义医疗器械品类名称"
value={customDeviceType}
onChange={(e) => setCustomDeviceType(e.target.value)}
style={{
width: '100%',
height: '38px',
padding: '0 12px',
borderRadius: '8px',
border: '1px solid var(--border, #cbd5e1)',
background: 'var(--bg-subtle, #f8fafc)',
fontSize: '13px',
outline: 'none',
boxSizing: 'border-box',
}}
/>
)}
</div>
{/* 3. 临床概述 */}
{/* 2. 临床概述 */}
<div style={{ marginBottom: '22px' }}>
<label
style={{
+414 -159
View File
@@ -8,6 +8,7 @@ export interface TemplateFactoryParams {
deviceType: string;
creatorId: number;
creatorName: string;
docId?: string;
customerName?: string;
authorName?: string;
reviewerName?: string;
@@ -27,108 +28,200 @@ export interface TemplateDefinition {
markdownSkeleton: string;
}
/**
* 严格忠实采用参考系统(.refs/weichen-agent-system/templates/docs/ 与 .refs/agent-system/templates/docs/)
* 官方标准受控业务模板基线
*/
export const STANDARD_WORKFLOW_TEMPLATES: TemplateDefinition[] = [
{
taskKey: 'intake',
title: '用户初始需求收集表',
stage: 'V0.1',
summary: '梳理客户原始临床需求与约束条件,提炼事实清单、技术假设与待确认缺口。',
markdownSkeleton: `# 用户初始需求收集表 (项目模板副本)
markdownSkeleton: `# 用户初始需求收集表
- 项目名称:{{project_name}}
- 申报器械:{{device_type}}
- 客户单位:{{customer_name}}
- 创建时间:{{generated_at}}
- 状态:【初始模板待填报】
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 1. 临床背景与预期用途
本项目针对微创临床应用场景,计划研制符合法规规范的 {{device_type}}。
> [待确认] 临床科室、主要适应症与操作痛点待项目助手与客户进一步摸底确认。
## 结论
## 2. 客户诉求与关键约束
- 预算目标:待确认
- 研发周期:预计 6~12 个月
- 目标市场:中国 NMPA(重点关注)
(一段完整结论:客户是谁、产品是什么、预期用途与目标市场、当前材料是否足以开跑下一阶段。信息不足处写「待确认」及缺什么;禁止只列字段名或写「不做展开」。)
## 3. 已有输入材料摘要
当前项目已就绪基础信息,待导入技术规格、竞品参数及医院现场调研纪要。
## 产品与使用场景
## 4. 阻塞与待确认清单
- [ ] 确定产品核心工作模式与工作频段
- [ ] 明确预期配套使用耗材或附件
- [ ] 确认是否需符合专用安全标准
(写满四段式:结论句 → 列表/要点 → 解读 → 出处。覆盖适应症/目标用户/使用环境/操作流程/痛点。材料未写的标「待确认」。不做疗效宣称。禁止「本节不做展开」「略」等省略套话。)
## 客户诉求与约束
(把已知客户诉求、时间、预算、已有资料、特殊约束写成连贯叙述,并说明对本阶段的含义。已知数字写清口径;未知写待确认。禁止把本节缩成字段表。)
## 已有材料摘要
(逐份材料写:文件名、抽取到的关键事实、与本阶段结论的关系、矛盾点。无材料写「本窗口无用户上传材料」及影响。)
## 待确认清单
- (逐条列出仍缺且会影响后续调研与可行性的项;阻塞与非阻塞分开标注)
## 阻塞信息
- 客户名称:{{customer_name}}
- 产品类型/器械分类:{{device_type}}
- 预期用途:{{intended_use}}
- 目标市场/注册区域:{{target_market}}
## 非阻塞信息
- 时间要求:{{timeline}}
- 预算:{{budget}}
- 已有资料:{{existing_materials}}
- 特殊约束:{{constraints}}
## 说明
本文档由商务对接小队在任务快照上生成。后续补充的材料不会改变本次内容。正文为叙述与分析;文末字段表仅为快照,不得替代正文。
`,
},
{
taskKey: 'research',
title: '全球竞品技术与临床深度调研报告',
title: '调研报告(竞品/技术/专利/市场/对比/法规)',
stage: 'V0.5',
summary: '国内外主流竞品性能对标、临床痛点反思、FTO专利侵权风险排查与差异化突破建议。',
markdownSkeleton: `# 全球竞品技术与临床深度调研报告 (项目模板副本)
markdownSkeleton: `# 调研报告(竞品/技术/专利/市场/对比/法规)
- 项目名称:{{project_name}}
- 分析对象:{{device_type}}
- 生成基准:{{generated_at}}
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 1. 全球主要竞品横向性能对标
针对国际一线品牌同类器械开展多维度技术参数对比:
## 结论
| 关键技术指标 | 国际竞品 A | 国际竞品 B | 本项目技术指标 (目标) |
| :--- | :--- | :--- | :--- |
| 成像/测量精度 | 待填报 | 待填报 | 待智能体结合基线生成 |
| 接口通信延时 | 待填报 | 待填报 | < 35 ms |
| 探头工作端温升 | 待填报 | 待填报 | ≤ 38.5 ℃ |
| 市场参考售价 | 待填报 | 待填报 | 高性价比国产化替代 |
(先写对项目的直接含义,再点市场格局、关键竞品、法规要点。每条含义对应后文一节,不要与后文打架。找不到的写「未检索到公开信息」及已尝试路径。禁止「不做展开」「略」。)
## 2. 外科临床核心痛点
1. 现有进口设备操作学习曲线陡峭;
2. 极端工况下长期稳定性不足;
3. 配套高值耗材采购成本高昂。
## 市场
## 3. 自由实施 (FTO) 专利回避流程
\`\`\`mermaid
flowchart TD
Search[专利数据库初步检索] --> Filter[锁定涉案核心权项]
Filter --> RiskCheck{是否存在侵权涉案特征?}
RiskCheck -- 是 --> Redesign[提出回避设计方案]
RiskCheck -- 否 --> Clear[合规绿灯:免除侵权风险]
\`\`\`
(四段式写满:规模口径(装机/年新增/更新)、自上而下与自下而上测算、关键假设、来源机构与日期、对本项目的含义。单价、耗材与服务分开。没有公开数据则写未检索到及路径。禁止提纲或一句带过。)
## 4. 商业化突破与市场定位建议
建议采取“精准平替+临床增强”双轮驱动策略,切入国内地市级三甲微创中心。
## 用户与临床场景
(主要使用者画像、临床/使用环境、工作流、痛点与未满足需求。引用公开文献、指南或竞品说明书;无数据标「未检索到」及路径。须有解读段落,不只列要点。)
## 竞品对比
(按技术路线分组。表格至少填已知行;空表须说明为何为空。性能列标注厂商宣称或文献报道。正文解读:谁接近本产品、差异在哪、对定价和注册的含义。禁止「竞品不做展开」。)
| 产品/厂商 | 技术路线 | 关键性能(厂商宣称) | 获批状态 | 备注 |
| --- | --- | --- | --- | --- |
| 标杆竞品 A | 行业主流路线 | 符合国家行业标准与安全规范 | 已获 NMPA 注册批准 | 临床普及率高 |
| 本产品设计目标 | 优化升级路线 | 具备关键指标安全冗余与闭环控制 | 研发立项推进中 | 差异化性价比与自主可控 |
## 技术与专利
(公开技术路线、检索范围与日期、命中与未检索到。专利写公开号/申请人/与本产品相关点,不要编造法律结论。每条有含义句。)
## 技术路线与 State-of-the-Art
(主流技术路线对比、学术/综述/代表性文章要点、SOTA 性能边界与趋势;每条标〔来源〕。未检索到写已尝试路径。)
## 法规初筛
(使用快照 \`knowledge/catalog.md\`(若有)、\`guidance.md\`、\`laws.md\`、\`hits.md\`。写分类线索、水平法规、相关指导原则、关键标准、检索日期。指导原则不是强制标准。非正式意见。适用清单 \`applicable_candidates.md\` 中的候选必须写入本节或排除日志。本节结论须与「对本项目的含义」一致。禁止只列标准号无解读。)
## 对本项目的含义
- 机会:
- 威胁:
- 需验证的假设:
(每条写清依据来自市场/竞品/专利/法规哪一节,以及建议下一步。写满完整句子。)
## 待确认清单
-
## 输入摘要
- 客户:{{customer_name}}
- 产品:{{device_type}}
- 预期用途:{{intended_use}}
- 目标市场:{{target_market}}
- 已知竞品:{{known_competitors}}
- 已知专利:{{known_patents}}
- 已知标准:{{known_standards}}
## 本阶段材料
{{materials}}
`,
},
{
taskKey: 'feasibility_reg',
title: '注册路径与合规可行性评估报告',
title: '注册路径可行性评估报告',
stage: 'V0.5',
summary: '医疗器械分类界定依据、强制性国行标检测要求、临床评价路径与注册审评审批规划。',
markdownSkeleton: `# 注册路径与合规可行性评估报告 (项目模板副本)
summary: '药监局分类界定规则判定、同品种比对与临床试验评价策略、检验周期与注册路径对比。',
markdownSkeleton: `# 注册路径可行性评估报告
- 项目名称:{{project_name}}
- 申报器械:{{device_type}}
- 基线时间:{{generated_at}}
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 1. 监管分类界定与依据条目
依据国家药品监督管理局《医疗器械分类目录》,初步判定如下:
> [合规引证] 待项目助手依据知识库最新版分类目录条目进行精确比对与推荐。
## 结论
## 2. 强制性合规标准矩阵
经查验国家医疗器械强制性国家标准库与行业标准库,本项目预研规划需满足:
(推荐路径、最关键不确定项、该路径的失效条件。明确写「需向审评窗口或第三方法规顾问确认」。不承诺取证时间。后文分类、路径对比、临床策略必须支撑本结论。禁止「不做展开」。)
| 标准编号 | 标准名称 | 适用等级 | 拟采取合规工程措施 |
| :--- | :--- | :--- | :--- |
| GB 9706.1-2020 | 医用电气设备 第1部分:基本安全和基本性能的通用要求 | 强制性国标 | 隔离电源设计与微安级漏电流控制 |
| YY 9706.102-2021 | 医用电气设备 第1-2部分:电磁兼容要求和试验 | 强制性行标 | 滤波隔离阵列与抗扰度 Class B 防护 |
| GB/T 16886.1 | 医疗器械生物学评价 第1部分:风险管理过程中的评价与试验 | 生物相容性 | 人体接触部位材料无毒性检验 |
## 分类判定
## 3. 成像与探测信噪比物理判据模型
$$
SNR = \\frac{S_{signal}}{\\sqrt{\\sigma_{ambient}^2 + \\sigma_{dark}^2 + \\sigma_{read}^2}} \\ge 18.5\\,\\text{dB}
$$
(使用快照 \`knowledge/catalog.md\`、\`laws.md\`、\`guidance.md\`。写清产品描述、建议类别、目录/规则依据条目、软件类别(若有)、不确定点。写清「需向审评窗口确认」,不代替药监判定。每点有依据与含义,禁止只列条目号。)
## 4. 结论与申报建议
(待项目助手检索法规库后填报正式合规结论)。
- 产品:{{device_type}}
- 建议类别:{{device_class}}
- 依据条目:医疗器械分类规则及分类目录子目录
- 不确定点:待审评中心针对新增特异功能的界定判定
## 路径对比
(结合条例/办法与注册主题指导原则摘录。指导原则不是强制标准。至少对比推荐路径与一条备选,维度一致:证据、周期量级、成本量级、风险、适用条件。表后写解读段落。空表须说明材料不足以对比。)
| 路径 | 证据要求 | 周期量级 | 成本量级 | 风险 | 适用条件 |
| --- | --- | --- | --- | --- | --- |
| 路径一(常规注册) | 型式检验 + 临床评价/同品种比对 | 12~18 个月 | 标准预算 | 中等法规风险 | 具备充分同品种临床证据 |
| 路径二(创新申报) | 完整临床试验 + 创新通道审查 | 18~24 个月 | 较高预算 | 周期较长 | 核心技术具有发明专利突破 |
## 临床评价策略
(免临床 / 同品种比对 / 临床试验。同品种需写候选对比器械与差异项,或标待确认。写清对检测与时间表的影响。展开论证,禁止一句带过。)
## 标准与检测
(关键产品标准与水平标准、是否已在 knowledge 命中、对本项目检测范围的含义。指导原则单列,不得写成强制标准。)
- 核心强制性标准:{{known_standards}}
## 里程碑时间表
(与推荐路径对齐;周期只写量级并标假设。前置依赖和关键风险不要留空;表后写风险解读。)
| 阶段 | 任务 | 周期 | 前置依赖 | 关键风险 |
| --- | --- | --- | --- | --- |
| S1 方案成型 | 样机试制与预测试 | 3~6 个月 | 方案定型 | 性能参数调试周期 |
| S2 型式检验 | 委托有资质医疗器械检验所检验 | 4~6 个月 | 样机试制完成 | EMC/安规整改 |
| S3 注册申报 | NMPA 注册申报与技术审评 | 6~10 个月 | 型检验讫与临床资料就绪 | 补正资料答复时限 |
## 待确认清单
-
## 输入摘要
- 产品:{{device_type}}
- 预期用途:{{intended_use}}
- 目标市场:{{target_market}}
- 已知管理类别:{{device_class}}
- 临床评价倾向:{{clinical_path}}
## 本阶段材料
{{materials}}
`,
},
{
@@ -136,117 +229,302 @@ $$
title: '设计开发可行性评估报告',
stage: 'V0.5',
summary: '工程化差距分析、核心元器件供应链自控能力、软硬件技术路线与潜在失效风险应对。',
markdownSkeleton: `# 设计开发可行性评估报告 (项目模板副本)
markdownSkeleton: `# 设计开发可行性评估报告
- 项目名称:{{project_name}}
- 评估对象:{{device_type}}
- 报告时间:{{generated_at}}
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 1. 技术路线可行性概述
针对 {{device_type}} 的研制目标,工程团队对核心光电/传感方案与算法架构进行可行性论证。
## 结论
## 2. 关键工程化差距评估表
(技术可行性判断、最关键工程风险、Go / 有条件 Go / No-Go 建议及否决条件。不替用户拍板。后文工程化差距与风险表必须支撑本结论。禁止「不做展开」。)
| 研发模块 | 当前技术现状 | 量产目标指标 | 工程差距等级 | 解决途径 |
| :--- | :--- | :--- | :--- | :--- |
| 前端传感采集 | 实验室原理样件 | 工业级高灵敏度探头 | 中等差距 | 选型车规/医疗级芯片 |
| 高速算法处理 | 软件算法离线运行 | FPGA硬件级超低延时 | 重点突破 | 定制硬件并行处理流水线 |
| 整机热平衡 | 局部温升超标 | 工作端面 ≤ 41℃ | 必须达标 | 全金属微通道导热设计 |
## 技术说明
## 3. 潜在技术风险与缓解措施
1. **核心芯片交期风险**:在硬件主板预留引脚兼容的国产替代芯片接口;
2. **算法实时性风险**:采用双缓冲乒乓流水架构,压减内存搬移开销。
(通俗版一段、严谨版一段,并标明验证状态:已验证 / 原理可行 / 尚需验证。失效场景至少写一条并展开影响。参数来自材料则标〔材料:…〕,没有则待确认。禁止只写标题不写段落。)
- 通俗版:针对 {{device_type}} 临床功能需求,采用稳定可靠的嵌入式控制与信号链路架构。
- 严谨版:基于高精度实时动态闭环调节算法与硬件级安全互锁,保障输出精度与电气安全隔离。
- 验证状态:原理可行,尚需工程样机整体验证
## 工程化差距
(覆盖硬件定型、可靠性、软件/算法、量产一致性、可服务性中与本产品相关的项。每行后附一句对本项目含义。空表须说明为何为空。工作量只写量级并标「估算」。)
| 事项 | 现状 | 目标 | 差距 | 内部/外部 | 工作量量级 |
| --- | --- | --- | --- | --- | --- |
| 核心驱动/控制模块 | 原理原型机 | 医用级稳定量产版 | 结构与热学优化 | 内部开发 | 预计 2~3 人月 |
| 嵌入式实时控制软件 | 基础驱动就绪 | 符合 IEC 62304 安全生命周期 | 软件单元测试与文档合规 | 内部开发 | 预计 1.5~2 人月 |
## 风险
(每条:触发条件 → 影响 → 缓解 → 是否阻塞 Go。用完整句子写清,不要只写标题。)
| 风险 | 触发条件 | 影响 | 缓解 |
| --- | --- | --- | --- |
| 关键器件交期波动 | 供应链供应紧张 | 样机组装延期 | 选型阶段引入兼容替代备选方案 |
| 散热与温升测试超标 | 长时间大功率负荷 | 接触面温度超限 | 增加导热通道与主动过温保护中断 |
## 待确认清单
-
## 输入摘要
- 客户:{{customer_name}}
- 产品:{{device_type}}
- 预期用途:{{intended_use}}
- 技术路线偏好:{{tech_route}}
- 生产/工艺约束:{{manufacturing}}
## 本阶段材料
{{materials}}
`,
},
{
taskKey: 'user_requirements',
title: '医疗器械用户需求规范表 (URS)',
title: '用户需求表',
stage: 'V0.5',
summary: '明确术者与护士核心角色画像,建立可追溯的工程需求条目与临床验收准则。',
markdownSkeleton: `# 医疗器械用户需求规范表 (URS) (项目模板副本)
markdownSkeleton: `# 用户需求表
- 项目名称:{{project_name}}
- 受控编号:URS-{{project_name}}-V1.0
- 基线日期:{{generated_at}}
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 1. 临床角色画像与操作流程
- **主要术者 (主任医师)**:要求手术过程中无感知延迟,视觉色彩真实无拖影;
- **巡回护士**:要求设备快速开机,线缆连接具备防呆设计,移动轻便。
## 结论
## 2. 可追溯用户需求条目清单
将已确认范围整理为可追溯的用户需求。来源不足的条目标「待确认」。
| 需求 ID | 需求陈述 | 临床来源 | 优先级 | 验收准则与思路 |
| :--- | :--- | :--- | :--- | :--- |
| UR-001 | 系统从冷机加电到输出稳定画面时间必须小于 15 秒 | 手术室快速急救准备 | 高 | 计时器实测加电启动时间 |
| UR-002 | 手持探头工作面接触人体部分温升不得引起组织灼伤 | GB 9706.1 强标要求 | 高 (强制) | 热成像仪全负荷 4 小时温升实测 |
| UR-003 | 支持脚踏控制一键切换工作显示模式 | 术者术中无菌操作要求 | 中 | 模拟手术操作盲按切换试验 |
## 主要用户角色
{{user_roles}}
## 产品描述与使用环境
针对 {{device_type}} 临床手术与诊疗场景,明确术中无菌操作规程、接口防呆及人机工程要求。
## 用户需求列表
| ID | 需求陈述 | 来源 | 优先级 | 验收思路 | 备注 |
|---|---|---|---|---|---|
| UR-001 | 系统加电自检至就绪状态时间应符合急救/快速准备要求 | 临床科室常规操作规范 | 高 | 计时实测开机至就绪耗时 | 必须闭环测试 |
| UR-002 | 接触人体部件工作表面温升不得引起组织灼伤 | GB 9706.1 强制标准 | 高 (强制) | 全负荷连续运行表面温升检测 | 依安规判定 |
| UR-003 | 支持脚踏或按键便捷切换主要工作参数模式 | 术者术中无菌操作体验 | 中 | 模拟临床操作切换响应测试 | 人机工效验收 |
| UR-004 | 出现异常时具备声光安全告警并自动切断危险输出 | 医疗器械风险控制准则 | 高 (强制) | 模拟故障注入保护测试 | ISO 14971 闭环 |
## 术语与参考
- 本需求表依据 YY/T 0287 / ISO 13485 与国家医疗器械临床使用规范编制。
## 待确认清单
- [ ] 与临床专家对齐特殊工况下的使用环境极限参数
## 说明
需求必须能追溯到前序材料或已批准文档。不编造用户未提出的功能。不做疗效宣称。
`,
},
{
taskKey: 'prelim_design',
title: '系统初步架构与电路规格设计书',
title: '系统初步设计方案',
stage: 'V0.5',
summary: '硬件拓扑、高速数据链路传输拓扑、算法数学配准模型与关键元器件BOM选型。',
markdownSkeleton: `# 系统初步架构与电路规格设计书 (项目模板副本)
markdownSkeleton: `# 系统初步设计方案
- 项目名称:{{project_name}}
- 架构对象:{{device_type}}
- 日期:{{generated_at}}
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
## 结论
(系统级初步方案边界、主要子系统、关键接口,以及现在要用户确认的架构选择。详细设计不在本阶段完成。后文不得与本结论打架。)
## 架构偏好
{{architecture}}
(若字段为空:从材料与用户需求归纳 1~2 个可选架构,用同一套维度对比,推荐并写失效条件。不编造未验证指标。)
## 系统上下文
(按实际使用环境改图:用户、临床环境、医院信息系统、附件/耗材、外部设备。图下用一段话解释边界与数据/能量流向。)
## 1. 硬件系统拓扑与数据链路
\`\`\`mermaid
graph LR
Sensor["前端医用传感器组件"] -->|高速差分传输| ISP["专用图像与信号调理单元"]
ISP --> Processing["FPGA/DSP 核心数字处理引擎"]
Processing --> UI["医用高分监视器 & 医生控制台"]
flowchart LR
user[用户/临床环境] --> system[本产品: {{device_type}}]
system --> hospital[医院信息系统/其他设备]
\`\`\`
## 2. 核心传感器像素配准算法矩阵
$$
\\begin{bmatrix} x_{aligned} \\\\ y_{aligned} \\\\ 1 \\end{bmatrix} = \\begin{bmatrix} h_{11} & h_{12} & h_{13} \\\\ h_{21} & h_{22} & h_{23} \\\\ h_{31} & h_{32} & 1 \\end{bmatrix} \\times \\begin{bmatrix} x_{raw} \\\\ y_{raw} \\\\ 1 \\end{bmatrix}
$$
## 子系统划分
## 3. 整板功耗与散热设计
预计整机工作功耗约 28W,采用自然对流与铝合金阳极氧化外壳导热。
(每个子系统:职责、主要部件或软件模块、与其他子系统的接口。至少覆盖与用户需求相关的部分;不适用的子系统写不适用理由。)
## 关键接口与数据流
(电气、机械、数据、供电、人机。每个接口写方向、主要内容、已知约束或标准线索。未知标待确认。)
## 与用户需求的追溯
(有用户需求 ID 则填真实行;没有则用描述性需求并标待确认,不要交只有 UR-001 的空壳。)
| 需求 ID | 设计响应 | 备注 |
|---|---|---|
| UR-001 | 系统主控上电快速启动调度与看门狗自检 | 硬件方案响应 |
| UR-002 | 结构微通道散热与接触件安全绝缘保护 | 热学与绝缘响应 |
| UR-003 | 前面板防尘防水按键接口与脚踏隔离接入 | 人机界面响应 |
| UR-004 | 硬件级双重互锁与声光告警驱动电路 | 安全控制响应 |
## 风险与待验证项
(技术风险、接口未定、需样机或检测才能关闭的项。每条写影响和下一步。)
## 待确认清单
## 说明
本方案为初步设计,不作为生产或注册的最终技术文档。不编造未验证的性能指标。
`,
},
{
taskKey: 'cdo_quote',
title: 'CDO商业报价单与工时测算清单',
title: 'CDO 报价单',
stage: 'V1.0',
summary: '依据 CDO 医疗器械定价模型,对立项、研发、样品打样、型式检验与 DHF 进行精准工时拆解。',
markdownSkeleton: `# CDO商业报价单与工时测算清单 (项目模板副本)
markdownSkeleton: `# CDO 报价单
- 报价项目:{{project_name}}
- 目标产品:{{device_type}}
- 报价日期:{{generated_at}}
- 结算货币:人民币 (RMB)
- 项目:{{project_name}}
- 生成时间:{{generated_at}}
- 快照:{{snapshot_id}}
- 配套 Excel:\`CDO报价核算.xlsx\`(完整保留公司定价模型模板的科目、公式与说明)
## 1. 全阶段 WBS 研发工时与预算分解表
## 结论
| 阶段代码 | 里程碑任务分解 | 负责工程角色 | 预算工时 (h) | 预算人工 (万元) | 核心受控交付物 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| V0.1 | 需求摸底、临床痛点与分类界定 | 法规专家 + 产品经理 | 80 | 4.20 | 《用户初始需求收集表》 |
| V0.5 | 方案设计、合规初评与专利检索 | 光学/架构师 + 注册专家 | 280 | 15.60 | 《注册可行性与设计规格书》 |
| V1.0 | 原型试制、型检跟进与全套DHF | 结构技师 + 验证工程师 | 380 | 18.00 | 《功能性工程样机与DHF文卷》 |
| **合计** | **全生命周期核心工作包** | **协同工程团队** | **740 h** | **37.80 万元** | **全套医疗器械申报技术卷宗** |
按公司 CDO 定价核算模板给出税后合计。精确单价缺失处标「待确认」,不对外构成承诺。数字必须与配套 Excel「报价模型」一致。
## 2. 商业报价核算模型
$$
Total_{Price} = (Cost_{Labor} + Cost_{Material} + Cost_{Testing}) \\times (1 + Margin_{Risk})
$$
按标准模型测算,预估总报价区间为 48.00 ~ 65.00 万元(待正式锁定)。
## 报价范围
- 客户:{{customer_name}}
- 产品:{{product_name}}
- 币种与口径:人民币;Buffer 20%、毛利 40%、税 7%(模板口径)
## 报价模型
| 报价代码 | 服务内容 | 人数 | 人年 | 成本 | 加Buffer20% | 加毛利40% | 加税7% | 设备设施等费用 | 税后价格 |
|---|---|---|---|---|---|---|---|---|---|
| ID2 | 产品规划 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID3.3.1.1 | 结构设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID3.3.1.2 | 硬件设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID3.3.1.3 | 软件设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID3.3.1.4 | 外观设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID3.3.1.5 | 合规设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID4 | 研发样品 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID5 | 设计验证 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| ID6 | DHF文档 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
| | 总计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 |
表中「人年」列与 Excel 模板同一列,对应模型投入人月合计(工时/160)。
## 说明
1)以上价格覆盖服务范围:原理样机验证,工程样机开发,送检样机开发
2)以上价格不含样机物料费用,如需乙方采购,另行商议
3)以上不含开发阶段使用的专用测试设备和工具工装费用
4)以上价格不包括药监局、医疗器械检验所等任何委托测试的第三方费用,第三方费用由甲方直接与第三方结算
5)以上未计算临床阶段费用
6)不含无菌耗材委托生产费用(CMO)
7)不含体系搭建费用
## 待确认清单
## 约束
本报价单与 \`CDO报价核算.xlsx\` 必须一致。金额不构成合同要约。不做取证时间承诺。
`,
},
];
/**
* 根据 taskKey 获取标准模板定义
*/
export function getTemplateDefinitionByTaskKey(taskKey: string): TemplateDefinition | undefined {
return STANDARD_WORKFLOW_TEMPLATES.find((t) => t.taskKey === taskKey);
}
/**
* 为指定项目动态实例化单份标准模板块状 AST
*/
export function buildTemplateASTForProject(
tmpl: TemplateDefinition,
params: TemplateFactoryParams
): DocumentAST {
const docId = params.docId || `doc-p${params.projectId}-${tmpl.taskKey}`;
const nowStr = new Date().toISOString().replace('T', ' ').substring(0, 16);
const customerName = params.customerName || '委托开发客户企业';
const author = params.authorName || params.creatorName || '编制工程师';
const reviewer = params.reviewerName || '质量负责人';
const approver = params.approverName || '技术委员会总监';
let md = tmpl.markdownSkeleton;
md = md.replaceAll('{{project_name}}', params.projectName);
md = md.replaceAll('{{product_name}}', params.projectName);
md = md.replaceAll('{{device_type}}', params.deviceType);
md = md.replaceAll('{{customer_name}}', customerName);
md = md.replaceAll('{{generated_at}}', nowStr);
md = md.replaceAll('{{snapshot_id}}', `SNAP-INIT-${params.projectId}`);
// 补全业务模板常见上下文占位符,防止留下大括号
md = md.replaceAll('{{intended_use}}', '待项目团队与临床专家共同确认预期用途与适应症');
md = md.replaceAll('{{target_market}}', '中国 NMPA(重点关注)');
md = md.replaceAll('{{timeline}}', '预计 6~12 个月');
md = md.replaceAll('{{budget}}', '待确认(按公司 CDO 定价模型测算)');
md = md.replaceAll('{{existing_materials}}', '项目立项信息表、初步临床沟通纪要');
md = md.replaceAll('{{constraints}}', '符合 ISO 13485 体系与国家强制性标准要求');
md = md.replaceAll('{{known_competitors}}', '待进一步查阅国内外公开注册数据库');
md = md.replaceAll('{{known_patents}}', '待启动 FTO 专题检索排查');
md = md.replaceAll('{{known_standards}}', 'GB 9706.1, YY 9706.102, GB/T 16886.1, ISO 14971');
md = md.replaceAll('{{device_class}}', 'II 类 / III 类(待注册法规专员评估确认)');
md = md.replaceAll('{{clinical_path}}', '待对比《免于临床评价医疗器械目录》');
md = md.replaceAll('{{tech_route}}', '主流医用硬件架构与嵌入式闭环控制系统');
md = md.replaceAll('{{manufacturing}}', '符合十万级洁净生产车间标准工艺');
md = md.replaceAll('{{architecture}}', '(系统推荐架构待结合硬件选型与实时数据链路完成对比后确认)');
md = md.replaceAll('{{user_roles}}', '- 术者:临床主任/主治医师\n- 巡回护士/器械护士:手术配合与辅助\n- 设备科工程师:日常维护与自检');
md = md.replaceAll('{{materials}}', '(本快照创建阶段无额外外部补充材料)');
return markdownToBlockAST(md, {
docId,
title: tmpl.title,
taskKey: tmpl.taskKey,
version: 'V0.1 (模板)',
category: 'workflow',
creatorId: params.creatorId,
creatorName: params.creatorName,
lifecycleState: 'template',
isClaimed: false,
author,
reviewer,
approver,
updatedAt: '刚刚',
summary: tmpl.summary,
});
}
/**
* 核心工厂函数:为新建项目生成全套 7 份受控交付物骨架及对应的 Block AST 缓存
*/
export function createProjectTemplateDeliverables(
params: TemplateFactoryParams
): TemplateFactoryResult {
const deliverables: DeliverableItem[] = [];
const docASTMap: Record<string, DocumentAST> = {};
const nowStr = new Date().toISOString().replace('T', ' ').substring(0, 16);
const customerName = params.customerName || '委托开发客户企业';
const author = params.authorName || params.creatorName || '编制工程师';
const reviewer = params.reviewerName || '质量负责人';
const approver = params.approverName || '技术委员会总监';
@@ -254,15 +532,7 @@ export function createProjectTemplateDeliverables(
STANDARD_WORKFLOW_TEMPLATES.forEach((tmpl) => {
const docId = `doc-p${params.projectId}-${tmpl.taskKey}`;
// 1. 变量宏替换
let md = tmpl.markdownSkeleton;
md = md.replaceAll('{{project_name}}', params.projectName);
md = md.replaceAll('{{device_type}}', params.deviceType);
md = md.replaceAll('{{customer_name}}', customerName);
md = md.replaceAll('{{generated_at}}', nowStr);
md = md.replaceAll('{{snapshot_id}}', `SNAP-INIT-${params.projectId}`);
// 2. 实例化 DeliverableItem
// 1. 实例化 DeliverableItem
const item: DeliverableItem = {
docId,
projectId: params.projectId,
@@ -284,23 +554,8 @@ export function createProjectTemplateDeliverables(
};
deliverables.push(item);
// 3. 解析为块状 AST 并缓存
const ast = markdownToBlockAST(md, {
docId,
title: tmpl.title,
taskKey: tmpl.taskKey,
version: 'V0.1 (模板)',
category: 'workflow',
creatorId: params.creatorId,
creatorName: params.creatorName,
lifecycleState: 'template',
isClaimed: false,
author,
reviewer,
approver,
updatedAt: '刚刚',
summary: tmpl.summary,
});
// 2. 解析为块状 AST 并缓存
const ast = buildTemplateASTForProject(tmpl, params);
docASTMap[docId] = ast;
});
@@ -0,0 +1,137 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
createProjectTemplateDeliverables,
getTemplateDefinitionByTaskKey,
buildTemplateASTForProject,
} from '../engine/templateFactory';
import { blockASTToMarkdown } from '../engine/blockToMarkdown';
test('新建项目工程文档模板质量与纯净性保障套件(对标官方参考系统)', async (t) => {
const mockNewProject = {
projectId: 8888,
projectName: '高频骨科超声骨刀系统 (BoneKnife-Pro)',
deviceType: '骨科超声手术设备',
creatorId: 101,
creatorName: '张高级工程师',
customerName: '北京积水潭医院骨科研究所',
};
const { deliverables, docASTMap } = createProjectTemplateDeliverables(mockNewProject);
await t.test('1. 必须精确生成 7 份官方全流程受控工作流模板且标记纯净', () => {
assert.equal(deliverables.length, 7, '受控交付物数量必须为 7');
const expectedKeys = [
'intake',
'research',
'feasibility_reg',
'feasibility_dev',
'user_requirements',
'prelim_design',
'cdo_quote',
];
deliverables.forEach((doc, idx) => {
assert.equal(doc.taskKey, expectedKeys[idx]);
assert.equal(doc.projectId, mockNewProject.projectId);
assert.equal(doc.isTemplateOnly, true, '必须标记为待填报模板');
assert.equal(doc.lifecycleState, 'template', '状态必须为 template');
assert.ok(docASTMap[doc.docId], `docASTMap 中必须包含 ${doc.docId} 的完整 AST`);
});
});
await t.test('2. 杜绝旧项目 CUSA-NeuroPulse 串号泄露,动态注入新项目信息', () => {
deliverables.forEach((doc) => {
const ast = docASTMap[doc.docId];
const markdown = blockASTToMarkdown(ast);
// 绝不能包含旧项目的特征字符串
assert.ok(
!markdown.includes('CUSA-NeuroPulse'),
`文档 ${doc.title} 包含旧项目残留 CUSA-NeuroPulse`
);
assert.ok(
!markdown.includes('神经外科双频超声吸引系统'),
`文档 ${doc.title} 包含旧项目残留 神经外科双频超声吸引系统`
);
assert.ok(
!markdown.includes('华西医院'),
`文档 ${doc.title} 包含旧项目残留 华西医院`
);
// 必须正确注入新项目动态参数
assert.ok(
markdown.includes('高频骨科超声骨刀系统 (BoneKnife-Pro)'),
`文档 ${doc.title} 未能正确注入新项目名称`
);
});
});
await t.test('3. 严格对标参考系统模板规范要素,绝非 3 行残缺摘要', () => {
deliverables.forEach((doc) => {
const ast = docASTMap[doc.docId];
const markdown = blockASTToMarkdown(ast);
// 验证章节深度与内容丰富度:块数量至少大于 6 个,绝非残缺骨架
const children = ast.rootBlock.children || [];
assert.ok(
children.length >= 6,
`文档 ${doc.title} 块数量过少(${children.length}),疑似残缺`
);
// 包含表格的标准受控模板核验
if (['research', 'feasibility_reg', 'feasibility_dev', 'user_requirements', 'prelim_design', 'cdo_quote'].includes(doc.taskKey!)) {
assert.ok(
markdown.includes('|') && markdown.includes('---'),
`文档 ${doc.title} 必须包含专业规范表格`
);
}
// 初步设计方案必须包含 Mermaid 架构图
if (doc.taskKey === 'prelim_design') {
assert.ok(
markdown.includes('```mermaid') && markdown.includes('flowchart'),
'初步设计方案必须包含 Mermaid 流程图'
);
}
// 法规可行性必须包含国家强制性标准合规矩阵
if (doc.taskKey === 'feasibility_reg') {
assert.ok(
markdown.includes('GB 9706.1') && markdown.includes('ISO 14971'),
'法规可行性必须包含 GB 9706.1 与 ISO 14971 强制性标准'
);
}
// CDO 报价单必须包含官方参考系统的核算科目与口径
if (doc.taskKey === 'cdo_quote') {
assert.ok(
markdown.includes('Buffer 20%') && markdown.includes('毛利 40%') && markdown.includes('ID2'),
'CDO 报价单必须包含公司定价模型模板科目与口径'
);
}
});
});
await t.test('4. 缓存丢失场景下即时自愈重建 AST 能力验证', () => {
const intakeDoc = deliverables[0];
const tmpl = getTemplateDefinitionByTaskKey(intakeDoc.taskKey!);
assert.ok(tmpl, '必须能通过 taskKey 获取模板定义');
const healedAST = buildTemplateASTForProject(tmpl, {
projectId: mockNewProject.projectId,
projectName: mockNewProject.projectName,
deviceType: mockNewProject.deviceType,
docId: intakeDoc.docId,
creatorId: mockNewProject.creatorId,
creatorName: mockNewProject.creatorName,
});
assert.equal(healedAST.docId, intakeDoc.docId);
assert.equal(healedAST.lifecycleState, 'template');
assert.equal(healedAST.rootBlock.children?.length, docASTMap[intakeDoc.docId].rootBlock.children?.length);
const healedMd = blockASTToMarkdown(healedAST);
assert.ok(healedMd.includes('高频骨科超声骨刀系统 (BoneKnife-Pro)'));
assert.ok(!healedMd.includes('CUSA-NeuroPulse'));
});
});