diff --git a/AGENTS.md b/AGENTS.md index 1dec328d9..e629574b2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -107,6 +107,143 @@ - **违规判定**: 因修改导致原有代码编译失败或运行报错,视为违反铁律18,必须立即回滚修复 +**铁律19: 编译错误不区分来源(Bug #698 教训)** +- `mvn compile`、`vite build`、`vue-tsc` 等构建命令报错 = 不过关,**不管是自己引入的还是历史遗留的** +- 禁止说"这是预存问题""不是我改的""原有bug"——构建通不过就不能宣称完成 +- 正确做法:定位错误 → 修复 → 重新构建确认通过 → 然后才能继续 +- **违规判定**: 构建命令有 ERROR 但未修复就报告"编译通过",视为违反铁律 + +**铁律20: 数据来源必须验证(Bug #698 教训)** +- 涉及数据查询/提取时,必须先确认数据实际存储位置,不能假设 +- 案例:从 `raw_steps_html` 提取 fileID,而不是从 `steps`(纯文本,已被 strip) +- 修复前必须:打印/检查原始数据结构 → 确认字段存在 → 再写提取逻辑 +- 禁止:凭代码推断数据位置、假设"应该在这里" + +**铁律21: 外部配置值必须实测验证(Bug #698 教训)** +- 使用外部服务(API、模型、数据库)的配置值,必须实际调用验证,不能仅凭记忆或推测 +- 案例:模型名 `mino-v2.5` 应为 `mimo-v2.5`,拼写错误导致 400 +- 配置变更后必须:发起一次真实请求 → 确认返回 200 → 再宣称配置正确 +- 禁止:改完配置不测试、假设"应该能用" + +**铁律22: 端到端验证必须有实际输出证据(Bug #698 教训)** +- 声称功能生效前,必须有实际的端到端输出证据 +- 不能仅凭代码路径推断"应该走了 vision"——必须看到实际返回内容 +- 验证方式:运行命令 → 检查输出中包含预期关键词(如 vision 分析结果、图片识别文字) +- 禁止:只检查代码路径可达就算"验证通 +**铁律23: 文件读写强制 UTF-8 编码(必遵守)** +- **禁止**使用 Get-Content -Raw(不带 -Encoding UTF8)读取源文件 +- **禁止**使用 Out-File -Encoding utf8(会写 BOM) +- **正确写法**: + - 读取:[System.IO.File]::ReadAllText(, [System.Text.Encoding]::UTF8) + - 写入:[System.IO.File]::WriteAllText(, # HealthLink-HIS — AI 开发规范 + +> 🤖 本文件由 Codex CLI、Claude Code 等工具自动读取。 +> 工具进入项目目录时会自动加载此文件作为开发规范上下文。 + +--- + +# HealthLink-HIS — AI 开发规范(自动加载) + +> 🤖 **本文件供所有 AI 编码工具自动读取**。进入本项目后必须遵守以下规范。 +> +> **模型决定上限,Harness 决定底线。** + +--- + +## 一、项目概览 + +| 属性 | 值 | +|------|------| +| 项目名 | HealthLink-HIS(医院信息系统) | +| 后端路径 | `healthlink-his-server/` | +| 前端路径 | `healthlink-his-ui/` | +| 文档路径 | `MD/` | +| JDK | 25 (OpenJDK) | +| Spring Boot | 4.0.6 | +| MyBatis-Plus | 3.5.16 | +| Vue | 3.x + Vite + Element Plus | +| 数据库 | PostgreSQL 15+ | +| 包名 | `com.healthlink.his` | +| 后端端口 | 18082 | +| 前端端口 | 81 | + +--- + +## 二、铁律(必须遵守,违反即失败) + +### 🔴 P0 铁律 — 不可违反 + +**铁律1: 修改完必须测试** +``` +后端: mvn clean compile -DskipTests → mvn install -DskipTests → mvn test +前端: npm run build:dev → npm run lint +``` +- 白盒:编译通过,无 ERROR +- 黑盒:关键接口返回 `{code:200, data:...}`,验证业务逻辑 +- 冒烟:应用正常启动,核心流程通畅 + +**铁律2: Flyway 数据库迁移** +- 凡是新建表、新增字段,必须创建 Flyway 迁移脚本 +- 路径:`healthlink-his-domain/src/main/resources/db/migration/` +- 命名:`V{版本号}__{描述}.sql`(双下划线) + +**铁律3: 测试通过后才提交** +- 编译 + 测试全部通过后才能 git commit +- 不提交未完成的功能、调试代码、临时文件 + +**铁律4: 前后端API路径对齐** +- 后端前缀:`/healthlink-his/api/v1/` +- 前端 `request.js` 的 baseURL 必须与后端匹配 + +**铁律5: 状态值一致性(Bug #574 教训)** +- 修改任何状态值前,必须先列出完整的状态流转链路 +- 检查项:枚举定义 → Service 设置 → 查询映射 → 前端 STATUS_CLASS_MAP → 前端 v-if → 统计SQL +- 禁止:只改一端不检查其他端 + +**铁律6: 禁止删除源文件(Bug #574 教训)** +- 绝对禁止删除项目中已有的 Java/Vue/SQL 源文件 +- 编译错误 → 修复错误;重复文件 → 重构合并 +- 唯一例外:明确由人类确认删除的文件 + +**铁律7: 禁止修改已有公开方法签名** +- 不能删除/重命名已有的 public 方法,不能修改参数列表 +- 需要新功能 → 添加重载方法;需要改行为 → 修改内部实现 + +**铁律8: 验证后才宣称完成(Verification Before Completion)** +- **没有跑过验证命令,就不能说"完成了""通过了""没问题"** +- 禁止使用"应该可以""大概没问题""看起来正确" +- 必须:运行命令 → 读取输出 → 确认结果 → 才能宣称 +- 这是诚实原则,不是效率问题 + + +**铁律9: 开发前必须审核原有代码(P0 — 铁律)** +- **任何新功能开发前,必须先搜索项目中是否已有相关代码** +- 搜索路径:Controller / AppService / Service / Mapper / Entity / 前端页面 / API接口 +- 如果已有部分功能 → 在原有代码基础上**升级优化完善**,禁止另起炉灶 +- 如果已有接口但前端缺失 → 只补前端,不重复建后端 +- 如果已有前端但后端缺失 → 只补后端,不重写前端 +- 搜索命令:`rg -l "关键词" healthlink-his-server/ healthlink-his-ui/src/` +- 禁止:不看代码就新建模块、重复实现已有功能、废弃原有代码另写一套 + + +**铁律12: 设计文档确认后自主开发(铁律)** +- 设计文档(如 `MD/architecture/GRADE3A_GAP_ANALYSIS_AND_DESIGN.md`)一旦确认,后续开发**必须按文档自主执行** +- **禁止反复询问"是否继续""下一步做什么""是否开始"**——直接按计划推进 +- 每完成一个 Sprint,自动提交推送,然后立即开始下一个 Sprint +- 只在遇到**无法解决的阻塞**(如技术选型冲突、需求不明确、第三方依赖不可用)时才暂停询问 +- 设计文档是"**已签合同**",不是"参考意见"。铁律执行优先级:设计文档 > 人类临时指令 > AI 自行判断 + +**铁律18: 禁止破坏原有功能(P0绝对铁律)** +- **完善增加功能和流程时,绝对不能破坏或者让原有功能不能用** +- 修改已有实体前必须对比原始文件(`git show HEAD~N:./file.java`),保留所有原有字段和方法 +- 新增字段只能追加,不能删除或重命名已有字段 +- SQL迁移只允许 `ALTER TABLE ADD COLUMN`,不允许 `DROP COLUMN` 或 `RENAME COLUMN` +- Controller新端点不能修改已有端点的路径或参数 +- 前端新页面不能修改已有页面的组件结构 +- 每次修改后必须 `mvn clean compile -DskipTests` 验证 +- **违规判定**: 因修改导致原有代码编译失败或运行报错,视为违反铁律18,必须立即回滚修复 + + **铁律19: 编译错误不区分来源(Bug #698 教训)** - `mvn compile`、`vite build`、`vue-tsc` 等构建命令报错 = 不过关,**不管是自己引入的还是历史遗留的** - 禁止说"这是预存问题""不是我改的""原有bug"——构建通不过就不能宣称完成 @@ -533,3 +670,410 @@ git status && git add -A && git commit -m "feat(module): desc" && git push origi --- > 📅 最后同步: 2026-06-06 15:09 | 源文件: RULES.md | 重新同步: `bash scripts/sync-ai-rules.sh` +, [System.Text.UTF8Encoding]::new(False)) + - git提取:先 Out-File -Encoding utf8 保存到临时文件,再用 [System.IO.File]::ReadAllText() 读取 +- **根因**:PowerShell 管道会丢失换行符,git show | Out-File 会将多行文件压缩为一行 +过" + + +### 🟡 P1 铁律 — 强烈建议 + +**铁律9: 先分解再行动** +- 修改超过3个文件、涉及多模块、数据库变更,必须先制定计划 + +**铁律10: 验证后信** +- 每次修改后必须验证编译通过,不信记忆 + +**铁律13: 文档统一管理** +- 所有文档存储在 `MD/` 目录 +- 文件名:大写英文+下划线(如 `BACKEND_CHECKLIST.md`) +- 文档头部必须包含元数据块(文档类型、版本、日期) + +--- + + +**铁律14: 设计文档必须包含UI设计和调用流程** +- 所有新模块/页面的设计文档必须包含:UI布局描述、交互效果清单、前后端调用流程 +- 没有明确UI设计的模块,禁止直接编码 +- 详见 +- 设计文档必须写清楚:系统调用关系、方法函数调用关系、完整业务流程 +- 设计文档中每个用户操作必须对应:前端事件 → API调用 → 后端处理链路 → 返回数据 → UI渲染 + +--- + +## 三、Karpathy 编码准则 + +> 减少 LLM 常见编码错误。偏向谨慎而非速度。 + +### 3.1 先想再写 +- 明确陈述假设,不确定就问 +- 多种解读时都列出来,不要默默选一种 +- 有更简单的方案就说出来,该推回就推回 +- 不清楚的地方停下来,说清楚哪里不清楚 + +### 3.2 简洁优先 +- 不做没要求的功能,不做一次性代码的抽象 +- 不加没要求的"灵活性"和"可配置性" +- 200 行能 50 行搞定就重写 +- 自问:"高级工程师会不会觉得这过度设计?" + +### 3.3 精准修改 +- 只改必须改的,不"顺手改进"相邻代码 +- 匹配现有代码风格,即使你有不同的偏好 +- 每行改动都能追溯到用户的请求 +- 只清理你自己改动产生的无用代码 + +### 3.4 目标驱动 +- 把任务转化为可验证目标 +- 多步任务声明计划:`[步骤] → 验证: [检查]` +- 强验收标准让 Agent 能独立循环,弱标准需要持续澄清 + +--- + +## 四、全链路 6 环分析 + +> ⚠️ **涉及数据库字段的 Bug / 需求,必须走完整链路。** + +``` +前端/页面 → Controller → Service → Mapper → DB/SQL → 关联模块 + ①录入 ②验证 ③业务 ④持久化 ⑤存储 ⑥联动 +``` + +| 环 | 检查内容 | +|----|---------| +| ① 录入 | 前端有无输入入口(弹窗、表格行编辑、表单) | +| ② 验证 | Controller 参数校验、@Valid、权限控制 | +| ③ 业务 | Service 业务逻辑、事务边界、多个 Service 实现类入口 | +| ④ 持久化 | Mapper XML、DTO 字段映射、类型转换 | +| ⑤ 存储 | 数据库表结构、索引、NOT NULL 约束 | +| ⑥ 联动 | 上游(医嘱→护士站)、下游(打印、计费、报表)是否同步 | + +**修复后的验证顺序**: +1. 数据库:确认状态值已正确写入 +2. 后端接口:确认返回的状态映射正确 +3. 前端显示:确认页面显示正确状态文本 +4. 前端交互:确认按钮/操作基于正确状态启用/禁用 +5. 统计数据:确认池/报表统计包含新状态 + +--- + +## 五、Harness Engineering 方法论 + +> Harness = 约束 + 反馈 + 控制平面 + 持久执行 + +### 5.1 四层约束金字塔 + +| 层级 | 内容 | 落地方式 | +|------|------|---------| +| **L1 架构约束** | 接口合约、包结构、命名规范、禁止模式 | 本文件铁律 | +| **L2 代码质量** | 圈复杂度、代码风格、类型提示 | 编译门禁 + ESLint | +| **L3 安全约束** | 敏感信息检测、权限检查、输入验证 | 配置不可硬编码 | +| **L4 业务规则** | 领域逻辑、数据一致性、事务边界 | 全链路 6 环验证 | + +**约束设计原则**: +- **可验证**:每条约束必须能被自动化检查("覆盖率>90%"✅ "质量要高"❌) +- **无歧义**:"每函数不超过50行"✅ "函数不要太长"❌ +- **优先级**:安全(1) > 架构(2) > 业务(3) > 质量(4) > 性能(5) +- **渐进增强**:L1编译通过 → L2+命名规范 → L3+测试覆盖 → L4+安全扫描 + +### 5.2 三层反馈系统 + +| 层级 | 速度 | 覆盖范围 | 失败处理 | +|------|------|---------|---------| +| **L1 编译检查** | <30秒 | 语法、类型、签名 | 立即阻断,自行修复 | +| **L2 数据流验证** | <5分钟 | 全链路字段、Mapper XML、DTO | 修复后上报 | +| **L3 人工审查** | 10-30分钟 | 架构、设计、业务正确性 | 驳回/指导/批准 | + +**反馈铁律**: +- 反馈必须可行动(文件 + 行号 + 错误类型 + 修复方向) +- 失败后先回滚到最近检查点,再重试 +- 持续失败3次 → 上报人类 + +### 5.3 控制平面 + +``` +战略层(人类) → 设定目标、审批决策、异常升级 +战术层(Agent) → 任务分解、update_plan、依赖协调、检查点保存 +执行层(Agent) → 代码生成、测试执行、错误恢复、幂等重试 +``` + +### 5.4 持久执行 + +- 每个关键步骤保存检查点(`update_plan` 进度) +- 失败后从最新检查点恢复,不从头开始 +- 幂等设计:同一操作重复执行结果一致 +- **三层状态管理**:系统层(工作流ID/超时/重试) → 执行层(当前活动/进度) → 业务层(已完成工作/中间产物) + +--- + +## 六、五层质量门禁 + +| 门禁 | 时间 | 范围 | 失败处理 | +|------|------|------|---------| +| **L1 编译检查** | <30秒 | 语法、类型、导入 | Agent 自行修复 | +| **L2 静态分析** | <2分钟 | 代码风格、复杂度、安全 | Agent 修复 | +| **L3 单元测试** | <5分钟 | 功能正确性、边界条件 | 自动修复或上报 | +| **L4 集成测试** | <15分钟 | 模块间交互、数据流 | 上报人工 | +| **L5 生产验证** | 持续 | 监控、告警、性能 | 自动回滚 | + +**提交铁律**:L1-L2 必须通过才能 commit,L3(如有DB变更)必须通过才能 push + +--- + +## 七、系统化调试(Systematic Debugging) + +> **铁律:没有根因调查,不能提出修复方案。** + +### 四阶段流程 + +**阶段1:根因调查**(修复前必须完成) +1. 仔细阅读错误信息(堆栈、行号、错误码) +2. 稳定复现(能否可靠触发?步骤?每次?) +3. 检查最近变更(git diff、新依赖、配置变更) +4. 多组件系统:在每个组件边界加诊断日志,定位哪一层断裂 +5. 追踪数据流:坏值从哪里来?谁调用的?一直追溯到源头 + +**阶段2:模式分析** +- 找到同代码库中类似的正常工作代码 +- 逐项对比差异 +- 理解依赖关系 + +**阶段3:假设与测试** +- 形成单一假设:"我认为X是根因,因为Y" +- 做最小改动测试 +- 有效 → 阶段4;无效 → 新假设 + +**阶段4:实施** +- 创建失败测试用例 +- 修复根因(不是症状) +- 验证修复 + +--- + +## 八、后端开发规范 + +### 分层架构 +``` +Controller → AppService → Service → Mapper → Entity +``` + +### 命名规范 +| 类型 | 规则 | 示例 | +|------|------|------| +| Controller | `XxxController` | `RegistrationController` | +| AppService | `IXxxAppService` / `XxxAppServiceImpl` | `IRegistrationAppService` | +| Service | `IXxxService` / `XxxServiceImpl` | `IRegistrationService` | +| Mapper | `XxxMapper` | `RegistrationMapper` | +| Entity | `Xxx` | `Registration` | +| DTO | `XxxDto` / `XxxQueryDto` | `RegistrationDto` | + +### 包结构 +``` +com.healthlink.his.web.{module}.controller +com.healthlink.his.web.{module}.appservice +com.healthlink.his.web.{module}.service +com.healthlink.his.web.{module}.mapper +com.healthlink.his.web.{module}.dto +com.healthlink.his.domain.{module} +com.healthlink.his.common.enums +``` + +### 关键约束 +- 所有查询使用 `LambdaQueryWrapper`,禁止字符串拼接 SQL +- `@Transactional(rollbackFor = Exception.class)` 管理事务 +- 所有接口标注 `@PreAuthorize` 权限控制 +- 患者敏感信息在日志中脱敏 +- **扩展功能不修改原有函数签名** + +--- + +## 九、前端开发规范 + +### 技术栈 +- Vue 3 + Vite + Element Plus + Pinia + Axios(基于 RuoYi-Vue3) + +### 目录结构 +``` +src/api/{module}/ # API接口 +src/views/{module}/ # 页面组件 +src/store/modules/ # Pinia状态管理 +src/components/ # 公共组件 +``` + +### 关键约束 +- API前缀:`/healthlink-his/api/v1/` +- 路由懒加载:`() => import('@/views/xxx/index.vue')` +- 页面使用 `