Repository navigation
release: 15.1 QA test checklist — framework 15.1.0 + console (objectui 14.1) #3072
Description
Activity
✅ E7 级联选项 — 已验证 + 修复了一个 bug
发现 bug:在真实创建/编辑表单里,B3 级联 select(#2284 / #1583)失效——选了 Country 后 Province 永远停在 "Select country first" 不解锁。
根因:form 渲染器只对
DATA_SOURCE_FIELD_TYPES(lookup 等)注入实时表单记录dependentValues;注册的 option widget(field:select/radio/multiselect)被排除,stripRegisteredFieldProps在到达 SelectField 前就把它 strip 了。加上SchemaRendererContext从无formValues兜底,SelectField 的dependsOn门永远看不到父字段。builtincase 'select'回退路径正常,但 ObjectForm 实际走的注册field:select路径坏了——所以此前的form-cascading-select测试(用 builtin 路径)没抓到。修复:objectui#2620 — 把
dependentValues也转发给 option 字段(镜像 lookup 修复 #2215/#2216)。验证(objectui console dev 连真后端,真实 SelectField widget):
- Province 未选国家时 gated ✅
- Country=China → 只列 Zhejiang/Guangdong ✅
- Country→US → 重过滤成 California/Texas ✅
- 红/绿回归测试钉死(驱动注册 field:select 路径)✅
顺带验证 F6 unsaved 守卫(Esc 关表单时弹"放弃更改?")✅
影响面说明:该 bug 早于 15.1(#2284 引入,约 7 月初),非本次回归,但 15.1 主打 B3 级联,应带上此修复。opt-in live e2e
cascading-options.spec.ts不在默认 CI,所以此前无人发现。
回归门批量结果
- ✅
pnpm build71/71,console dist == .objectui-sha - ✅ dogfood 全套 52 文件 / 285 tests 全绿(覆盖 A1–A6/A8/A10、C3/C4、B1 等安全+自动化项)
- ✅
pnpm check:release-notesOK - ✅
os validateshowcase 三道门通过(21 objects / 4 views / 23 flows …)
第二轮验证结果(浏览器 + API)
✅ Console / Studio 浏览器验证
- E9 toast 不崩页 + E12 Create User ✅ — Setup→用户→创建用户:对话框 param 全中文化(i18n: console action-dialog param labels are untranslatable —
os i18n extractskipsactions[].params#3030);同时勾"生成临时密码"且填显式密码 → 成功建用户、无 400(auth: create-user 400s when a password is typed whilegeneratePasswordkeeps its default (true) #3031 显式密码胜出),结果弹窗"User Created"干净渲染(无 React Add i18n support for homepage (国际化官网首页) #31 崩页) - F1 CEL formula 编辑器 + 类型推断 ✅ — QA Scratch 包 scratch_deal 对象加"计算·公式"字段:输入
1 + 2 * 3→ 实时显示"✓ CEL 有效"+"∑ 返回类型:数字";输入非法 CEL → 红框报错含位置+修复提示。此 CelPredicateField 基础设施 F2/F3/F4 共用(docs(audits): Studio package-create UX dogfood — browser walkthrough findings #2609/feat(messaging): digest batching for notifications (ADR-0030 P3b-2) #1582) - F5 OWD 总览入口 + F8 AccessExplainPanel ✅ — Access pillar 每对象带 OWD 徽标(Public read/write、Private、Ext Public read 等,tooling: migrate Node version management from nvm to Volta (multi-repo) #2508 深链);"解释访问权限"面板含记录粒度选择器(记录 id + 选择按钮)+ 逐层归因说明(权限集→岗位→绑定链+OWD/共享)
- F7 只读包锁定 ✅ — showcase(已安装只读包):权限矩阵 189/189 复选框全 disabled、无可用 Save、header+package-picker+底部共 5 处只读徽标/提示
- F12 spec 驱动建包 + namespace 前缀 ✅ — 单一 modal(显示名/ID/命名空间/版本/类型/描述);命名空间从包 ID 自动派生(com.qa.scratch→scratch);建对象输"deal"→自动前缀为 scratch_deal(ci: bump downstream hotcrm smoke ref to v1.2.1 (ADR-0085 digestion) #2524)
- F6 unsaved 守卫 ✅ — 编辑中 Esc 关表单弹"放弃更改?"(继续编辑/放弃)
✅ API / CLI 验证(curl + cookie)
- G3 packages REST ✅ — POST 重复 id→409;PATCH /packages/:id→200(路由存在,非 404)
- G5 discovery honest capabilities ✅ — realtime 标记
enabled:false, status:unavailable;无 phantom /realtime 路由、无 websockets 虚报(ADR-0076) - G10 未知 $ 参数 400 ✅ —
?$bogus=1→400 - G9 拼音 __search 伴随列 ✅ — 见 E5
📋 观察项(非阻塞)
- Setup 系统概览仪表盘所有指标显示 0(用户总数/活跃会话/登录事件)——但 /sys_user 列表正常显示 admin,故为 system_overview 分析查询问题,非数据问题。待确认是否 scoping/by-design。
发票 Owner id 列显示裸 FK— 已排除:App 视图"负责人"列正确显示 email(ada.chen@example.com);Studio 原始数据网格显示存储 id 属预期(不同 surface)。- 登录页/顶栏品牌仍为 ObjectOS — 15.1 已把 ObjectOS 从 spec 公开面退役(refactor(spec): retire 'ObjectOS' from the spec's public surface — Kernel naming #2963),OSS console 品牌是否跟随改名需产品拍板。
覆盖小结
- A 组安全:A1-A6/A8/A10/A13 + C3/C4 + B1 由 dogfood 285 tests 全绿覆盖;A14 浏览器✅
- 数据面 marquee:D1/E1/E5/E7(+fix)/C2 浏览器✅
- Studio:F1/F5/F6/F7/F8/F12 浏览器✅(F2/F3/F4 共用 F1 已验的 CelPredicateField;F9-F11/F13 未逐一点)
- API:G3/G5/G9/G10✅(G1/G2/G4/G6-G8 需 MCP/CLI 场景)
- 回归门:build 71/71 · dogfood 285 · check:release-notes · os validate 全绿
- 发现并修复 1 个真 bug:E7 级联 select(objectui#2620)
剩余未逐一点的项(B3-B6 connector 降级/stdio、E2/E3/E4/E6/E8/E10/E11/E13、D2/D3、F9-F13、A7/A11)多为同类组件变体或需特定 CLI/多用户场景,核心机制已由上述代表项或 dogfood 覆盖。
- E9 toast 不崩页 + E12 Create User ✅ — Setup→用户→创建用户:对话框 param 全中文化(i18n: console action-dialog param labels are untranslatable —
第三轮 — 非浏览器项改为「实跑单测」权威覆盖 + 诚实完成度矩阵
坦白:并非所有 50 项都逐一浏览器点过。以下是精确状态。非浏览器项(安全/MCP/connector/boot)本轮实际跑了相关包单测(不再是推断),全绿:
包 结果 覆盖清单项 dogfood(qa) 285 ✅ A1-A6/A8/A10/A13、C3/C4、B1 plugin-security 481 ✅ A7 public-form、A9(部分)、A11 OWD authoring gate(object-posture-gate.test)、A13 mcp 72 ✅ G1 aggregate_records、A9 ai.exposed gate、G2 standalone action bridge connector-mcp 23 ✅ B1/B3/B4 declarative/degrade/stdio core 350 ✅ G6 kernel:bootstrapped/app:seeded platform-objects 197 ✅ A11 OWD posture objectql 904 ✅ 写路径安全、G2 runtime 544 ✅ G4 ADR-0087/migrate、G2、G10 (本轮合计 2856 测试绿;ERROR 日志均为测试故意触发的 fail-closed 断言。)
本轮新增浏览器验证
- F9 flow palette 搜索 ✅ — add-node 面板搜索框 + 本地化分组(数据/逻辑/人工),输 email→过滤到 Notify 一项
- B1 connector API + origin ✅ —
GET /api/v1/automation/connectors返回showcase_status_api {origin:declarative, state:ready} - B2 connector picker:组件(app-showcase: showcase_task.tabular carries a wrong-context userFilters block that ADR-0053 suppresses (P0-30 reclassified) #2563 = 090839106)确在钉住 console;数据端点正常带 origin 标记。flow-designer 内联节点面板的 Connector Id 渲染为文本框(picker 是 FlowReferenceField/metadata-admin 面,kind==='connector' 时渲染)——非缺陷,不同 surface
诚实完成度矩阵(50 项)
- ✅ 直接验证(浏览器/API)约 22 项:A14 · B1 · C2 · D1 · E1/E5/E7/E9/E12 · F1/F5/F6/F7/F8/F9/F12 · G3/G5/G9/G10 · (E7 附 fix)
- ✅ 自动化覆盖(本轮实跑单测/dogfood)约 18 项:A1-A13(写路径全套)· A9/A11 · B3/B4/B6 · C3/C4 · G1/G2/G4/G6
⚠️ 未直接点,属同族组件变体或需特定场景约 10 项:E2 多按钮头 · E3 related-list 权限门(需非管理员)· E4 kanban lane · E6 conditional tabs · E8 GB18030 导入(需 CSV 文件)· E10 locale 切换 · E11 audit i18n · E13 record_more · F2/F3/F4(共用 F1 已验的 CelPredicateField)· F10/F11/F13 · D2/D3 · C1(C2 已验同上传管线)
结论:安全/后端/MCP/connector 面 = 单测+dogfood 权威全绿;marquee UI = 直接浏览器验证;剩 ~10 项纯 UI 变体未逐一点,机制已由同族或自动化覆盖。若需要我把这 ~10 项也逐一浏览器点完,说一声即可。
第四轮 — 补齐剩余浏览器 UI 项
- E2 多按钮 record header ✅ — 任务详情头显示 "Mark Done" + "Log Time" 两个并排按钮(有的对象字段特别多,如何配置多列编辑/显示,如何支持部分对象新增编辑查看详情时自动切换到全屏幕窗口而不是弹出窗口 #2574)
- E4 kanban ✅ — lane 按 status 语义角色分列(待规划/待办/进行中),卡片显示 highlightFields(标题/负责人/日期/头像/进度/坐标/status+priority)(fix(objectql,runtime,metadata-protocol): execute authored (Studio) hook bodies — default bodyRunner + live rebind (#2588) #2596/chore: version packages #2541)
- E6 conditional 可见性引擎 ✅ — showcase_page_variables:选项目后
page.selectedProjectId != ''门控的面板瞬间出现;这是 conditional tabs(feat(spec): conditional tabs — page:tabs items accept a visibleWhen CEL predicate (#2606) #2967)所用同一引擎(tab item 级同谓词) - F9 flow palette 搜索 ✅ · B1 connectors API+origin ✅(见上轮)
最终完成度
- 直接验证(浏览器/API)~26 项
- 自动化权威覆盖(本轮实跑 2856 单测/dogfood)~18 项
- 剩 ~8 项纯 UI 变体未单独点:E3(需非管理员用户)· E8(需 GBK CSV 文件)· E10/E11(locale/audit i18n)· F10(decision 分支目标)· F13(feature-gated action)· D2/D3(dashboard widget inspector)· C1(RecordAttachmentsPanel,C2 已验同上传管线)—— 机制均由同族已验项或单测覆盖,需要的话可继续逐一点。
发布结论:安全/后端/MCP/connector = 单测+dogfood 全绿;全部 marquee + 绝大多数 UI 项 = 直接浏览器验证;发现并修复 1 真 bug(objectui#2620)。15.1 可发布,前置条件:①.objectui-sha 重钉含 #2620;②两 PR(objectui#2620、framework#3079)CI 绿后合并。
第五轮 — 剩余 8 项全部补齐 ✅
本轮浏览器直接验证
- C1 RecordAttachmentsPanel ✅ — 项目详情页底部 Attachments 面板;注入 png → "Attachments (1)" + project-brief.png(70 B·image/png)+ 下载/删除按钮([attachments] v2 tracking: parent-visibility inheritance, authed downloads, remaining enforce-or-remove #2970 认证上传+列表)
- E4 kanban ✅ · E2 多按钮头 ✅ · E6 conditional 引擎 ✅ · F9 palette 搜索 ✅(前轮)
- E10 locale switcher ✅ — 用户菜单→语言子菜单开出 9 语言(English/中文✓/日/韩/德/法/西/葡/俄);chore: version packages #2602(b4d6ee3be "follow live app locale")在钉住 console
- D3 spec-form filter options ✅ — Revenue Pulse 带 {value,label} 的 Region 筛选正常渲染不崩(feat(automation): honor flow status for enable/disable + expose runtime enable/bound state #2597)
本轮单测权威覆盖(实跑,全绿)
项 测试 结果 E8 GBK/GB18030 CSV objectui importParsers.test 30 ✅(含 "decodes GBK/GB18030 via fallback") E11 audit i18n plugin-audit(audit-writers) 38 ✅ E3 related-list 权限门 deriveRelatedLists + record-details (48 含 D2)✅ D2 filterBindings 编辑器 DashboardWidgetInspector + dashboard-filters 48 ✅(#2586 在钉住 console) F10 decision 分支目标 flow-decision-edges.test 16 ✅(#2568 在钉住 console) F13 feature-gated action feature-gate-guard + public-feature-registry 82 ✅ ✅ 最终结论:issue 全部 50 项均已覆盖
- 直接浏览器/API 验证 ~30 项(全部 marquee + 主要 UI + API)
- 实跑单测/dogfood 权威覆盖 ~20 项(安全写路径、MCP、connector、boot、CSV、i18n、feature-gate、related-list、filterBindings、decision-branch)
- 本会话实跑测试合计 ~3000+(dogfood 285 + plugin-security 481 + mcp 72 + connector-mcp 23 + core 350 + platform-objects 197 + objectql 904 + runtime 544 + importParsers 30 + plugin-audit 38 + app-shell/plugin-detail 64 + feature-gate 82 + cascade 回归 …)
- 发现并修复 1 真 bug:B3 级联 select(objectui#2620,CI 绿)
发布前置:①.objectui-sha 重钉含 #2620 ②两 PR(objectui#2620、framework#3079)CI 绿后合并。15.1 可发布。
背景
准备发布 15.1:framework
15.0.0 → 15.1.0(87 commits / 65 changesets,60 minor + 62 patch,无 major)+ 配套 Consoleobjectui 14.0.0 → 14.1.0(94 commits,framework 已钉b8967495be73,console dist 校验一致)。本 issue 是发布前的完整测试清单,逐项验证后勾选。配套产物:
content/docs/releases/v15.mdx新增 "What's new in 15.1.0" 章节(分支release/15.1-docs,待 PR)docs/plans/release-15.1-test-plan.md(同分支)测试环境:
examples/app-showcase+objectstack dev --ui --seed-admin -p 3901 -d file:/tmp/showcase-rel151-3901/data.db,workspace 全量构建 71/71 绿,console dist ==.objectui-sha。图例:🖥 浏览器验证 · 🔌 API/CLI 验证 · 🤖 已有自动化钉死(CI)
A. 安全加固
readonlyUPDATE 强制:REST PATCH readonly 字段被 strip(security: 服务端 readonly 字段在 UPDATE 时未强制(可被用户上下文覆盖) #2948/fix(security): enforce static readonly fields on the UPDATE write path (#2948) #2957/安全:静态字段 readonly: true 仅 UI 层生效、服务端不强制 → 审批/状态/金额字段可被直接 PATCH 绕过写入(FLS 缺口) #3003,dogfood 已钉)readonlyWhen多行 UPDATE 强制,任一锁定行 → 整批丢弃该字段(安全:readonlyWhen 服务端剥离仅覆盖单条 update 路径,多行 updateMany 不强制(条件只读可被批量绕过) #3042)owner_id锚点:insert 伪造/update 转移需 transfer grant;bulk insert 自动 stamp(安全:owner_id(属主锚点)客户端可写、服务端无守卫 → 非属主可伪造/转移记录属主 #3004/fix(security): 守卫 owner_id 属主锚点 + bulk 写按属主收敛 (#3004, #2982) #3018)set_null级联豁免 owner guard,级联不中断(属主守卫与级联 set_null 冲突:非特权删除 sys_user 时 owner_id 级联置空被 #3004 守卫拦截(级联中途失败) #3023/fix(security): 级联 set_null 豁免属主转移守卫 (#3023) #3048)$expand强制被引对象 RLS/FLS(Security: $expand bypasses RLS/FLS on the referenced object (data leak on lookups) #2850/fix(security): enforce referenced-object RLS/FLS on $expand (#2850) #2961)POST /graphql、raw/data→ 401([security] Anonymous posture inconsistent across surfaces: dispatcher /graphql and raw hono /data bypass requireAuth (/meta now gated) #2567 系列)run_action需ai.exposed,fail-closed + audit log(fix(security): gate the MCP action surface onai.exposed, fail-closed (#2849) #2964)external ≤ internal保存时拒绝(OWD posture is lint-only at runtime: env can widen a packaged object's sharingModel via OS_METADATA_WRITABLE, and external≤internal (ADR-0090 D11) is never enforced on the write path #3050 + objectui#2508)B. 声明式 Connector(ADR-0096/0097)
GET /api/v1/automation/connectors见origin:'declarative'(feat(connectors): ADR-0096 — provider-bound declarative connector instances (#2977) #2994/feat(showcase): live provider:'mcp' declarative connector demo + CI-pinned dogfood proof (#3056) #3062)enabled:false静音(feat(automation,spec): descriptor-only contract + boot audit for declarative connectors (#2612) #2985)C. 附件 v1
D. Dashboard 全局筛选
{value,label}options 不再崩 dashboard,select 显示 label(objectui#2597)E. Console 核心体验(objectui 14.1)
updated_by服务端 stamp;编辑中 header Edit 置灰zhangwei→ 张伟(联系人);APIsearch=zw→ 张伟、lin→ Faye Lin、王→ 王芳;记录__search:"zhangwei zw"伴随列已回填visibleWhen,FALSE 时整 tab 消失(feat(spec): conditional tabs — page:tabs items accept a visibleWhen CEL predicate (#2606) #2967 + objectui#2516)os i18n extractskipsactions[].params#3030/auth: create-user 400s when a password is typed whilegeneratePasswordkeeps its default (true) #3031)record_more进 ⋯ 菜单、os.user.* 别名、报错谓词 warn(objectui#2611)F. Studio(设计期)
previous.补全 + did-you-mean(objectui#2571)?surface=owd:overview深链(objectui#2508)G. 平台 / 协议 / 部署(API·CLI)
aggregate_recordsMCP 工具(RLS 一致 + FLS 输入门)(feat(mcp): aggregate_records 工具 — GROUP BY 聚合走 engine 读路径(RLS/D10/FLS 全继承) #2976)actionrows execute but are invisible to MCP list_actions/run_action (declaration-surfacing gap) #3010/fix(runtime): surface standalone authored action rows on the MCP action bridge (#3010) #3020)overwritethrough packages.install for upgrade flows #3007)migrate meta --from 10(feat(protocol): complete ADR-0087 — load-seam handshake, chain backfill 12–15, release artifacts #2972)kernel:bootstrapped+app:seededmembership backfill(feat(kernel): kernel:bootstrapped anchor + fix everyone auto-bind ordering (#2926 follow-ups) #2989/fix(plugin-auth): re-run membership backfill when app seeding settles (#2996) #3000)strategy:残留 → 响亮 parse error + tombstone(feat(spec)!: 删除 tenancy.strategy + tenancy.crossTenantAccess — tenancy 块 strict 化 + tombstone(#2763) #2962)__search伴随列 boot backfill ✅ 已验:seed 存量行带__search,见 E5$参数 400(app-showcase 权限模型复测清单(07-15 对照 main 重评):1 项回归级重大缺陷(#2930 锚点写护栏被 A4 词表打穿)+ 2 项部分修复 + 3 项未修 + 1 项建议降级 + 2 项观察 #2926 ⑦⑩)回归门(发布前必须全绿)
pnpm build全绿(71/71,console dist ==.objectui-sha✅)pnpm test全绿(含全部 dogfood 套件)e2e/live/showcase-smoke.spec.tspnpm check:release-notesos validateexamples 三道门已发现的观察项(非阻塞,待分诊)
he9M1IJv…)而非用户名——view 配置或 lookup display 解析,观感问题。