10 KiB
Executable File
10 KiB
Executable File
OpenHIS — Harness Engineering 开发指南
模型决定上限,Harness 决定底线。 本文件是 OpenHIS 项目的 Harness Engineering 落地。整合了 OpenAI/Anthropic Harness Engineering 方法论与 walkinglabs 实战模式。
🔴 铁律统一文件:
/root/.codex/rules/IRON_LAWS.md— 所有智能体必须遵守,运行时自动加载。
📋 项目信息
OpenHIS 医院管理系统 | Java 17 + Spring Boot + MyBatis Plus | Vue 3 + Element Plus | PostgreSQL
构建和运行
cd /root/.openclaw/workspace/his-repo
# 初始化(每次新会话先运行)
bash .harness/init.sh
# 后端编译
cd openhis-server-new && mvn compile -pl openhis-application -am
# 后端打包
mvn clean package -DskipTests
# 后端运行
cd openhis-application && mvn spring-boot:run
# 前端
cd openhis-ui-vue3 && npm install && npm run dev
关键路径
后端代码: openhis-server-new/openhis-application/src/main/java/com/
后端配置: openhis-server-new/openhis-application/src/main/resources/
Mapper XML: .../mapper/ (regdoctorstation/, doctorstation/, ...)
前端代码: openhis-ui-vue3/src/
Harness: .harness/ (init.sh, PROGRESS.md, feature_list.json, ...)
🔧 5 子系统模型(WalkingLabs)
1. 指令子系统(Instruction)
| 文件 | 用途 |
|---|---|
| AGENTS.md(本文件) | 项目规则、约束、工作流程 |
.harness/feature_list.json |
机器可读的功能状态追踪 |
.harness/PROGRESS.md |
会话进度和已验证状态 |
.harness/session-handoff.md |
跨会话交接摘要 |
2. 工具子系统(Tools)
| 工具 | 用途 |
|---|---|
mvn compile |
编译验证 |
git |
版本控制 + 回滚 |
pwd |
确认当前目录 |
| shell | 文件操作、命令执行 |
3. 环境子系统(Environment)
| 组件 | 状态 |
|---|---|
| Java 17 | ✅ pom.xml 锁定 |
| Maven | ✅ mvn-wrapper |
| PostgreSQL | ✅ 192.168.110.252:15432 |
| Node.js | ✅ package.json 锁定 |
4. 状态子系统(State)
| 机制 | 用途 |
|---|---|
update_plan |
当前步骤检查点 |
.harness/PROGRESS.md |
跨会话进度记录 |
.harness/feature_list.json |
功能状态跟踪 |
git log |
变更历史追溯 |
5. 反馈子系统(Feedback)
| 层级 | 命令 | 时间 |
|---|---|---|
| L1 编译 | mvn compile -pl openhis-application -am |
<30 秒 |
| L2 全链路 | 六环检查清单(见下文) | <5 分钟 |
| L3 审查 | 你人工审查 diff | 10-30 分钟 |
📋 标准工作循环
开始会话
│
├→ 1. Init
│ ├── bash .harness/init.sh
│ ├── 读取 PROGRESS.md / feature_list.json
│ ├── git log --oneline -5
│ └── 确认编译通过
│
├→ 2. Plan
│ ├── update_plan / checklist_write 分解步骤
│ ├── 评估复杂度/风险
│ └── 设定检查点
│
├→ 3. Implement
│ ├── 一次只做一个功能
│ ├── 全链路检查清单核对
│ └── 增量修改,只动必要文件
│
├→ 4. Verify
│ ├── L1: mvn compile
│ ├── L2: 全链路数据流验证
│ └── 生成变更摘要
│
└→ 5. Cleanup
├── 运行 clean-state-checklist.md
├── 更新 PROGRESS.md + feature_list.json
├── git add + commit + push
└── init.sh 确认干净状态
🔗 全链路修复原则
修 Bug 时,不得"就事论事",必须走通完整的数据流全链路:
六环检查清单
1. 录入 → 前端有无输入入口?(弹窗、行编辑、表单...)
2. 保存 → 前端 → API → Controller → Service → Entity → DB,
每个保存入口都传了该字段吗?
3. 查询 → DB → Mapper XML(UNION ALL 子查询统一加)→ DTO → 前端展示
4. 修改 → 编辑回显 → 修改保存 → 正确更新?
5. 删除 → 状态变更会丢失该字段吗?
6. 关联 → 上下游(护士站、计费、打印、报表)需要同步改吗?
常见陷阱
| 陷阱 | 解决 |
|---|---|
| 只修主入口,批量保存/签发保存漏了 | 检查所有 Service 实现类 |
| 前端加了后端没传 | 逐个入口确认 |
| UNION ALL 只改一半 | 所有子查询统一加 |
| DTO 继承链没检查 | 检查父类/子类字段一致性 |
| 只测新增没测编辑 | 新增和编辑都要测 |
🚨 铁律(不可违反 — 来自实际 Bug 教训)
状态值一致性
涉及状态流转的 Bug,修改前必须列出完整链路并逐项检查:
- 枚举定义(如
SlotStatus、OrderStatus)的数值 - Service 层设置的状态值是否与枚举一致
- 查询/列表接口的状态映射是否覆盖所有枚举值
- 前端
STATUS_CLASS_MAP是否包含新状态 - 前端过滤条件(
v-if、v-for)是否兼容新状态 - 池/统计表的聚合 SQL 是否包含新状态值
禁止:只改一端不检查其他端。必须全链路对齐。
禁止删除源文件
- 绝对禁止删除项目中已有的 Java/Vue/SQL 源文件
- 编译错误 → 修复错误,不删除文件
- 重复文件 → 重构合并,不删除文件
- AI 幻觉文件 → 检查
git ls-tree baseline -- <file>确认后再删除 - 唯一例外:人类明确确认删除
全链路验证(状态流转 Bug 必做)
修复后按以下顺序验证,编译通过不等于修复完成:
① 数据库:SELECT status FROM table WHERE id = ? → 确认写入正确
② 后端接口:检查所有 if/switch 分支 → 确认映射正确
③ 前端显示:检查 STATUS_CLASS_MAP → 确认文本正确
④ 前端交互:检查 v-if/v-for/disabled → 确认按钮状态正确
⑤ 统计数据:检查聚合 SQL → 确认统计包含新状态
禁止修改已有公开方法签名
- 不能删除或重命名已有的 public 方法
- 不能修改已有方法的参数列表
- 需要新功能 → 添加重载方法
- 需要改行为 → 修改方法内部实现
状态变更影响面分析(来自 Bug #574→575 教训)
改任何状态枚举值前,必须执行影响面分析:
rg "原状态枚举名" --type java列出所有引用文件- 逐个检查:设置值?查询过滤?显示映射?统计聚合?
- 检查逆向流程:退号、取消、停诊是否兼容新状态
- 检查 XML mapper 中所有查询过滤条件
- 检查前端 STATUS_CLASS_MAP 和所有 v-if/v-for 条件 禁止:只改正向流程不验逆向流程
逆向流程验证(来自 Bug #575 教训)
涉及状态流转的 Bug,验证时必须覆盖:
- 正向:预约→签到→就诊→完成
- 逆向:退号、取消预约、停诊、退费
- 边界:并发操作、重复操作、异常中断 禁止:只测正向流程就标记"修复完成"
搜索所有相关代码路径
修复前必须用 rg 搜索:
rg "状态枚举名\|相关方法名\|相关字段名" --type java --type vue
确保不遗漏任何引用该状态的代码路径。
📐 代码风格规范
Java 后端
| 项目 | 规范 |
|---|---|
| 包结构 | com.openhis(业务)、com.core(核心) |
| 命名 | 类 PascalCase、方法 camelCase、常量 SCREAMING_SNAKE_CASE |
| 注解 | @Slf4j、@Data、@Service/@Controller/@Repository |
| 异常 | 统一异常处理,业务异常继承 RuntimeException |
| 缩进 | 4 空格,行 120 字符 |
Vue 前端
| 项目 | 规范 |
|---|---|
| 框架 | Vue 3 + Composition API + Element Plus + Pinia |
| 命名 | 组件 PascalCase、文件 kebab-case、变量 camelCase |
| 缩进 | 2 空格,单引号,行 100 字符 |
导入顺序
Java: java.* → javax.* → 第三方 → com.core.* → com.openhis.*
Vue: vue 相关 → 第三方 → @/ 别名 → 相对路径
🏗️ 开发约定
| 领域 | 约定 |
|---|---|
| API | RESTful,统一响应格式,Swagger 文档 |
| 数据库 | snake_case 命名,主键 id,软删除 valid_flag |
| 安全 | 所有 API 需权限验证,SQL 注入/XSS 防护 |
| 性能 | Druid 连接池,路由懒加载,虚拟滚动 |
⚙️ 关键配置
| 项目 | 值 |
|---|---|
| 后端端口 | 18080 |
| 前端端口 | 81 |
| API 前缀 | /openhis |
| Swagger | /openhis/swagger-ui/index.html |
| 后端配置 | application.yml / application-{profile}.yml |
| 前端配置 | vite.config.js / .env.* |
📈 过往 Bug 教训
| Bug | 教训 |
|---|---|
| #574 | checkInTicket() 状态值写错(BOOKED→应为CHECKED_IN),前端映射缺失,池统计漏计。根因:没走完整状态链路 |
| #574 | AI 智能体看到编译错误直接删文件,没检查 git baseline。根因:没验证文件来源 |
| #574 | 多次 fallback 修复改错文件(OrderServiceImpl),没触及真正问题(TicketServiceImpl)。根因:没用 rg 搜索所有引用 |
📈 成熟度追踪
| 等级 | 特征 | 本项目 |
|---|---|---|
| L1 初始 | 零星使用 AI 工具 | ✅ 已超越 |
| L2 管理 | 基础约束 + 反馈 + 控制 | ✅ 当前 |
| L3 定义 | 标准化、可复用 | 🔄 walkinglabs 5 子系统整合 |
| L4 量化 | 数据驱动优化 | ⏳ |
| L5 优化 | AI 自主优化 Harness | ⏳ |
📚 技能索引(Codex 内置)
| 技能 | 用途 |
|---|---|
$harness-engineering |
主方法论 — 约束 + 反馈 + 控制 + 持久 |
$walkinglabs-harness |
实战模式 — 5 子系统 + 模板 + 会话持续 |
$durable-execution |
检查点、幂等性、事件溯源 |
$closed-loop-testing |
质量门禁、测试策略、反馈循环 |
$constraint-design |
DSL 设计、策略模式、约束编排 |
$review-audit |
审查工作流、审计追踪、合规检查 |
$full-chain-fix |
全链路数据流修复 |
$karpathy-guidelines |
减少 LLM 编码常见错误 |
总纲: 你负责"做什么"和"为什么",Agent 负责"怎么做"和"做多好" 工作循环: Init → Plan → Implement → Verify → Cleanup