OA 开发验证门禁
目的
本技能让 OA 开发验证保持可复现:
- 后端重启是代码/SQL 预检之后的受控门禁,不是“保存文件就自动算生效”。
- 通过官方 Edge/浏览器插件捕获真实动作证据:Network、console、toast/modal、截图、下载、后端日志和必要的数据库读回。
- 页面报错、请求报错或接口信息核对时,先读取对应后端 IDEA/Tomcat/Spring 控制台或文件日志,再做数据库探针、源码推断或配置修复。
- 证明重启后的后端健康,并且确实服务于当前要验收的代码路径。
真实点击、延迟错误、生成下载、副作用分类或共享页面上下文保护,交给 oa-real-action-evidence 做详细动作窗口循环。
代码与产物边界
本门禁可能编译代码、更新 target/classes、触碰 .reloadtrigger 或读取日志,但这些运行时产物不等于可提交源码。涉及源码修复、暂存、提交、还原或清理时,遵守 oa-business-logic-compare 的“任务边界、提交边界与还原边界”;本门禁不得为了证明运行时新鲜而 stage .idea、target、日志、下载文件或证据报告,也不得还原归属不明的源码差异。
可执行闭环原则
本门禁优先寻找可运行路径,而不是直接报告阻断。凡是页面动作会发送到后端,且任务是在排查、验证或核对该请求/接口,第一优先级都是对应后端运行时日志;只有命令侧日志链路已尝试或有证据证明不适用后,才使用 runtime-stale、restart-unproven 或 Computer Use 兜底。
本工作区已验证的命令侧链路:
- 编译或更新真实变更 class/resource 到
target/classes。 - 验证当前 8090 Java 进程由 IDEA 启动,并带有 DevTools 参数。
- 必要时更新真实 classpath 产物时间戳,再写入
back/office-web/target/classes/.reloadtrigger。 - 读取 Logback 文件,确认新鲜的
thread="restartedMain"和NfrcApplication startup。 - 探测
http://localhost:8090/portal/common/captchaImage,要求 JSONcode:"0"/message:"操作成功"。 - 重跑需要后端刷新的真实 Edge 动作。
不要停在“IDEA console file 未配置”。可运行日志路径是 IDEA 启动 JVM 产生的 Logback 文件。只有确实配置了保存 console 输出时才读 IDEA console 文件;只有文件/进程证据缺失或矛盾且需要可见 IDEA console 时,才用 Computer Use。
跨技能交接契约
本门禁负责后端/运行时新鲜度和后端请求日志取证,不代替 SQL gate 或浏览器动作证明:
- 输入:后端面对文件或重载原因、适用时的编译/SQL gate 结果、要复测的 endpoint/action、请求 URL/method/status/timestamp、后端端口或系统线索、已知进程事实、调用方最后失败的 Network/log 症状。
- 输出:运行时证据行,包含时间戳、编译/预检结果、后端 PID、父 IDEA/Tomcat/Spring 进程、DevTools/运行配置状态、trigger 文件路径/时间、classpath 产物或编译输出、Logback/Tomcat/IDEA console 启动/失败/请求日志行、探活 URL/body 判定和最终运行时状态。
- 返回状态:
runtime-fresh、runtime-verified-api-only、runtime-stale、restart-unproven、compile-failed、sql-gate-required、probe-failed、computer-use-fallback-required。 - Mapper/SQL 改动且没有 SQL gate 报告时,返回
sql-gate-required,先调用或交给oa-real-sql-gate,再重启。 - 运行时为
runtime-fresh时,把精确 action/API 交回oa-real-action-evidence或oa-real-browser-driver重跑。运行时新鲜不等于功能验收。 - 只有轻量未认证 API 探活成功时,除非用户请求的正是该 API,否则返回
runtime-verified-api-only,并写清仍需真实浏览器/动作复跑的 endpoint。 - 运行时仍陈旧或无法证明时,停止业务点击,返回缺失证据或兜底路径。
- 需要可见 IDEA console 证据时,Computer Use 只是兜底证据通道,要与 Logback/进程证据分开。
门禁流程
0. 后端请求日志优先门禁
当真实页面动作、弹窗、下载、保存、搜索、列表加载或接口核对会发送后端请求时,先完成本门禁,再做数据库探针或源码结论:
- 从浏览器 Network 取请求 URL、method、status、payload 摘要和点击时间窗口;没有 Network 时先说明是前端 handler/禁用/校验问题。
- 识别对应后端,不凭记忆猜:新 OA 通常是 8090 Spring Boot;老 OA 通常是 9099 Tomcat/JSP;其他端口按 Network URL 和监听进程确认。
- 读取对应后端运行日志:
- 新 OA:IDEA 启动的 Spring Boot Logback 文件;确有保存 console 输出时可读 IDEA console 文件。
- 老 OA:IDEA/Tomcat console 保存文件、Tomcat
catalina.base下日志;无文件时用 Computer Use 只读查看可见 IDEA/Tomcat 控制台。 - 其他后端:先用监听端口、进程命令行、父进程和 run configuration 确认日志来源。
- 日志窗口必须覆盖本次请求时间;至少搜索请求路径、业务主键、异常关键词、SQL/ORA、JSP/Servlet、Controller/Mapper/方法名。
- 只有拿到后端日志证据,或证明当前日志通道不可达并记录兜底尝试后,才进入 DB 元数据/FRAME_PAGE/Mapper/配置探针。
codex_app.read_thread_terminal不是 IDEA/Tomcat/Spring 控制台,除非本线程明确运行了对应后端进程;不能用它替代后端日志。
1. 分类动作
frontend-only:Vue/CSS/下载处理,不需要后端重启。backend-code:Java、Service、Controller、模板或配置改动,需要编译和后端重载。mapper-sql:MyBatis XML、DAO、SQL 或数据库面对代码。任何重启结论前先读并执行oa-real-sql-gate。backend-request-check:任何页面请求、接口信息核对、列表加载、搜索、下载、保存、弹窗打开后需要验证或排查后端行为。第一步执行“后端请求日志优先门禁”。browser-failure:点击后出现用户可见失败。猜测前先捕获 Network/console 证据,并读取对应后端 IDEA/Tomcat/Spring 控制台或文件日志。old-oa-jsp-failure:老 OA 9099/JSP/FRAME 点击后出现“服务器程序出现错误”、空白 iframe、JSP 编译错误或 Struts forward 错误。第一动作是读取老 OA 运行控制台/日志和浏览器 Network/console,然后才查 FRAME_PAGE、JSP 同步、Oracle SQL/函数。unknown-side-effect:副作用和恢复计划未知前不要执行。
用户明确要求先解决 IDEA 重启或日志读取时,暂停无关业务验证,先完成本门禁。运行时重载路径未证明前,不要漂移到页面修复。
1.1 老 OA 9099/JSP 错误页快速路径
老 OA 与新 OA Spring Boot 门禁分开处理。遇到老 OA localhost:9099、cpzx-oa、JSP/FRAME、Struts forwardName 或 Phr 弹窗错误页时:
- 不调用
oa-real-sql-gate;它只验证新 OA MyBatis。 - 不把
codex_app.read_thread_terminal当作 IDEA/Tomcat 老 OA 控制台。该工具只读当前 Codex 线程 terminal;除非本线程明确挂接了老 OA 运行控制台,否则结果为“不适用”。 - 先找真实运行通道:
- 若 IDEA/Tomcat console 保存到了文件,读取保存文件并验证
LastWriteTime晚于本次点击。 - 若没有保存文件,用 Computer Use 兜底读取可见 IDEA/Tomcat 控制台,只读观察,不点击 Stop/Rerun/Debug/Run。
- 同时用官方 Edge 插件读取弹窗/iframe 的 Network、console、URL、状态码和页面文本。
- 若 IDEA/Tomcat console 保存到了文件,读取保存文件并验证
- 控制台/日志要优先搜索:
Exception、JasperException、ServletException、SQLException、ORA-、NoSuchMethodError、ClassNotFoundException、NullPointerException、forwardName、FRAME_PAGE、目标 JSP 文件名和业务主键。 - 只有拿到运行时错误线索,或证明控制台/日志当前不可达后,才转到数据库只读探针检查
FRAME_PAGE、表字段、函数状态和 SQL 解析。 - 如果数据库探针先发现明确缺口,也必须回到浏览器/控制台复验错误页是否消失;不能把
FRAME_PAGE补齐读回当作页面验收。
2. 重启前预检
- 后端代码改动时,从
E:/IdeaProjects/oa/hrtac-oa/back运行能证明变更模块可编译的最窄命令,通常是:
mvn -pl office-web -am -DskipTests compile
- Mapper XML 或 SQL 改动时,按真实开发/测试数据源和回滚规则运行
oa-real-sql-gate。 - 生成文档/模板变化时,确认目标资源在运行时 classpath 或打包模块路径中存在。
- 预检失败时不要重启 IDEA 后端;先修预检失败。
3. 进入重载门禁
- 简单 Java 方法体变更且 IDEA 确认 HotSwap 时,可以接受方法体热替换。但 bean 定义、方法签名、Mapper XML、资源/模板、配置、依赖或注解变更不能只靠 HotSwap。
- 首选路径:使用 Codex 命令侧进程检查、编译输出、Spring DevTools trigger-file、Logback 证据和 HTTP 探活,在不手动点击 UI 的情况下重载并验证 IDEA 启动的后端。仅当运行中 JVM command line 证明
spring.devtools.restart.enabled=true和spring.devtools.restart.trigger-file=.reloadtrigger都启用时,该路径才有效。缺任一参数时,先走 run configuration 启用路径;完成前只能记录runtime-stale。 - 后端改动不能仅凭编译或触碰
.reloadtrigger视为通过。证明必须包含:IDEA-owned Java PID、DevTools 参数、trigger 时间戳、该时间之后的新鲜 Logback startup/restartedMain 证据和轻量 8090 探活。 - DevTools reload 需要但未配置时,说明缺少的 VM options;用户授权修改本地 IDEA 配置时,只改本地 ignored 的 IDEA run configuration,加入:
-Dspring.devtools.restart.enabled=true -Dspring.devtools.restart.trigger-file=.reloadtrigger
然后通过 IDEA 重启一次,让后续可由命令触发 reload。
- 修改 IDEA Run/Debug Configuration 后,不要用当前 Debug 工具窗口底部的
Rerun按钮证明配置生效。本工作区观察到该路径可能复用旧 debug session 快照,不会重新读取新 VM options。应停止当前NfrcApplicationsession,再从顶部工具栏启动当前NfrcApplicationDebug configuration,然后用jcmd验证。 - 命令侧 reload 不可用、未配置或证据矛盾时,记录命令侧事实后才使用 Computer Use。检查 IntelliJ IDEA 中
E:/IdeaProjects/oa/hrtac-oa窗口,选择精确的NfrcApplicationrun/debug console,读取可见错误/启动状态。确需重启时,只点击该 configuration 的 IDEA 自身 rerun/start 控件。控件不清楚时先查官方 JetBrains IDEA 文档,不要猜图标。 - 除非当前会话启动了精确进程,并有 PID/命令/工作目录直接证据,否则不要杀 Java 进程或释放端口。归属不明时询问。
4. 证明后端就绪
不要把 Computer Use 当作常规日志读取方式。常规路径是命令侧文件/进程证据。
先识别当前活动后端,而不是依赖记忆路径:
- 找到监听
8090的进程。 - 读取 owning Java 进程 command line 和父进程。
- 确认父进程是
idea64.exe,main class 是com.nfrc.apps.NfrcApplication,classpath 指向E:/IdeaProjects/oa/hrtac-oa/back/.../target/classes。 - 用
jcmd <pid> VM.command_line或jcmd <pid> VM.system_properties检查spring.devtools.restart.enabled和spring.devtools.restart.trigger-file。
再读取 IDEA 启动后端写出的活动 Logback 文件。正常路径是 JVM 产生的运行时文件日志,不是 Computer Use,也不是 Codex terminal。
活动 Logback 文件推导步骤:
Get-NetTCPConnection -LocalPort 8090 -State Listen得到 Java PID。Get-CimInstance Win32_Process -Filter "ProcessId=<pid>"得到父 IDEA PID 和 command line。jcmd <pid> VM.command_line/jcmd <pid> VM.system_properties得到user.dir、classpath、DevTools 参数、active profile/config 线索。- 读取
back/office-web/src/main/resources/logback-spring.xml中${hrtac.log.path}/${hrtac.log.name}.${HOSTNAME}.log。 - 读取 active profile config,通常是
back/office-web/src/main/resources/application-dev.yml中的hrtac.file.root_path、hrtac.log.path、hrtac.log.name。 - 用
Test-Path/Get-Item验证路径,并要求LastWriteTime与活动进程/重启窗口匹配。再用Get-Content -Encoding UTF8 -Tail ...或Select-String -Encoding UTF8 -Path ...读取。
历史验证过的命令模式:
Select-String -Encoding UTF8 -Path '<active-logback-file>' `
-Pattern 'restartedMain|NfrcApplication startup|APPLICATION FAILED TO START|BeanCreationException|BindingException|UnsatisfiedDependencyException|NoSuchMethodError|ORA-|port|端口' |
Select-Object -Last 80 | ForEach-Object { $_.Line }
该文件可用于证明 DevTools reload(restartedMain + 新鲜 NfrcApplication startup),检查真实 /portal/... 请求、SQL interceptor 输出、响应体和后端错误。
IDEA 保存的 console 输出文件只在 run configuration 确实配置时使用。检查 .idea/runConfigurations/NfrcApplication.xml 和 .idea/workspace.xml 是否有 SAVE_OUTPUT_TO_FILE、OUTPUT_FILE、fileOutputPath、saveOutput、LogFileOptions 或等价设置。有路径时验证 Test-Path、LastWriteTime 和当前进程时间,再读取。没有配置时,不要声称存在 IDEA console 输出文件。
idea.log 只用于 IDEA runner/configuration 错误、profiler 参数、action 失败和插件错误。不要把 idea.log 当 Spring Boot 应用 console,除非它确实包含所需应用输出。
文件日志搜索应覆盖启动和失败标记:Picked up JDK_JAVA_OPTIONS、Picked up JAVA_TOOL_OPTIONS、spring.devtools.restart.enabled、restartedMain、NfrcApplication startup、APPLICATION FAILED TO START、BeanCreationException、BindingException、UnsatisfiedDependencyException、NoSuchMethodError、ORA- 和端口绑定错误。
报告中要分清证据通道:
- Logback 文件:IDEA 启动后端的应用运行时日志,是这里常规后端诊断来源。
- IDEA 保存 console 输出文件:只有 run configuration 真的保存时才是磁盘上的 IDEA console 文本。
idea.log:IDEA 进程/runner 日志。codex_app.read_thread_terminal:仅 Codex 线程 terminal,不是 IDEA Debug console。
如果没有 IDEA 保存 console 输出配置,而用户希望未来能用文件读取字面 IDEA console 文本,先说明并征求授权,再修改本地 IDEA run configuration 启用“Save console output to file”。本地 .idea 配置不是产品代码,除非用户明确要求,不要 stage。
Computer Use 仅为最后兜底:当文件/进程证据缺失或矛盾,或用户明确说可见 IDEA console 中有文件没有的信息时使用。先读 computer-use 技能,目标锁定精确 hrtac-oa IDEA 窗口,被动检查截图/文本;只是读日志时不要点击 Stop/Rerun/Debug/Run。
成功必须同时满足:
- 有晚于 restart trigger 的 startup 行,例如
NfrcApplication startup。 - 8090 探活成功。
- 没有同一窗口内的致命启动失败。
- 运行时 classpath/资源与变更文件对应。
5. 重跑真实动作
后端新鲜后,回到原失败动作:
- 用同一个或健康兜底 Edge tab。
- 重跑原按钮/下载/保存/搜索。
- 捕获 Network、console、可见消息、后端日志和文件/DB 证据。
- 若仍失败,把失败交回
oa-real-action-evidence或业务技能继续分析,不要把后端新鲜误当成功能验收。
数据库与副作用边界
- Mapper XML 或 SQL 变更必须先过
oa-real-sql-gate。 - 生产库或身份不明库只读。
- 开发/测试库写入也必须有样例、备份、预期影响、读回、恢复和恢复验证。
- 不要在本门禁里自行发明 DML 恢复方案;交给 SQL gate。
报告模板
报告至少包含:
| 项 | 内容 |
|---|---|
| 分类 | frontend-only / backend-code / mapper-sql / backend-request-check / browser-failure / old-oa-jsp-failure / unknown-side-effect |
| 编译/预检 | 命令、结果、失败摘要 |
| SQL gate | 报告路径和状态,如适用 |
| 进程 | 实际后端端口 PID(新 OA 通常 8090、老 OA 通常 9099)、父 IDEA/Tomcat/Spring PID、main class、classpath 或 catalina.base |
| DevTools | spring.devtools.restart.enabled、.reloadtrigger |
| Trigger | 文件路径和时间戳 |
| Logback | 日志路径、新鲜 startup/failure 行 |
| 对应后端请求日志 | URL/method/status/timestamp、日志通道、命中日志行或不可达证明 |
| 探活 | URL、状态、body 判定 |
| 重跑动作 | Edge tab、请求、可见消息、文件/DB 证据 |
| 最终状态 | runtime-fresh 等精确标签 |
禁止事项
- 禁止在 SQL gate 失败或缺失时重启后端并声称 SQL 已安全。
- 禁止把旧后端上的浏览器成功当成新代码验收。
- 禁止只凭 IDEA 可见运行中图标断言后端新鲜。
- 禁止杀归属不明的 Java、IDEA、浏览器或系统进程。
- 禁止关闭用户原有标签页或归属不明标签页。
- 禁止在报告中输出数据库凭据、token、cookies、Authorization、Set-Cookie 或敏感 payload。
- 禁止把 unauthenticated probe 升级成完整业务流程验收。
- 禁止提交本地
.idea配置、生成日志、target、下载文件或证据报告,除非用户明确要求。
完成标准
- 后端面对变更已编译或明确不需要编译。
- Mapper/SQL 变更已有 SQL gate 结论。
- 需要重载时,DevTools/重启证据新鲜且可审计。
- 页面/接口动作涉及后端请求时,已读取对应后端 IDEA/Tomcat/Spring 控制台或文件日志,或明确证明日志通道不可达并说明兜底尝试。
- 8090 探活成功,且无启动失败。
- 原真实 Edge 动作已重跑,或明确交回下一步动作证据技能。
- 所有未完成项都有精确阻断原因和下一步。