Files
railwaysystem/DEMO_RUNBOOK.md

15 KiB
Raw Permalink Blame History

SYFJGYD 学员管理系统 — Java 21 / Spring Boot 4 隔离 QA 运行手册

本手册仅对应 boot4-iot-fusion-archive 的 fix/iot-safety-hardening 本地候选版本。 原 RailwaySystem 和历史实验工程只读;不执行 Push、Merge、共享部署或硬件操作。

当前验收边界

当前分项结论(2026-10-15,Round 5V-7),三项必须分开: SOFTWARE_FUNCTIONAL_QA_PASSED=YES;Round 5V-6的SOFTWARE_FINAL_SIGNOFF=PENDING_OPERATING_ISOLATION已在 Round 5V-7完成受管QA运行/退出路径验证,现为PASS_MANAGED_QA_SCOPE; REAL_HARDWARE_VERIFIED=NO。 Round 5V-5 已经通过 Tailscale 跳板恢复访问,并对新融合后端完成登录、培训页、IoT页和既有Mock状态冒烟。 此前的断网不是撤销已通过的功能验收。两条旧授权的同步时间现已定位到旧实验进程的补偿写入, 不是新融合后端的正常Mock回执,也不能再标成“原因未知”。 完整时间线和脱敏归因见Round 5V-6; 实际隔离、观察窗口、故障退出和签署范围见Round 5V-7。

Round 5V-4 已在获准的新建离线 Kingbase V9 容器中实际恢复原生备份,完成 005 的提交、重复执行、异常/断连/锁超时回滚及原备份恢复演练,然后才对 railwaysystem_fusion_qa_20261013 执行 16 列 / 4 索引增量迁移。 11 项真实 Kingbase Service/Mapper/事务测试(含独立测试 JVM 强制中断)已通过。 当前 QA 后端、15 个 Chrome 路由与合成学员入住/调宿/退宿的 Mock 双回执闭环已实际验收。 详见 本轮软件验收记录。 Round 5V-4 收尾18:27实测服务器22/4321均超时,后端出现08001/EOF;当时状态为 BLOCKED_NETWORK,不是软件功能失败或迁移未执行。Round 5V-5 已恢复合法链路并完成最小冒烟, 且已停止该轮本机QA三进程和临时隧道。不要重做005、覆盖恢复或修改系统路由。 不能将 H2/替身测试、构建成功或登录页显示称为 Kingbase 事务/浏览器业务闭环验收。真实硬件验收始终未进行。 迁移前置、失败回滚和核验清单见 迁移计划。 不要执行 qa-bootstrap 全量初始化、清空测试数据、重建库、重置已有账号或序列。

1. 构建前提

  • Java 21(本机验证 21.0.2)、Maven 3.9.x;全部模块统一 release 21。
  • Node 22.23.2、npm 10.9.8(build_ui/.nvmrc / packageManager / lockfile)。
  • Python 3.9+、本机 redis-server(新实例只监听 loopback 的独立端口)。
  • 合法取得当前商业 JDBC 9.0.0;不向 Git 或公共 Maven 上传二进制。

从本工作树根目录执行(路径以实际 checkout 为准,不引用 RuoYi-Vue-master):

java -version
mvn -version
export KINGBASE_JDBC_JAR='/absolute/path/to/authorized/kingbase8-9.0.0.jar'
bash scripts/bootstrap/install-kingbase-jdbc.sh
bash scripts/bootstrap/check-kingbase-jdbc.sh
mvn -B -f RuoYi-Vue/pom.xml -pl ruoyi-admin -am '-Dtest=Round5s*,Round5vAccommodationAtomicityTest,RealIotSecurityGateTest,FaceExtractClientMockTest,CommandRespHandlerMockTest,DmsHttpClientTest,DmsTokenManagerTest,TrainIotLockAuthBridgeMockTest' -Dsurefire.failIfNoSpecifiedTests=false package
python3 -m unittest discover -s scripts/qa -p 'test_qa*.py' -v
mvn -B -f RuoYi-Vue/pom.xml -pl ruoyi-admin -am -Dtest=Round5v4MissingResourceTest -Dsurefire.failIfNoSpecifiedTests=false test

驱动私有坐标:cn.com.kingbase:kingbase8:9.0.0;SHA256: e439bd1c48ce654748c4f333b874a61465702ceb18f29ee017c3f9bc47738c23。 安装脚本先校验供应商文件,再用固定版本 Maven install plugin 安装到本机私有仓库。 ruoyi-admin/lib 不再是构建依赖来源。CI 由管理员合规预置同一私有依赖,缺失即失败。

cd build_ui
node --version
npm --version
npm ci --ignore-scripts --no-audit --no-fund
npm run build:prod
cd ..

不得用实验工程/node_modules1/node_modules2、服务器 symlink 或临时依赖目录替代 lockfile 安装。Quill 2 的转译配置与实验工程一致。Vue 2/CLI 4 的废弃依赖及旧版 node-ipc engine/ESLint peer 警告仍存在:本轮不做整套前端框架迁移,不声称无漏洞。

2. 凭据和只读身份检查

将 qa-bootstrap/round5v.env.example 的键名交给管理员,在 Git 外受保护文件中 填写真实 QA 配置并设置 owner-only 权限 0600。不要把密码放命令行、截图或报告。 脚本也兼容本机已有 ~/.railwaysystem-qa.env 中的 FUSION_QA_APP_PASSWORD 和 身份加密键,但不会复用其中可能指向旧库的 QA_DB_URL。

python3 scripts/qa/qa.py inspect --config /protected/round5v.env
python3 scripts/qa/qa.py snapshot --config /protected/round5v.env
python3 scripts/qa/qa.py verify-snapshot --snapshot-dir .qa-runtime/snapshot-REPLACE_WITH_ACTUAL_ID

固定目标:railwaysystem_fusion_qa_20261013;固定运行账号:fusion_qa_app。 检查使用只读 repeatable-read 事务并 rollback,记录版本、schema、列、索引和计数; 不打印业务行。快照含两张受影响表的敏感内容,仅存 .qa-runtime/(目录0700, 数据0600);其 XML 解析和 SHA 验证不等同于原生全库备份或数据库恢复演练。 服务器现有kingbase容器的 /home/kingbase/install/kingbase/bin/ 已确认具备 V009R003C018原生工具;现有kingbase管理角色可经容器本地连接认证,不需要给 fusion_qa_app提权。已完成原生备份,服务器及本机副本均在非Git目录,目录0700、文件0600。 最新位置、SHA及独立恢复解阻方案见 本轮记录。 sys_restore --file=/dev/null成功仅证明归档可完整读取,不能替代实际数据库恢复。 Round 5V-4 已另获明确授权,复用服务器现有 V9 镜像创建专用隔离恢复容器, 原生恢复及迁移/回滚均已实际验证;该授权不扩展到其他实例或数据库。 恢复证据及新建资源身份见本轮记录;不要把一次性演练脚本当作通用初始化脚本重跑, 不要复用共享库进行覆盖恢复。历史 Round 5V-3 文档保留为当时的真实阻塞记录。

3. 启停隔离 QA(目标库 005 已完成)

经跳板访问时的受管运行隔离(强制)

旧实验进程曾配置 DB_HOST=127.0.0.1 / DB_PORT=14321。端口没有监听者,不代表没有旧客户端等着重连。 Round 5V-5 在该端口建立隧道时,旧实验进程重新访问同一QA库,补偿任务写了两条旧授权的同步时间。 不要手工开放14321或用普通SSH转发替代下面的守卫;单纯更换端口不算隔离。

先只读核对现有Java进程、SSH监听者和非秘密数据源Host/Port。从本工作树根目录,终端A运行:

python3 scripts/qa/qa_isolation.py
# 默认选择临时空闲端口;需固定端口时可显式 --port 14327,但仍会检查客户端依赖。

工具首先持有14321的拒绝连接专用socket,不读写数据库协议、不连接任何上游; 已有未知监听者会导致安全失败,不停止它。新版SSH仅监听127.0.0.1的独占端口, 通过既有wzbmatebook链路访问目标4321;不继承SSH配置中的额外转发/本地命令,不复用共享ControlMaster。 身份认证只走既有合法密钥/Agent或交互密码提示,不将密码放参数、配置或日志。

必须看到QA_ISOLATION_READY后,才在终端B执行下面的启动命令。 Git外0600配置可不设置FUSION_QA_DB_URL,启动器会采用当前受管账本的确切URL; 如显式设置,必须与该账本的127.0.0.1端口和固定QA库完全匹配,否则拒绝。 只读inspect/snapshot在存在活动账本时也采用同一默认端点;无账本时允许其原有只读预检,但不允许应用start。

启动器核对守卫/SSH的PID、出生时间、cwd、命令、loopback监听归属及新端点Java客户端冲突。 看门狗持续核验并更新心跳;隧道退出或核验失败会清理同一租约的前端/后端/Redis, 再关自己的SSH,最后释放拒绝端口。账本/退出证据在.qa-runtime/,不进Git。 正常停止可先执行qa.py stop,再在终端A按Ctrl+C;只停止本任务所属资源,不按名字pkill。

旧实验进程不被停止、旧配置/账号不被修改;受管工作流以外的管理员手动重开14321仍可恢复旧链路, 这不是永久数据库权限撤销或系统级网络隔离。不得绕过受管入口进行QA写入演示。 若需要永久停用旧服务或调整账号,须另获对应批准。原始Kingbase全矩阵驱动仍锁定旧原地址, 不要拿当前隧道配置重跑它;本轮只做启动/登录/查询,不重做005或完整业务矩阵。

python3 scripts/qa/qa.py start --config /protected/round5v.env
python3 scripts/qa/qa.py frontend

默认端口:后端18096、前端18088、独立 Redis16389,仅监听127.0.0.1;端口占用即 失败,不杀旧进程、不改共享 Redis。启动器先确认目标数据库和16列/4索引存在, 缺迁移拒绝启动;列/索引的完整定义仍须按迁移计划人工核验。PID 输出不代表就绪。

安全值强制为 MQTT Mock=true / enabled=false / real-device-write-enabled=false / whitelist空 / protocol-verified=false / retry-task-enabled=false;人脸 HTTP关闭; OpenAPI、QA危险接口、Druid控制台和Quartz自动启动关闭;旧DMS关闭。 继承环境中的 Spring/IoT/DMS/JVM 注入覆盖被过滤,数据库 URL/账号由命令行固定。 启动器将构建包复制为 .qa-runtime/ruoyi-admin-<SHA前缀>.jar 并校验散列,防止 Maven 覆盖正在运行的嵌套 JAR。Druid URL 去除 JDBC 秒单位超时参数,池统一使用连接30秒/ 网络60秒;实际 Kingbase/Druid 探针验证了 60000ms,不能把 URL 的 15 当成池毫秒值。 JWT和独立Redis密钥由安全随机数首次生成至 .qa-runtime/runtime-secrets.env,0600, 以进程环境注入,不写源码/命令行;数据库及身份密钥仅取受保护配置文件。 不得为演示去打开真实门禁或危险接口。

curl --noproxy '*' --fail http://127.0.0.1:18096/captchaImage
# 真实 Chrome 访问 http://127.0.0.1:18088 ,使用管理员单独提供的 QA 账号。
python3 scripts/qa/qa.py stop

stop只处理本脚本账本中且进程命令身份仍匹配的PID,等待其退出再移除账本;不会清端口、杀其他Chrome、 停止实验工程或修改系统网络。JWT、访问日志、快照、浏览器证据均不进入Git。

4. 可复现的真实 Kingbase / Chrome 软件验收

仅在已迁移、已批准合成写入的同名 QA 库执行:

python3 scripts/qa/run_kingbase_tests.py --approve-synthetic-qa-writes --config /protected/round5v.env
# 真实 Kingbase 11 项;不使用 H2,不启动任何真实 MQTT / 人脸客户端。
# 合成数据有 R5V4 标识并保留审计,不删除既有数据,不重置序列。

Chrome 验收使用 Playwright CLI 技能(本轮实际 Chrome 155.0.8059.40),打开独立 round5v4 会话后运行:

python3 scripts/qa/browser_login.py --config /protected/round5v.env
# 若 QA 自身启用验证码:从实际截图识别后,加 --use-current-page --captcha ACTUAL_ANSWER;
# 不关闭验证码。本轮现有配置的 captchaImage 返回 captchaEnabled=false,未改其开关。
playwright-cli -s=round5v4 run-code --filename=scripts/qa/browser_regression.js
python3 scripts/qa/browser_fixture.py seed --approve-synthetic-qa-writes --config /protected/round5v.env

登录配置额外需要受保护文件中的 QA_ADMIN_USERNAME / QA_ADMIN_PASSWORD。登录驱动仅 在独立 about:blank 页内存中读取配置,关闭该页后填写登录表单,不把配置上传至应用。 CLI 不具备本机工具时使用技能自带 wrapper;不要为此修改工程依赖或系统浏览器设置。

seed 仅首次执行,生成 .qa-runtime/round5v4/browser-fixture.properties;已存在则拒绝覆盖。 按该文件学号在动态菜单 /equip/accommodation 搜索,依次入住、调房至同标识 B 宿舍、退宿。 每次操作后,先观察 AWAITING_ACK,然后执行受控回执驱动,再到授权和指令页面核对:

python3 scripts/qa/browser_fixture.py state --approve-synthetic-qa-writes --config /protected/round5v.env
python3 scripts/qa/browser_fixture.py ack --approve-synthetic-qa-writes --config /protected/round5v.env
python3 scripts/qa/browser_fixture.py verify --approve-synthetic-qa-writes --config /protected/round5v.env

驱动使用真实 Mapper/Service,只接受该文件合成人员与两把合成门锁、MOCK 来源及 round5v-local-mock 环境的当前 AWAITING_ACK 指令,不开放任何 HTTP 回执端点。 授权页按人员编号过滤,指令页按 fixture.marker(分组编号)过滤,应有四条 CONFIRMED 指令。 住宿 V2 模型只持久化分配与最后变更时间,页面已按真实字段标注,不捏造独立入住/退宿时间戳。

  1. 管理员真实登录、getInfo/getRouters、原品牌菜单和首页图表;培训核心查询。
  2. IoT九页:group/gateway/device/face/auth/command/accesslog/mqttlog/config, 必须验证组件渲染及实际QA查询,不能把SPA fallback HTTP200当作无404证明。
  3. 为本轮创建可追踪的合成业务样本,不复用/覆盖既有培训测试记录:报名、 住宿预分配、入住、调宿、退宿、授权意图与iotlocks.lock_command流水。
  4. 用实际Kingbase Mapper/Service/事务管理器覆盖迁移计划中的崩溃、并发、晚到ACK、 提交/回滚场景;外部MQTT和人脸只能是可控替身。危险Mock HTTP端点保持关闭, ACK由隔离的Service测试驱动,不通过开放生产式控制接口来换取通过。
  5. 受控Mock ACK成功只能证明软件闭环,不能证明真实门锁已授权或撤权。

现有 H2 与替身测试仍不等于真实数据库证据;本轮新增 Round5v4KingbaseIntegrationTest 才是上述 Kingbase 事务和应用进程中断验证的执行入口。

5. CI与硬件边界

.gitlab-ci.yml 已改为显式web+RUN_FUSION_VALIDATION=true才允许的验证流水线; Java21、私有JDBC预检及npm ci,无部署job。本轮未Push,也未触发/验证远程Runner。 本轮数据库、事务、启动和 Chrome 软件验收已经完成;仍未做真实门锁、人脸或网关验收。 硬件测试另需老师批准、确认协议中未验证的帧校验字段/回执及重传策略、单台白名单和人工核对流程。 商业驱动和恢复容器许可仅按现有合法 QA/试用环境验证,不代表生产部署许可。 应用账号既有的三张系统表过宽权限未扩大也未自动收回,应由管理员另行最小化。 任何安全前提不满足时,不得用旧实验后端或伪造 API 响应冒充新版本验收。