- 替换LoginUser中的getOptionJson().path()调用为新的getOptionJsonValue()方法 - 为LoginUser类添加安全的选项JSON值访问方法getOptionJsonValue() - 修复LoginUser类中乱码注释并优化代码结构 - 更新SysLoginService类中乱码注释为中文描述
18 KiB
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 源文件
- 编译错误 → 修复错误;重复文件 → 重构合并
- AI 幻觉文件 → 检查
git ls-tree baseline -- <file>确认后再删除 - 唯一例外:明确由人类确认删除的文件
铁律7: 禁止修改已有公开方法签名
- 不能删除/重命名已有的 public 方法,不能修改参数列表
- 需要新功能 → 添加重载方法;需要改行为 → 修改内部实现
铁律8: 验证后才宣称完成(Verification Before Completion)
- 没有跑过验证命令,就不能说"完成了""通过了""没问题"
- 禁止使用"应该可以""大概没问题""看起来正确"
- 必须:运行命令 → 读取输出 → 确认结果 → 才能宣称
- 这是诚实原则,不是效率问题
铁律9: 开发前必须审核原有代码(P0 — 铁律)
- 任何新功能开发前,必须先搜索项目中是否已有相关代码
- 搜索路径:Controller / AppService / Service / Mapper / Entity / 前端页面 / API接口
- 如果已有部分功能 → 在原有代码基础上升级优化完善,禁止另起炉灶
- 如果已有接口但前端缺失 → 只补前端,不重复建后端
- 如果已有前端但后端缺失 → 只补后端,不重写前端
- 搜索命令:
rg -l "关键词" healthlink-his-server/ healthlink-his-ui/src/ - 禁止:不看代码就新建模块、重复实现已有功能、废弃原有代码另写一套
铁律10: 状态变更影响面分析(Bug #574→575 教训)
- 改任何状态枚举值前,必须执行影响面分析
rg "原状态枚举名" --type java列出所有引用文件- 逐个检查:设置值?查询过滤?显示映射?统计聚合?
- 检查逆向流程:退号、取消、停诊是否兼容新状态
- 检查 XML mapper 中所有查询过滤条件
- 检查前端所有 v-if/v-for/disabled 条件
- 禁止:只改正向流程不验逆向流程
铁律11: 逆向流程验证(Bug #575 教训)
- 涉及状态流转的 Bug,验证时必须覆盖:
- 正向:预约→签到→就诊→完成
- 逆向:退号、取消预约、停诊、退费
- 边界:并发操作、重复操作、异常中断
- 禁止:只测正向流程就标记"修复完成"
铁律12: 全链路 6 环分析
- 涉及数据库字段的 Bug/需求 必须走完整链路
前端/页面 → Controller → Service → Mapper → DB/SQL → 关联模块
①录入 ②验证 ③业务 ④持久化 ⑤存储 ⑥联动
- ①录入:前端有无输入入口(弹窗、表格行编辑、表单)
- ②验证:Controller 参数校验、@Valid、权限控制
- ③业务:Service 业务逻辑、事务边界、多个 Service 实现类入口
- ④持久化:Mapper XML、DTO 字段映射、类型转换
- ⑤存储:数据库表结构、索引、NOT NULL 约束
- ⑥联动:上游(医嘱→护士站)、下游(打印、计费、报表)是否同步
铁律13: 全链路验证(状态流转 Bug 必做)
- 修复后按以下顺序验证,编译通过不等于修复完成
① 数据库:SELECT status FROM table WHERE id = ? → 确认写入正确
② 后端接口:检查所有 if/switch 分支 → 确认映射正确
③ 前端显示:检查 STATUS_CLASS_MAP → 确认文本正确
④ 前端交互:检查 v-if/v-for/disabled → 确认按钮状态正确
⑤ 统计数据:检查聚合 SQL → 确认统计包含新状态
铁律14: 池/统计表同步(Bug #574 教训)
- 任何状态变更必须同步更新关联统计表
- 检查清单:
- 状态变更后,哪些统计字段需要更新?
- 是原子递增/递减,还是全量重算?
- 并发安全:用
SET field = field + 1还是先查后改? - 逆向操作(退号/取消)是否正确回滚统计?
- 禁止:只改状态不改统计,或只改统计不改状态
铁律15: 统计变更必须验证实际值(Bug #575 教训)
- 修改统计逻辑后,必须查数据库验证实际值
- 对比操作前后的值,确认统计正确
- 禁止:改了统计逻辑不查数据库验证
铁律16: 搜索所有相关代码路径
- 修复前必须用
rg搜索所有引用
rg "状态枚举名|相关方法名|相关字段名" --type java --type vue
- 确保不遗漏任何引用路径
铁律17: 数据库铁律
- 修前必须查询真实数据库 — 确认表结构、字段约束、索引
- 禁止凭猜测写 SQL — 先查看表结构
- 修改 SQL 后必须验证 —
EXPLAIN或实际查询验证语法 - NOT NULL 约束必须检查 — INSERT/UPDATE 前先查
is_nullable - 关联表必须查完整 — 涉及 JOIN 查所有关联表结构和外键
铁律18: 禁止破坏原有功能(P0绝对铁律)
- 完善增加功能和流程时,绝对不能破坏或者让原有功能不能用
- 修改已有实体前必须对比原始文件(
git show HEAD~N:./file.java),保留所有原有字段和方法 - 新增字段只能追加,不能删除或重命名已有字段
- SQL迁移只允许
ALTER TABLE ADD COLUMN,不允许DROP COLUMN或RENAME COLUMN - Controller新端点不能修改已有端点的路径或参数
- 前端新页面不能修改已有页面的组件结构
- 每次修改后必须
mvn clean compile -DskipTests验证
铁律19: 编译错误不区分来源(Bug #698 教训)
mvn compile、vite build、vue-tsc等构建命令报错 = 不过关,不管是自己引入的还是历史遗留的- 禁止说"这是预存问题""不是我改的""原有bug"——构建通不过就不能宣称完成
- 正确做法:定位错误 → 修复 → 重新构建确认通过 → 然后才能继续
铁律20: 数据来源必须验证(Bug #698 教训)
- 涉及数据查询/提取时,必须先确认数据实际存储位置,不能假设
- 修复前必须:打印/检查原始数据结构 → 确认字段存在 → 再写提取逻辑
- 禁止:凭代码推断数据位置、假设"应该在这里"
铁律21: 外部配置值必须实测验证(Bug #698 教训)
- 使用外部服务(API、模型、数据库)的配置值,必须实际调用验证
- 配置变更后必须:发起一次真实请求 → 确认返回 200 → 再宣称配置正确
- 禁止:改完配置不测试、假设"应该能用"
铁律22: 端到端验证必须有实际输出证据(Bug #698 教训)
- 声称功能生效前,必须有实际的端到端输出证据
- 验证方式:运行命令 → 检查输出中包含预期关键词
- 禁止:只检查代码路径可达就算"验证通过"
铁律23: 文件读写强制 UTF-8 编码(必遵守)
- 禁止使用 PowerShell Get-Content -Raw(不带 -Encoding UTF8)读取源文件
- 禁止使用 Out-File -Encoding utf8(会写 BOM)
- 正确写法:
- 读取:
[System.IO.File]::ReadAllText($path, [System.Text.Encoding]::UTF8) - 写入:
[System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new(False))
- 读取:
- 原因:Windows PowerShell 5.1 默认用系统 locale(GBK/CP936)读写,会把 UTF-8 中文变成乱码
铁律24: 禁止硬编码业务默认值(Bug #617 教训)
- 禁止在提交参数中硬编码业务默认值(如
contractNo: '0000') - 必须使用用户在表单中选择的值,硬编码值仅作为 fallback
- 检查清单:
- 表单字段是否有
v-model绑定? - 构建提交参数时是否使用了绑定值?
- 提交后是否覆盖了用户选择?
- 表单字段是否有
🟡 P1 铁律 — 强烈建议
铁律25: 先分解再行动
- 修改超过3个文件、涉及多模块、数据库变更,必须先制定计划
铁律26: 验证后信
- 每次修改后必须验证编译通过,不信记忆
铁律27: 文档统一管理
- 所有文档存储在
MD/目录 - 文件名:大写英文+下划线(如
BACKEND_CHECKLIST.md) - 文档头部必须包含元数据块(文档类型、版本、日期)
铁律28: 设计文档必须包含UI设计和调用流程
- 所有新模块/页面的设计文档必须包含:UI布局描述、交互效果清单、前后端调用流程
- 没有明确UI设计的模块,禁止直接编码
- 设计文档必须写清楚:系统调用关系、方法函数调用关系、完整业务流程
- 设计文档中每个用户操作必须对应:前端事件 → API调用 → 后端处理链路 → 返回数据 → UI渲染
铁律29: 设计文档确认后自主开发(铁律)
- 设计文档一旦确认,后续开发必须按文档自主执行
- 禁止反复询问"是否继续""下一步做什么""是否开始"——直接按计划推进
- 每完成一个 Sprint,自动提交推送,然后立即开始下一个 Sprint
- 只在遇到无法解决的阻塞时才暂停询问
铁律30: 前端验证铁律
- 提交前必须编译前端 —
npm run build:dev或npx vite build通过才算完成 - 禁止只改 .vue 文件不验证编译 — 改完必须跑一次编译确认无报错
- SCSS 括号闭合必须检查 —
<style lang="scss" scoped>内的所有{}必须成对闭合 - 编译报错必须当场修复 — 看到 error 立即修,不要留到下一步
铁律31: 提交前验证铁律
- 后端:
mvn compile通过 + 无新增 warning - 前端:
npm run build:dev通过 + 无 SCSS 错误 - 禁止跳过编译直接提交 — 编译失败的代码不允许进仓库
- 提交信息格式:
type(scope): description(如fix(registration): 修复退号金额计算)
铁律32: 修复流程
- 一次只修一个 Bug,不扩大范围
- 修前必须完整获取 Bug 全部信息 — 描述、复现步骤、所有截图/附件、所有备注历史。禁止只看标题就写代码
- 修复前必须读 AGENTS.md
- 修复后必须验证编译 —
mvn compile/vue-tsc --noEmit0 error - commit 前必须验证 — 编译通过 + 无新增 lint 警告
铁律33: Bug 状态管理
- 已关闭/已解决的 Bug 禁止处理 — 处理前检查状态,resolved/closed 直接跳过
- 人类提的 Bug 只加备注不改状态 — 不改 status、不改 assignedTo
- 智能体提的 Bug 可改分配和加备注 — 状态变更等测试通过后由华佗确认
- 每个修复必须有 git commit — 格式:
fix(#bug_id): 简要描述
铁律34: 质量门禁
- L1: 编译通过
- L2: 测试通过
- L3: DB审查通过
- L4: 验收通过
- L5: 归档完成
三、Karpathy 编码准则
减少 LLM 常见编码错误。偏向谨慎而非速度。
3.1 先想再写
- 明确陈述假设,不确定就问
- 多种解读时都列出来,不要默默选一种
- 有更简单的方案就说出来,该推回就推回
- 不清楚的地方停下来,说清楚哪里不清楚
3.2 简洁优先
- 不做没要求的功能,不做一次性代码的抽象
- 不加没要求的"灵活性"和"可配置性"
- 200 行能 50 行搞定就重写
- 自问:"高级工程师会不会觉得这过度设计?"
3.3 精准修改
- 只改必须改的,不"顺手改进"相邻代码
- 匹配现有代码风格,即使你有不同的偏好
- 每行改动都能追溯到用户的请求
- 只清理你自己改动产生的无用代码
3.4 目标驱动
- 把任务转化为可验证目标
- 多步任务声明计划:
[步骤] → 验证: [检查] - 强验收标准让 Agent 能独立循环,弱标准需要持续澄清
四、系统化调试(Systematic Debugging)
铁律:没有根因调查,不能提出修复方案。
四阶段流程
阶段1:根因调查(修复前必须完成)
- 仔细阅读错误信息(堆栈、行号、错误码)
- 稳定复现(能否可靠触发?步骤?每次?)
- 检查最近变更(git diff、新依赖、配置变更)
- 多组件系统:在每个组件边界加诊断日志,定位哪一层断裂
- 追踪数据流:坏值从哪里来?谁调用的?一直追溯到源头
阶段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权限控制 - 患者敏感信息在日志中脱敏
- 扩展功能不修改原有函数签名
- DTO 字段类型防御:前端传入的 Boolean 字段 → 改用 String + 业务层转换(Jackson 对 Boolean 严格校验);所有接受前端输入的 DTO 加
@JsonIgnoreProperties(ignoreUnknown = true)
六、前端开发规范
技术栈
- 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') - 页面使用
<script setup>语法 - 按钮权限使用
v-hasPermi指令 onMounted中注册的事件在onUnmounted中移除
七、Agent 体系
角色与路由
| 代号 | 名称 | 角色 | 路由关键词 |
|---|---|---|---|
| liubei | 刘备 | 项目经理 | 协调、分派、异常升级 |
| zhugeliang | 诸葛亮 | 架构师 | 分析、路由、设计 |
| guanyu | 关羽 | 后端开发 | java, api, spring, service, controller |
| zhaoyun | 赵云 | 前端开发 | vue, 界面, 显示, 弹窗, 按钮 |
| xunyu | 荀彧 | DBA | 数据库, sql, 迁移, mapper xml |
| zhangfei | 张飞 | 测试 | 测试, QA, 回归 |
| huatuo | 华佗 | 验收 | 需求验收、质量确认 |
| chenlin | 陈琳 | 文档 | 文档、归档、Git提交 |
协作流水线
刘备(协调) → 诸葛亮(分析路由) → {关羽|赵云}(修复) → 荀彧(DB审查) → 张飞(测试) → 华佗(验收) → 陈琳(归档)
八、快速参考命令
# === 后端 ===
export JAVA_HOME=/opt/jdk-25
mvn clean compile -DskipTests # 编译
mvn install -DskipTests # 构建
mvn test -pl healthlink-his-application -Dtest="XxxTest" -Dsurefire.failIfNoSpecifiedTests=false
# === 前端 ===
cd healthlink-his-ui
npm run dev && npm run build:dev && npm run lint && npm run test:run
# === Git ===
git status && git add -A && git commit -m "feat(module): desc" && git push origin develop
九、过往教训
| Bug | 教训 | 根因 |
|---|---|---|
| #574 | 状态值 BOOKED(1)→应为 CHECKED_IN(3),前端映射缺失 | 没走完整状态链路 |
| #574 | AI 看到编译错误直接删文件 | 没检查 git baseline |
| #574 | 多次 fallback 修错文件 | 没用 rg 搜索所有引用 |
| #574 | 签到后 booked_num 未累加 | 只改状态没改统计 |
| #575 | 改了签到状态没检查退号流程 | 只验正向不验逆向 |
| #575 | booked_num 应在预约时累加而非签到时 | 统计变更未验证实际值 |
| #617 | 费用性质硬编码为 '0000'(自费),用户选医保无效 | 构建参数时写死默认值 |
| #632 | Boolean DTO 接收字符串 "肝功能12项" 导致反序列化失败 | DTO 字段类型未做防御 |
| #698 | 模型名拼写错误 mino→mimo 导致 400 | 外部配置值未实测验证 |
| — | 修复完成未提交到 develop | 框架未强制验证提交 |
| — | 退号流程只检查 BOOKED(1) 不兼容 CHECKED_IN(3) | 状态变更影响面分析缺失 |
⚠️ 本文件是 AI 开发规范的唯一信源。
📅 最后更新: 2026-06-10 | 来源: AgentForge Harness Iron Laws (39条)