fix: 收口融合 QA 构建与验收安全基线
This commit is contained in:
1 parent
47bc6604e5
commit
5560a3ac04
28 files changed
+22947
-352
No files matched your search
@@ -0,0 +1,79 @@
|
||||
# Round 5V 验收记录 — 部分通过,迁移待授权
|
||||
|
||||
日期:2026-10-14;分支 `fix/iot-safety-hardening`;基线
|
||||
`47bc6604e53b841e9070b890e65e0a75df1c1e1c`。本文件描述本轮实际结果,
|
||||
不继承此前 Agent 的通过声明。最终本地提交号见 Git HEAD。
|
||||
|
||||
## 真实 Kingbase 结果
|
||||
|
||||
- JDBC 实际连接仅限 `192.168.139.218:4321/railwaysystem_fusion_qa_20261013`。
|
||||
账号 `fusion_qa_app`,KingbaseES V009R003C018,current_schema=public。
|
||||
只读 repeatable-read 事务结束 rollback;未执行 DDL、业务 INSERT/UPDATE/DELETE、
|
||||
全量初始化、GRANT、账号修改或共享库访问。
|
||||
- 迁移前 `iotlocks.lock_auth` 10条,`lock_command` 15条;最终只读复查不变。
|
||||
005的新增列/索引缺失,迁移未执行,`MIGRATION_WAITING_APPROVAL`。
|
||||
- 角色非 superuser/createdb/createrole,public/iotlocks 均无 CREATE,表属 kingbase。
|
||||
但3张 public 表具有额外 TRUNCATE/TRIGGER/REFERENCES,见迁移计划,待管理员审查。
|
||||
- 两张受影响表的 WebRowSet 私有快照10/15行,SHA256及XML解析通过:
|
||||
`.qa-runtime/snapshot-baf7eb8fede1`。不是原生全库备份,未做数据库恢复演练。
|
||||
- **八类生命周期/并发/跨事务 Kingbase 测试均未执行**。只读事务成功不是它们的证明。
|
||||
当前历史数据未被改写;新增默认 LEGACY/QUARANTINED 的实际迁移效果尚未验证。
|
||||
|
||||
证据:`scripts/qa/QaDatabaseProbe.java`、`.qa-runtime/final-database-inspection.log`、
|
||||
`.qa-runtime/snapshot-report.log`、[迁移/回退计划](ROUND5V_KINGBASE_MIGRATION_PLAN.md)。
|
||||
|
||||
## 构建与自动化结果
|
||||
|
||||
- Java 21.0.2 / Maven 3.9.x 打包成功;所有模块 release21,抽查 class major65。
|
||||
当前85项选定JUnit测试,失败0、错误0:原81项加4项住宿异常/事务声明测试。
|
||||
它们主要为H2/替身,不是Kingbase生命周期验收。
|
||||
- 修复入住/直接新增在住/调宿吞掉IoT持久化异常;checkIn增加事务边界。
|
||||
`Round5vAccommodationAtomicityTest`覆盖入住/调宿/退宿异常传播及事务声明。
|
||||
新增修复的真实Kingbase回滚语义待验证,未夸称原子性已通过。
|
||||
- 11项Python QA工具测试通过:目标库白名单、URL凭据拒绝、配置权限、无Shell
|
||||
执行、过滤继承覆盖、迁移缺失不启动、强制安全参数和PID复用拒绝。
|
||||
- JDBC已从授权本机文件校验后安装为私有Maven依赖9.0.0,正常打入Boot JAR,
|
||||
不再依赖systemPath;未提交供应商二进制。安装/预检脚本从旧8.6.0同步至9.0.0。
|
||||
- 前端Node22.23.2/npm10.9.8,`npm ci --ignore-scripts --no-audit --no-fund`
|
||||
实际安装1753依赖,生产构建通过。核心版本对齐实验工程,新增受跟踪lockfile。
|
||||
初次构建暴露Quill2语法转译缺失,补回实验已有transpileDependencies后通过。
|
||||
旧Vue2/CLI4废弃依赖、node-ipc engine/ESLint peer警告未在本轮整体迁移。
|
||||
- 登录表单残留固定测试账号/密码预填已清空,未重置任何数据库账号。
|
||||
|
||||
证据:`RuoYi-Vue/ruoyi-*/target/surefire-reports/`、
|
||||
`.qa-runtime/backend-build.log`、`.qa-runtime/frontend-build.log`、
|
||||
`.qa-runtime/qa-tools-tests.log`;准确复现命令见根目录DEMO_RUNBOOK.md。
|
||||
|
||||
## 实际 Chrome 与运行结果
|
||||
|
||||
- Playwright使用已安装的 `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`,
|
||||
UA Chrome155。实际打开生产dist(loopback18088),可见原SYFJGYD品牌登录页。
|
||||
截图 `output/playwright/round5v-login-backend-blocked.png`,已目视检查。
|
||||
- 新后端未启动:`qa.py start`执行真实目标库预检后以MIGRATION_REQUIRED拒绝,
|
||||
未启动Redis或Spring Boot。前端的captchaImage如实返回502,没有替身API或旧后端。
|
||||
因此管理员登录、动态路由、首页图表、培训/IoT API、九页功能、住宿E2E均未验收。
|
||||
九个IoT页面源码被生产构建编译不代表页面运行无404。
|
||||
- 独立端口方案18096/18088/16389,实际只为登录页检查启动了前端服务;
|
||||
交付前关闭本任务前端和本任务Chrome会话。既有Java PID51901/53305未被停止。
|
||||
|
||||
## 配置与工程边界
|
||||
|
||||
- 所有安全默认保持关闭真实MQTT/设备写入、空白名单、关闭人脸HTTP、OpenAPI、
|
||||
QA危险接口、Druid控制台、补偿任务和Quartz自动启动;旧DMS关闭。
|
||||
运行器不清端口、不杀既有进程、不修改共享Redis或Mac网络;JWT/Redis密钥在
|
||||
私有0600外部运行配置中生成并仅经环境注入,数据库/身份密钥从受保护文件读取。
|
||||
- DEMO_RUNBOOK已移除不存在脚本/错误路径/固定登录口令/100%真实执行等声明,
|
||||
提供实际存在的inspect/snapshot/start/frontend/stop入口和未通过项。
|
||||
- CI YAML静态解析通过:Java21、私有JDBC预检、npm ci,显式web+变量门禁,
|
||||
无部署job、无push自动流水线。本轮未Push、Merge、触发远程CI或部署;Runner未验证。
|
||||
- 变更范围私钥/常见Token模式扫描无发现,未将快照/日志/浏览器缓存/驱动加入Git。
|
||||
原工程无tracked diff;历史实验工程clean,未改写两者源码或历史。
|
||||
|
||||
## 仍需完成
|
||||
|
||||
1. 明确仅针对目标QA库的005授权、合规原生备份及回退演练,协调该库写入窗口。
|
||||
2. 授权后执行并核验增量迁移、历史LEGACY隔离和实际Kingbase八类事务测试。
|
||||
3. 启动新隔离后端,以真实Chrome完成管理员/菜单/首页/九页/API/住宿Mock闭环。
|
||||
4. 管理员审查3张表额外权限;老师协议/单台现场测试批准仍独立待办。
|
||||
|
||||
READY_FOR_SUPERVISED_HARDWARE_TEST = false。Mock/H2成功不等于真实门锁联调成功。
|
||||
@@ -0,0 +1,86 @@
|
||||
# Round 5V — isolated Kingbase migration and rollback gate
|
||||
|
||||
## Scope and observed prestate
|
||||
|
||||
2026-10-14 read-only JDBC probe: database `railwaysystem_fusion_qa_20261013`, user
|
||||
`fusion_qa_app`, KingbaseES `V009R003C018`, current schema `public`, search path
|
||||
`"$user", public`. Application account is not superuser and cannot create databases
|
||||
or roles. Existing `iotlocks.lock_auth`: 10 rows; `lock_command`: 15 rows. Existing
|
||||
sequence-backed primary keys, unique auth number, unique person/device/type, and
|
||||
unique command number remain unchanged. Round 5S columns/indexes were absent.
|
||||
No migration authorization is inferred from an instruction conditional on approval.
|
||||
The application role has USAGE but not CREATE on both schemas and does not own
|
||||
the affected tables. However, existing grants on `public.sys_menu`,
|
||||
`public.sys_notice_read`, and `public.sys_role_menu` include TRUNCATE, TRIGGER and
|
||||
REFERENCES. Administrator least-privilege review is pending; no grants were changed.
|
||||
|
||||
## Static review of 005
|
||||
|
||||
`RuoYi-Vue/sql/iot/005_round5s_execution_safety.sql` only adds nullable metadata,
|
||||
NOT NULL defaults for mode/version/state, two unique intent-key indexes, and two
|
||||
recovery indexes. All objects are schema-qualified; no sequences are reset, no
|
||||
existing business uniqueness is removed, no data is deleted, and there is no REAL
|
||||
backfill. Existing records must become `LEGACY / 0 / QUARANTINED`, not trusted Mock
|
||||
or REAL. Two nullable intent-key indexes must allow multiple nulls on this actual
|
||||
Kingbase instance; validate this with rollback-only synthetic rows after approval.
|
||||
|
||||
`ADD COLUMN IF NOT EXISTS` and `CREATE INDEX IF NOT EXISTS` are PostgreSQL-style
|
||||
syntax supported by the H2 substitute, **not yet a Kingbase execution result**.
|
||||
Do not use existence checks as proof of correct definitions: inspect names,
|
||||
types, nullability, defaults and index uniqueness/column order before/after.
|
||||
Use a bounded lock timeout and a single explicit transaction. DDL rollback and
|
||||
concurrent unique-index behavior still require actual Kingbase verification.
|
||||
Application sessions use `iotlocks, public, pg_catalog, sys_catalog`; do not change
|
||||
the global/database/user search path or accidentally query system `sys_user` views.
|
||||
|
||||
## Required approvals and backup
|
||||
|
||||
1. Record authorization explicitly naming this database, migration 005 and its
|
||||
SHA256, maintenance window, account and approving administrator. App-account
|
||||
credentials do not grant authority to migrate; do not expand its privileges.
|
||||
2. Inspect active sessions in this target only. Have owners pause *only* writers
|
||||
targeting this QA database. Do not kill the experiment, teacher or shared service.
|
||||
3. Run `python3 scripts/qa/qa.py snapshot --config /protected/qa.env`. It captures
|
||||
both affected tables with JDBC metadata in a repeatable-read **read-only**
|
||||
transaction, private WebRowSet XML and SHA256 manifest under `.qa-runtime/`.
|
||||
These contain credentials/personal data from rows: never commit, print or upload.
|
||||
This is an affected-table snapshot, **not a native full-database backup**.
|
||||
4. Before executing DDL, the administrator must also produce an authorized native
|
||||
Kingbase full QA backup (schema/data/sequences/ACLs) using the matching licensed
|
||||
vendor tools and validate it in an approved isolated restore destination. No
|
||||
native backup utility or restore destination is assumed or provisioned here.
|
||||
Do not use a mismatched PostgreSQL client or restore into any shared database.
|
||||
|
||||
## Execution and failure rollback (not executed in this round without approval)
|
||||
|
||||
With an approved migration account, enforce `current_database()` equals the exact
|
||||
target before any change. Begin a transaction, set a local lock timeout (5s),
|
||||
capture prechange schema/index definitions and row counts, execute only migration
|
||||
005, then verify the following **before commit**:
|
||||
|
||||
- All 16 new columns have the reviewed types/defaults/nullability; index definitions
|
||||
match exactly; existing constraints/sequences and row counts are unchanged.
|
||||
- Existing rows have `execution_mode='LEGACY'`, `intent_version=0`,
|
||||
`execution_state='QUARANTINED'`, null intent key/environment/action/attempt time.
|
||||
- No existing row is REAL, READY or eligible for automatic dispatch.
|
||||
- A savepoint-based synthetic insert validates null uniqueness and a duplicate
|
||||
nonnull intent key is rejected; roll back the synthetic savepoint. Sequence gaps
|
||||
from rolled-back inserts are expected and must not be "repaired" by setval.
|
||||
|
||||
Any error: **ROLLBACK the entire DDL transaction**, inspect from a second connection
|
||||
to prove original schema/counts/data fingerprints are unchanged. If actual Kingbase
|
||||
DDL is not transactional, stop; never guess or issue automated DROP/CASCADE.
|
||||
After commit, prefer keeping the additive schema and stopping the new application
|
||||
over a destructive down migration. Rollback to old software is NOT automatic once
|
||||
new lifecycle rows exist. Administrator-reviewed selective/native restore requires
|
||||
fresh approval and a proven isolated restore; no generic destructive down.sql.
|
||||
|
||||
## Required acceptance after migration
|
||||
|
||||
Run production XML Mappers, real Services and `DataSourceTransactionManager` using
|
||||
`fusion_qa_app`, with MQTT/face transport substitutes only. Persist synthetic QA
|
||||
rows with unique run marker; preserve existing training rows and history. Cover
|
||||
check-in/out intents, commit-before-command crash, never-attempted restart recovery,
|
||||
unknown outcome -> MANUAL_REVIEW without resend, unique-intent concurrent claims,
|
||||
late ACK vs new version, cross-transaction visibility/rollback. Preserve test rows
|
||||
for audit or explicitly scoped cleanup only. H2 results cannot satisfy this gate.
|
||||
Reference in new issue
Block a user