diff --git a/examples/app-showcase/docs/test/console-list-form-capability-report-2026-07.md b/examples/app-showcase/docs/test/console-list-form-capability-report-2026-07.md deleted file mode 100644 index 2cf5ed7cbb..0000000000 --- a/examples/app-showcase/docs/test/console-list-form-capability-report-2026-07.md +++ /dev/null @@ -1,135 +0,0 @@ -# Showcase 对象列表 / 表单能力完整实测报告(2026-07) - -> 内置浏览器(preview MCP)对 `examples/app-showcase` 逐项真实操作测试,全程截图留痕。 -> 本文为问题权威记录;Word 版(文字+截图)见同目录 -> `showcase-console-capability-test-report.docx`。 - -## 测试环境 - -| 项 | 值 | -| --- | --- | -| 分支 / 提交 | `claude/nifty-neumann-ed7c3e` @ `9d121934e` | -| 启动方式 | `objectstack dev --ui --seed-admin -p 3777 -d file:/tmp/showcase-dogfood-3777/data.db` | -| Console | `/_console`(vendored objectui,钉在 `.objectui-sha` = `2cfa36e96`) | -| 账号 / 语言 | `admin@objectos.ai`,浏览器 zh-CN 会话 | -| 测试日期 | 2026-07-02 ~ 2026-07-04 | -| 截图 | `./screenshots/`(01–38,29 号因外链图片慢加载误判已删除) | - -## 测试范围(用户要求"不要有遗漏") - -行按钮(行菜单/详情页 action 各 location)、行内编辑、列表选中批量按钮、批量修改 -(4 种参数形态)、对象表单分组、字段显示隐藏(对象级 visibleWhen/requiredWhen/ -readonlyWhen 与视图级 FormField.visibleOn)、lookup 级联选择(dependsOn + -lookupFilters)、命名视图与视图路由、userFilters、筛选/分组/排序/搜索、6 种可视化、 -分页/每页行数、主子表(发票明细)、related list 行内编辑、flow action(toolbar 与行级)、 -新建/编辑表单、必填校验、select 默认值、国际化与 UI 异常。 - ---- - -## 一、缺陷清单(35 项) - -严重度:**P0** 功能不可用/数据错误;**P1** 功能明显受损或严重误导;**P2** 体验/一致性/国际化。 - -### 行内编辑 / 行按钮 / action - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 10 | **P0** | **行内编辑完全不可用**:视图 meta `inlineEdit:true`、工具栏"行内编辑"按钮可切换高亮,但点击单元格(含真实点击)永不进入编辑态,反而触发行导航打开记录预览。源码链路完整,定性为 vendored console 运行时缺陷 | 截图 11、12 | -| 5 | P1 | 视图级 `inlineEdit` 开关失义:未配置 inlineEdit 的视图工具栏同样显示"行内编辑"按钮,开关不改变行为 | — | -| 6 | P1 | **modal 类型 action 不弹窗**:Quick View 点击后无任何弹窗,仅英文 toast "Action completed successfully"(既没执行也误报成功) | 截图 04 | -| 7 | P1 | 行级 action 的 `visible` 表达式(`!record.done`)在**列表行菜单不生效**:done=true 刷新后行菜单仍显示 Mark Done;详情页同一表达式正确生效(对照) | 截图 07 vs 08/09 | -| 8 | **P0** | **form 类型 action 崩坏**:Log Time 整页跳 `/_console/forms/showcase_task.default`,渲染黑屏 + 错误标题(取了 list 视图名"All Tasks")+ 零字段 + 裸 Submit;提交后还误报成功 toast | 截图 10 | -| 20 | **P0** | `/_console/forms/*` 路由渲染器对所有 form 视图全坏:`tabbed` 同样黑屏 + 原始名标题 + 零字段 + 裸 Submit → tabbed/wizard 表单**无任何可用 UI 入口** | 截图 24 | -| 19 | **P0** | **form 视图与 list 视图同名 `default` 时被静默改名 `default_2`**(`/api/v1/meta/view` 可见 showcase_task.default_2/tabbed/wizard/split/quick 均 viewKind:form),`showcase_task.default` 解析到 list 视图 —— form action target 失配的根因之一;冲突静默发生,无 build 告警 | API meta | -| 23 | P1 | `record_more` 与 `record_section` 两个 action location 在任务详情页**完全不渲染**(Open Docs / Recalculate Estimate 无处可见);项目详情页却有"…"按钮 —— 行为不一致 | — | -| 27 | **P0** | **flow action(list_toolbar)无记录上下文即崩**:Reassign… 从工具栏启动,提交后错误 toast 裸露英文技术信息 "Node 'apply' failed: update_record(showcase_task) failed: Update requires an ID or options.multi=true";flow screen 的 new_assignee 渲染为裸文本输入而非用户选择器,按钮 Cancel/Submit 英文 | — | -| 35 | **P0** | **flow action(行级 list_item)成功与失败信号并存**:从行菜单启动 Reassign…,记录实际更新成功(API 核实 assignee sam→nora),但界面同时弹出红色错误 toast(同 #27 文案)与绿色 "Done" toast —— 用户无法判断成败;且成功路径也复用了失败分支 | 截图 34,API 核验 | -| 17 | P2 | 自定义 action 标签(Mark Done / Reassign… / Quick View / Log Time)全英文,与系统项(编辑/删除)中文混排 | 截图 03 | - -### 批量操作 - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 12 | **P0** | **批量编辑多选 select 被单选化**:字段定义 `type:'multiselect'+multiple:true` 正确,但 UI 下拉即选即关、选新值替换旧值,落库为标量 `'qa'` 而非数组 —— 数据被写坏 | 截图 15,API 核验 | -| 13 | P1 | 批量编辑 lookup 参数确认页显示裸 ID(`94vGlm…` 而非 Dev Admin) | 截图 16 | -| 14 | P2 | 批量编辑 lookup 参数无搜索框(单选 8 个选项、多选皆无,数据多时不可用) | — | -| 15 | P1 | 批量编辑 date 参数无日期选择器:裸 text input,点击不弹日历;手输 `2026-08-01` 才可被接受 | 截图 17 | -| 11 | P2 | 批量栏/批量弹窗按钮英文混排(Delete/Cancel/Next/Back/Run/Close/Done/Undo) | 截图 13–17 | - -### 表单 / 字段显隐 / 级联 - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 16 | **P0** | **表单视图级 `FormField.visibleOn` 完全不生效**:meta 正常下发 CEL(`dialect:'cel'`),但 priority=Low 时 notes 字段仍显示。对照:对象字段级 visibleWhen/requiredWhen/readonlyWhen 全部生效(见"正常项") | 截图 18、19 vs 23 | -| 21 | **P0** | **级联 lookup(dependsOn)双缺陷**:① 选完 account 后 contact 主输入仍禁用,占位文案"请先选择account"中英混排字段名;编辑已有记录时也锁死;② 旁路"表格选择器"完全**不应用级联过滤**,列出全部联系人 —— 级联约束可被绕过 | 截图 21 | -| 22 | P1 | 明细行 `readonlyWhen`(parent.status=='paid')冻结可被**旁路表格选择器图标绕过**:Paid 状态下仍能打开产品选择弹窗(弹窗标题还是省略号"选择…") | — | -| 33 | P1 | **select 默认值全链路不生效**:contact.stage 定义 `default:true` 的 New 选项,新建表单不预选(显示"请选择"),仅填必填项提交后落库 `stage=null` —— 表单端与服务端都没应用默认值 | API 核验 | -| 18 | P2 | 必填校验消息中英混排:"标题 is required" | 截图 20 | - -### 视图 / 列表 / 筛选 / 分页 - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 29 | **P0** | **导航项 viewName 生成短名路由,视图解析静默失败回退默认视图**:Analytics→Task List 生成 `/view/tabular`,页面面包屑显示 "Tabular"、侧边栏高亮,但渲染的列/筛选/选中 tab 全是默认视图的;页内视图切换用全限定名 `/view/showcase_task.tabular` 则一切正常 —— 同一视图两个入口两种结果,且失败无任何提示。**→ 已修复**:objectui#2217 / PR #2218(解析端双向解析短名↔全限定名,失配时 console.warn 列出已知视图) | 截图 35 vs 36 | -| 30 | ~~P0~~ 定性更正 | **视图 `userFilters` 不渲染 —— 实为按设计抑制,非渲染 bug**:objectui ADR-0053 规定对象列表视图("views" 模式)唯一导航控件是视图切换器,`userFilters` 只属于页面列表(InterfaceListPage "filters" 模式,showcase 的 task-workbench 等 page 示例即正确用法)。真正缺陷有二:① 抑制**完全静默**(ADR-0053 phase-4 校验护栏未落地)→ objectui#2219 / PR #2220 已加一次性 console.warn;② showcase 自身 tabular 视图携带 wrong-context 的 `userFilters` 块(framework#2563,本次移除) | 截图 36;扫码 ADR-0053 | -| 25 | P1 | 筛选/排序面板新增行**默认字段为系统字段 Organization**(英文);字段列表暴露 Sync Status / Sync Error 等内部字段,且系统字段全英文 | 截图 26 | -| 26 | P2 | 分组点"添加分组字段"立即按默认字段"标题"分组(每组 1 条,无意义);组头显示英文选项标签(Done/In Progress) | 截图 27 | -| 31 | P1 | **列表页脚记录数显示的是当前页行数而非总数**:120 条数据、每页 100 时页脚显示 "100 条记录",翻到第 2 页变 "20 条记录" —— 用户看不到真实总量(分页条本身的"第 X 页,共 Y 页"是对的) | 截图 37、38 | -| 32 | P1 | 列表工具栏**无导出按钮**(只有导入),也**无列显示/隐藏设置**入口(工具栏仅 行内编辑/筛选/分组/排序/密度/搜索) | 截图 36 | -| — | P2 | (观察项)虚拟滚动懒加载中,lookup 列(Owner)单元格短暂渲染字面量 `[object Object]`,最终渲染正常;快速滚动时用户可见 | DOM 抓取 | - -### 服务端 / DX - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 9 | P1 | **持久 DB 缓存包元数据**:源码改动后重启 dev 不同步(须删 `.objectstack`/数据库文件)—— 开发体验陷阱,极易误判"改了没生效" | — | -| 34 | P1 | **API 无效查询参数被静默忽略**:`GET /api/v1/data/showcase_contact?filter=email eq '…'`(错误参数名/语法)不报错,直接返回**全量**数据;正确参数是 `filters=[["email","=","…"]]` 三元组 —— 静默忽略易造成调用方误取全量 | API 核验 | - -### 国际化 / UI 一致性 - -| # | 严重度 | 问题 | 证据 | -| --- | --- | --- | --- | -| 1 | P2 | zh-CN 下视图页签/视图名英文(All Tasks/In Progress/Urgent/Done)+"还有 9 个"混排;"管理所有视图…"中文与英文视图名混排 | 截图 01、06 | -| 2 | P2 | 日期列默认相对格式为英文(Tomorrow / In 2 days / Overdue 7d)与中文绝对日期(6月15日)同列混排;详情页同样出现 | 截图 01 | -| 3 | P2 | select 选项标签英文(Done/In Progress/High/Medium/Urgent 等)—— 选项级翻译缺失或平台不支持 | 截图 01、27 | -| 4 | P2 | console 首页中英混排(Your apps / Needs your attention / Items you open will show up here.) | — | -| 24 | P2 | 详情页 related list 可编辑网格标题 "Tasks" 及表头全英文 —— 翻译 bundle 里有中文但网格不读 | 截图 25 | -| 28 | P2 | 发票创建 toast 双条中英混出("发票创建成功"+"Created");发票表单按钮英文 Cancel 而任务/联系人表单是中文"取消"(同产品不一致);对象描述英文;"Owner"列头英文;数值列排序方向标注 "A → Z" | 截图 22 | - -## 二、验证正常的能力(不要遗漏"好消息") - -- 命名视图切换与过滤(In Progress → 2 行正确)— 截图 02 -- 行操作菜单齐全(编辑/删除/自定义 action)— 截图 03 -- script action 执行 + `refreshAfter` 写库(Mark Done → done/progress 落库)— 截图 05 -- action `visible` 表达式在**详情页**正确生效 — 截图 08/09 -- 批量操作主链路:选中出批量栏、内置删除、4 种自定义批量定义齐全、确认页 - (confirmText + 受影响记录 + 参数预览)、执行 Succeeded 2/2、**Undo 回滚**(API 核实)— 截图 13/14/16 -- 对象字段级三种条件规则全部生效:Paid → 付款日期出现且必填、税率只读、开具日期必填 — 截图 23 -- `lookupFilters` 生效(churned 客户被排除,13→11) -- 发票主子表:明细行内编辑、金额/汇总实时计算并正确落库 — 截图 22 -- 明细行 `readonlyWhen` 冻结(定义内路径)生效 -- related list 网格行内编辑保存落库(estimate 16→18)— 截图 25 -- 筛选(状态=Done → 2 条)、按状态分组、排序(预计工时降序)、列表搜索(homepage → 1 条)— 截图 26/27 -- 6 种可视化全部渲染:Grid/Kanban/Gallery/Calendar/Timeline/Gantt — 截图 28、30–33 -- 记录详情:状态机 stepper、评论区、related 页签中文 -- 表单必填校验拦截(空必填不能提交)— 截图 20 -- 新建表单正确排除 readonly 字段(contact.lead_score 不出现在创建表单) -- 分页:>100 条出现分页条,翻页正确(行号连续)、每页行数 5/10/20/50/100 可切换 - ("第 1 页,共 6 页" 正确)— 截图 37/38 - -## 三、测试数据变更(dev 库 /tmp,不入库) - -- 新建发票 INV-TEST-01(Draft/Nora West/1 行 ¥50) -- 任务 "SEO migration plan" estimate_hours 16→18;"Build homepage" assignee sam→nora(flow 测试) -- 批量造 115 个"分页测试联系人" + 1 个"默认值测试联系人"(分页/默认值测试) - -## 四、修复建议优先级 - -1. **P0 数据/功能级**:#12 批量多选写坏数据、#10 行内编辑不可用、#8/#19/#20 form - action 与 forms 路由全链、#27/#35 flow action、#16 visibleOn、#21 级联 lookup、 - #29 视图路由静默回退(已修:objectui#2218)、#30 userFilters(定性更正:按设计 - 抑制,静默问题已修 objectui#2220,showcase 元数据已清理 framework#2563) -2. **P1 误导/受损**:#31 页脚计数、#25 筛选默认系统字段、#33 select 默认值、#34 API - 静默忽略参数、#9 DB 元数据缓存、#13/#15 批量参数控件、#22 只读旁路、#23 action 位置 -3. **P2 国际化一致性**:集中治理 console 内置 UI 文案与元数据标签的 zh-CN 覆盖 - (#1–4、#11、#17、#18、#24、#26、#28) diff --git a/examples/app-showcase/docs/test/framework-objectui-changes-2026-07-03_05.md b/examples/app-showcase/docs/test/framework-objectui-changes-2026-07-03_05.md deleted file mode 100644 index 49db89ba93..0000000000 --- a/examples/app-showcase/docs/test/framework-objectui-changes-2026-07-03_05.md +++ /dev/null @@ -1,271 +0,0 @@ -# framework × objectui 近两天改动主题梳理(2026-07-03 ~ 07-05) - -> 覆盖 `framework`(spec/runtime/security/automation/showcase)与 `objectui` -> (console SPA:app-shell/studio/plugin-*)两仓两天内的全部改动,按**主题**而非 -> 时间线组织,并给出跨仓 PR 对照。文末含本次在 showcase 新增的 `ObjectNavItem.filters` -> 演示元数据与浏览器实测结论。 -> -> - framework 窗口内提交:**72**;objectui:**49**。 -> - 数据来源:两仓 `git log --since=2026-07-03 --until=2026-07-06`。 -> - PR 号:`(#NNNN)` 为对应仓的 PR;跨仓联动处标注 `framework#NNNN` / `objectui#NNNN`。 - ---- - -## 目录 - -1. [安全 / 授权(两扇门 + 反过滤预言机)](#1-安全--授权) -2. [协议契约演进(spec / lint)](#2-协议契约演进speclint) -3. [声明式导航切面:`ObjectNavItem.filters`(旗舰特性)](#3-声明式导航切面objectnavitemfilters) -4. [自适应记录呈现 + 关联列表主标签](#4-自适应记录呈现--关联列表主标签) -5. [声明式集成:apis / mappings / cube / objectExtension](#5-声明式集成apis--mappings--cube--objectextension) -6. [自动化 / Flow 运行可观测性](#6-自动化--flow-运行可观测性) -7. [Studio 编辑闭环:审阅后发布 + 只读包门禁 + 数据失效总线](#7-studio-编辑闭环) -8. [Showcase 重构:六域布局 + 能力地图 + 覆盖率守卫](#8-showcase-重构) -9. [协议元数据种类精简(ADR-0088)](#9-协议元数据种类精简adr-0088) -10. [本次新增演示元数据与实测结论](#10-本次新增演示元数据与实测结论) - ---- - -## 1. 安全 / 授权 - -两天内最重的一条主线,落地 **ADR-0086 两扇门(two-doors)权限分离** 与 -**secure-by-default** 翻转,并堵住一个"字段权限过滤预言机"侧信道。 - -| 主题 | framework | 说明 | -| --- | --- | --- | -| **Secure-by-default 翻转** | `#2562`(#2561 P0) | `requireAuth` 默认改为**必须鉴权**;`transfer/restore/purge` 加 RBAC 门禁。破坏性变更(`feat!`),旧代码若依赖匿名可写会被拒。 | -| **两扇门分离 P1/P2** | `#2566` `#2573` | 权限集(permission set)区分"元数据门"与"配置门":声明式来源带包 provenance(`bootstrapDeclaredPermissions`),运行期配置门独立。 | -| **鉴权架构文档** | `#2569` `#2559` `#2580` | ADR-0086 边界(元数据↔配置)+ 跨包组合;两扇门明确为"已落地"而非路线图。 | -| **字段权限反预言机** | `#2630` | 字段级权限**谓词守卫**:防止用户借"可筛选但不可见"字段的过滤结果反推隐藏字段值(filter-oracle)。同 PR 还加了导航落地互斥(见 §3)。 | -| **共享限流 / 会话** | `#2572`(ADR-0069 D2)`#2570` | 跨节点限流 + 会话存储走 cache service;补齐 last-login 审计字段。 | -| **失败暴露** | `#2568` `#2565` | 权限集解析失败不再被吞,显式上报。 | - -objectui 侧对应把 Studio 的 **Access(访问)支柱**按包作用域收口: - -| objectui | 说明 | -| --- | --- | -| `#2229` | Access rail 服务端按 `packageId` 作用域(ADR-0086 P1 跟进)。 | -| `#2225` | 包 Access 门是 draft/published 两态,而非直接 live(P2 · D6/D7)。 | -| `#2222` | Access 矩阵按 `{ packageId }` 作用域 + 保存时切片合并。 | - -**要点**:secure-by-default 翻转是升级时最需要注意的破坏性项——本地/示例若跑 -匿名写会 401/403,需要显式 `requireAuth:false` 或补 permission set。 - ---- - -## 2. 协议契约演进(spec/lint) - -`packages/spec` 是元数据生产者↔消费者的 Zod 契约。两天内它既加特性也**收紧 -lint**,把"构建期就该报的错"从运行期前移。 - -| framework | 类型 | 说明 | -| --- | --- | --- | -| `#2583` | lint(ADR-0053 phase 4) | **拒绝**对象列表视图上写 `userFilters`(快捷筛选只允许放 interface page,见记忆 `userfilters-only-in-page-mode`)。 | -| `#2586`(#2554) | build-lint | 视图引用检查:命名冲突**告警**,表单目标非法**报错**。 | -| `#2556` | lint | `expandViewContainer` 视图 key 冲突大声告警。 | -| `#2558` | metadata-protocol | 视图身份(identity)继承到运行期 overlay。 | -| `#2589` | runtime | metadata save/publish 错误携带 spec 校验 issue + 422 状态码贯通。 | -| `#2590` `#2582` | docs/adr | 补齐 10.0.0–11.10.0 协议 changelog;ADR-0087 面向 AI 消费者的协议升级(转换优先于通知 + 可重放迁移链)。 | - -objectui 侧把 spec 校验失败**下沉到字段**: - -| objectui | 说明 | -| --- | --- | -| `#2234` | Studio 保存/发布时,把 spec 校验失败显示在**出错字段**上。 | -| `#2218` | `/view/` 路由解析短视图名。 | -| `#2214` | 视图级 `FormField.visibleOn` 用规范 CEL 引擎求值(与对象级一致)。 | - ---- - -## 3. 声明式导航切面:`ObjectNavItem.filters` - -**本窗口最完整的一条 framework ↔ objectui 端到端特性**,也是本次 showcase -新增演示的对象。 - -**契约端(framework `#2626`)** — `spec` 给 `ObjectNavItem` 加 -`filters: z.record(z.string(), z.string())`:一个导航项可以直接对准对象的 -**裸数据面**(`/:objectName/data`),预置 `filter[]=` 条件, -而不必先建一个具名视图。支持模板变量 `{current_user_id}` / `{current_org_id}` -做"我的/本组织"切面。 - -**互斥守卫(framework `#2630`)** — `app.zod` 的 `superRefine` 拒绝把 `filters` -与 `recordId` / `viewName` 混用。落地优先级 **`recordId` → `filters` → `viewName`**; -混用是作者态歧义(残留的 `recordId` 会悄悄劫持切面),故构建期直接拒。 - -**消费端(objectui `#2255`,内含 `#2251`)** — app-shell 新增 -`/:objectName/data` 参数化裸数据面;`packages/layout/src/NavigationRenderer.tsx` -的 `resolveHref` 把 `item.filters` 编译成 `${objectPath}/data?filter[field]=value`, -并配套 active-state **逆向解析**(`#2272`/`objectui#2273`),让带 -`?filter[...]` 的切面项也能正确高亮(否则精确 pathname 匹配永不命中)。 -`AppNavInspector` 同步做了**四落地模式**改造(default / view / record / filters, -`objectui#2245`/`#2273`),Inspector 里可视化编辑这些 URL 过滤条件。 - -| 端 | PR | 交付物 | -| --- | --- | --- | -| 契约 | framework `#2626` | `ObjectNavItem.filters` schema | -| 守卫 | framework `#2630` | 落地互斥 superRefine + 优先级 | -| 裸数据面 | objectui `#2255`/`#2251` | `/:objectName/data` + `resolveHref` 切面路由 | -| 高亮 | objectui `#2272`/`#2273` | active-state 逆向解析器 | -| Inspector | objectui `#2245`/`#2273` | 四落地模式编辑器 + i18n | -| 技能文档 | objectui `#2265`/`#2247` | app-composition 决策指南(nav vs views vs pages)+ filters-slice eval | - ---- - -## 4. 自适应记录呈现 + 关联列表主标签 - -一组"记录详情页更聪明"的协同改动。 - -| 主题 | framework | objectui | 说明 | -| --- | --- | --- | --- | -| **自适应记录面** | `#2595`(#2578) | `#2237`(#2515) | `FormField.span` 语义跨列 + `navigation.size` + 响应式列;表单按视口自适应布局。 | -| **关联列表主标签** | `#2594`(#2579) | `#2235` | `relatedList: 'primary'` 让详情页把某个关联列表提升为**主标签页**;支持多 FK、自引用、统一 picker 列。 | -| **URL 驱动详情标签** | — | `#2267`(#2257) | `?tab=` 记录详情标签**在 remount 后仍存活**。 | -| **flow 感知记录面** | `#2622`(#2604 Step 1)`#2604 Step 2` | `#2256` | `deriveRecordFlowSurface`:把记录相关的 task flow 派生成 overlay 呈现在记录面上,带返回不变量。 | -| **默认关联列表 CRUD** | — | `#2227` | 默认关联列表支持增删改、打开详情、子级 action。 | -| **名称字段统一解析** | — | `#2236`(ADR-0079) | `page:header` 记录标题按 nameField 走统一解析器。 | -| 文档 | `#2599`/`#2600` | `#2239` | 技能与指南同步 adaptive + related-list 'primary'。 | - ---- - -## 5. 声明式集成:apis / mappings / cube / objectExtension - -把过去要写 handler 代码的东西**元数据化**。 - -| 主题 | framework | objectui | 说明 | -| --- | --- | --- | --- | -| **声明式 API 端点** | `#2611`(showcase 落地 `680804970`) | — | `apis:` 里声明 `ApiEndpoint`,运行期按 path+method 派发到 `object_operation`(数据读)或 `flow`(跑流程),**零 handler 代码**。 | -| **具名导入映射** | `#2611`/`#2629` | `#2277`(#2611) | `defineMapping` 接入导入链路;plugin-grid 导入向导用已注册映射。 | -| **数据立方 / 对象扩展** | `25f7035d7` | — | `defineCube`(服务端分析面)+ `defineObjectExtension`(对已有对象叠加字段/视图)在 showcase 骨干上演示。 | -| **Studio 授权动作接线** | `#2608`(#2605/#2591/#2592) | `#2244` | Studio 里挑连接器动作(不再手打 action id),运行期接线 objectql/sharing/i18n。 | - ---- - -## 6. 自动化 / Flow 运行可观测性 - -| framework | 说明 | -| --- | --- | -| `#2581` | **持久化运行历史**,带失败原因(run observability)。 | -| `#2603`(#2585) | 运行历史保留策略 + 单次运行详情持久化。 | -| `#2596`(#2588) | 执行 **Studio 作者编写的 hook body**:接默认 bodyRunner + live 重绑定。 | -| `#2576` `#2560` | 服务运行中发布的 flow 无需重启即绑定;冷启动即绑触发器(不只 HMR 后)。 | -| `497bda853` | 按 flow status 做启用/禁用 + 暴露运行期 enable/bound 状态。 | - -objectui 侧:`#2240`(自动化启停开关 + Automations rail 实时状态)、`#2246` -(草稿 flow 也显示在 rail)、`#2230`(失败运行原因显示在 Runs 面板)。 - ---- - -## 7. Studio 编辑闭环 - -objectui 这两天把 Studio 从"能改"推进到"改得**安全、可审阅、不白刷 UI**"。 - -| objectui | 说明 | -| --- | --- | -| `#2271` | **审阅后发布**:发布前确认 + 变更面板里字段级 diff。 | -| `#2270` | Studio dogfood 跟进:API 名派生、**只读包门禁**、发布确认、导航脚手架、i18n 清扫。 | -| `#2263` | 只读包上禁用编辑可供性 + 字段 API 名 live 同步。 | -| `#2274` | **数据失效总线**:刷新数据而非重建 UI(react/app-shell/plugin-detail/components 协同)。 | -| `#2280`(#2269) | refresh-in-place 的 CI 回归守卫。 | -| `#2275` | package-id 向导反馈 + P3 dogfood 打磨。 | -| `#2241`(ADR-0080) | app → Studio 顶栏反向桥。 | -| `#2233` | 表单提交剥离计算字段(computed)。 | - -framework 侧对应 `#2625`/`#2618`:只读包被拒时给**用户可读文案**,不泄露内部 ADR 路径。 - ---- - -## 8. Showcase 重构 - -`examples/app-showcase` 被系统性重组为"每种能力演示一次并索引"的样板库。 - -| framework | 说明 | -| --- | --- | -| `e03d2fc79` | 按**六大协议域**重组 `src/`。 | -| `7768a7593` + `1aab20937` | **注册表驱动的 kind 覆盖率**:每种元数据种类要么被演示(带证明文件),要么被显式豁免(带理由+issue)。`pnpm verify` 守住这张地图(`src/coverage.ts`)。 | -| `aa8f8dc47` | 能力地图(capability map)落地页 + 逐域向导游览。 | -| `#2621`(#2616)`576ef3201` | 跟上协议升级:REST 字段崩溃、AI 404 刷屏、死胡同向导、Mark Done 未绑定、KPI 卡片卡住、离线种子图;校验强制翻转 / span / 派生抽屉宽度。 | -| `#2631` `#2632` | Command Center flex 子项撑满;CRM Workbench KPI 卡读 `adapter.find().data`(非 `.records`,见记忆 `objectstack-multiselect-gotcha` 同源坑)。 | -| `205d15be8`(#2550) | console 列表/表单能力全量实测报告(35 项问题),见同目录 `console-list-form-capability-report-2026-07.md`。 | - ---- - -## 9. 协议元数据种类精简(ADR-0088) - -`da807f716`(`#2628`)落地 **ADR-0088 元数据种类准入测试**:退役 -`trigger` / `router` / `function` / `service` 四种旧元数据种类。配合早前退役 -`compactLayout` 别名的清理,协议表面在收敛。升级消费者需注意:这些 kind 不再被 -注册表接纳,应迁移到 flow / apis / hook。 - ---- - -## 10. 本次新增演示元数据与实测结论 - -### 10.1 新增内容 - -选取 §3 的旗舰特性 `ObjectNavItem.filters` 作为端到端演示,在 showcase 落地: - -- **`examples/app-showcase/src/ui/apps/index.ts`** — 新增导航组 - **`grp_slices`「Data Slices (filters)」**,插在 `grp_data` 与 `grp_analytics` - 之间。三个子项都对准同一个 `showcase_task` 对象,但各自预置不同切面: - - `nav_slice_in_progress` → `filters: { status: 'in_progress' }` - - `nav_slice_urgent` → `filters: { priority: 'urgent' }` - - `nav_slice_review` → `filters: { status: 'in_review' }` -- **`examples/app-showcase/src/docs/showcase_tour_ui.md`** — 新增 - "Data Slices — declarative `filters` on the bare data surface" 段,解释切面、 - 互斥守卫(#2630)与模板变量。 - -### 10.2 验证矩阵 - -| 层 | 手段 | 结果 | -| --- | --- | --- | -| 元数据构建 | `pnpm build`(turbo 70 任务) | ✅ 通过,dist 产物含 `grp_slices` + 3 个 filters | -| 协议校验 | `pnpm validate` | ✅ 通过 | -| 契约守卫 | `app.zod` superRefine(#2630) | ✅ filters 与 recordId/viewName 混用会被拒(未触发,三项纯 filter) | -| 单测 | `vitest`(55 例) | ✅ 全绿 | -| 后端语义 | REST `/api/v1/data/showcase_task?filter[...]` | ✅ in_progress=2、urgent=2、in_review=2、不带过滤=10 | -| 前端渲染(侧栏) | 内置浏览器 preview(:3777 `/_console`) | ✅ 「Data Slices (filters)」组渲染,展开出 3 个子项,显示自定义 label(旧 dist 只显示「任务」)| -| 前端渲染(URL 切面链路) | 点击切面项 → 跳 `/showcase_task/data?filter[...]` | ✅ **重建 dist 后跑通**(见 §10.3)| -| 前端渲染(裸数据面+chip) | 落地面渲染过滤结果 + 可移除 chip | ✅ 「状态 = in_progress ×」可移除 chip + **2 行**记录,与后端一致 | - -### 10.3 曾经的阻塞与其排查:vendored dist 陈旧 → 重建后跑通(无需改代码) - -**首测现象**:点击切面项时 URL 停在标准对象面 -`/_console/apps/com.example.showcase/showcase_task`,**没带** `/data?filter[...]`。 - -**排查(确认非代码缺陷)**: - -- `.objectui-sha` 钉在 **`6c1ad9e`(2026-07-05 14:34)**,其源码**已含**切面路由 - `resolveHref`(objectui `#2255`/`b8f158c64`,经 `git merge-base` 确认是 6c1ad9e - 的祖先)。→ 契约与消费端源码都在,逻辑上无需改任何代码。 -- 但**首测时** `packages/console/dist`(gitignore 产物)的 assets 时间戳是 - **2026-07-02 20:29**,**早于** `#2255` 落地(07-05);bundle 里搜不到切面路由的 - 运行期 token。即 vendored bundle 落后于所钉的 objectui 源(framework main 当时 - 尚未 `pnpm objectui:refresh`)。 - -**处置(不改代码,只重建产物)**:用官方脚本 `scripts/build-console.sh` -(经 `OBJECTUI_ROOT` 指向本地 objectui,脚本内部对该 SHA **建独立 git worktree** -于 `.cache/objectui-6c1ad9e20624`,**不改动**共享检出的 HEAD/工作树)重建 console -dist: -- 产物打上 provenance `packages/console/dist/.objectui-sha=6c1ad9e2062…`; -- bundle canary `import/jobs` 通过; -- layout chunk(`ui-layout-*.js`)现同时含 `}/data` 与 `filter[` 运行期字面量。 - -**重建后复测(全绿)**:重启 dev server 加载新 dist,三个切面项的 href 变为 -`…/showcase_task/data?filter[status]=in_progress`(以及 `priority=urgent`、 -`status=in_review`);点击落地到裸数据面,标题「由 URL 定义的数据切面——不绑定任何 -已保存视图」,带**可移除过滤 chip**「状态 = in_progress ×」,渲染 **2 行** -(Build homepage / Ingest pipeline),侧栏该项高亮(active-state 逆向解析 #2272)。 - -**结论**:切面特性本身完全正确,**首测未跑通纯属仓库构建产物陈旧,不需要改任何 -代码**。framework main 侧后续只需在 objectui bump 后跑一次 `pnpm objectui:refresh` -让 vendored dist 追上 `.objectui-sha` 即可(该刷新本就是发布管线职责)。 - -### 10.4 测试环境 - -| 项 | 值 | -| --- | --- | -| 分支 | `claude/wizardly-dubinsky-e30281`(worktree) | -| 启动 | `objectstack dev --ui --seed-admin -p 3777 -d file:/tmp/showcase-dogfood-3777/data.db` | -| Console | vendored objectui,`.objectui-sha=6c1ad9e`;首测吃 07-02 旧 dist,经 `build-console.sh` 重建到 6c1ad9e 后复测(见 §10.3) | -| 端口纪律 | 用隔离端口 3777 + 独立 tempdir DB;**未触碰**其他 agent 占用的 3000/5180 | -| 日期 | 2026-07-05 | diff --git a/examples/app-showcase/docs/test/screenshots/01-task-list-default.jpg b/examples/app-showcase/docs/test/screenshots/01-task-list-default.jpg deleted file mode 100644 index a8fa32b718..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/01-task-list-default.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/02-named-view-inprogress.jpg b/examples/app-showcase/docs/test/screenshots/02-named-view-inprogress.jpg deleted file mode 100644 index 8a316f99d7..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/02-named-view-inprogress.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/03-row-actions-menu.jpg b/examples/app-showcase/docs/test/screenshots/03-row-actions-menu.jpg deleted file mode 100644 index 8755b2f17a..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/03-row-actions-menu.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/04-quickview-no-modal-toast.jpg b/examples/app-showcase/docs/test/screenshots/04-quickview-no-modal-toast.jpg deleted file mode 100644 index 8cf3c734e7..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/04-quickview-no-modal-toast.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/05-markdone-toast.jpg b/examples/app-showcase/docs/test/screenshots/05-markdone-toast.jpg deleted file mode 100644 index aec03c3c60..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/05-markdone-toast.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/06-views-overflow-menu.jpg b/examples/app-showcase/docs/test/screenshots/06-views-overflow-menu.jpg deleted file mode 100644 index 2707c73caa..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/06-views-overflow-menu.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/07-markdone-visible-not-honored-after-reload.jpg b/examples/app-showcase/docs/test/screenshots/07-markdone-visible-not-honored-after-reload.jpg deleted file mode 100644 index f00ad3323d..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/07-markdone-visible-not-honored-after-reload.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/08-detail-markdone-hidden-done-record.jpg b/examples/app-showcase/docs/test/screenshots/08-detail-markdone-hidden-done-record.jpg deleted file mode 100644 index 78a4e9553c..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/08-detail-markdone-hidden-done-record.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/09-detail-markdone-visible-undone-record.jpg b/examples/app-showcase/docs/test/screenshots/09-detail-markdone-visible-undone-record.jpg deleted file mode 100644 index 75945c6df1..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/09-detail-markdone-visible-undone-record.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/10-logtime-form-action-broken-page.jpg b/examples/app-showcase/docs/test/screenshots/10-logtime-form-action-broken-page.jpg deleted file mode 100644 index 1317b3f855..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/10-logtime-form-action-broken-page.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/11-grid-view-inline-edit-available.jpg b/examples/app-showcase/docs/test/screenshots/11-grid-view-inline-edit-available.jpg deleted file mode 100644 index 55214779ab..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/11-grid-view-inline-edit-available.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/12-inlineedit-cell-click-opens-peek-not-editor.jpg b/examples/app-showcase/docs/test/screenshots/12-inlineedit-cell-click-opens-peek-not-editor.jpg deleted file mode 100644 index 26aac26bcb..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/12-inlineedit-cell-click-opens-peek-not-editor.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/13-bulk-bar-builtin-delete.jpg b/examples/app-showcase/docs/test/screenshots/13-bulk-bar-builtin-delete.jpg deleted file mode 100644 index 406e2df808..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/13-bulk-bar-builtin-delete.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/14-bulk-actions-project-4defs.jpg b/examples/app-showcase/docs/test/screenshots/14-bulk-actions-project-4defs.jpg deleted file mode 100644 index 7929af879a..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/14-bulk-actions-project-4defs.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/15-bulk-setlabels-dialog.jpg b/examples/app-showcase/docs/test/screenshots/15-bulk-setlabels-dialog.jpg deleted file mode 100644 index 44f3917d48..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/15-bulk-setlabels-dialog.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/16-bulk-setlabels-confirm.jpg b/examples/app-showcase/docs/test/screenshots/16-bulk-setlabels-confirm.jpg deleted file mode 100644 index 8c8c595b18..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/16-bulk-setlabels-confirm.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/17-bulk-reschedule-dialog.jpg b/examples/app-showcase/docs/test/screenshots/17-bulk-reschedule-dialog.jpg deleted file mode 100644 index d72d009816..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/17-bulk-reschedule-dialog.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/18-task-create-form-notes-shown.jpg b/examples/app-showcase/docs/test/screenshots/18-task-create-form-notes-shown.jpg deleted file mode 100644 index 04b15d8099..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/18-task-create-form-notes-shown.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/19-form-visibleon-not-honored-low-notes-shown.jpg b/examples/app-showcase/docs/test/screenshots/19-form-visibleon-not-honored-low-notes-shown.jpg deleted file mode 100644 index 16641a071d..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/19-form-visibleon-not-honored-low-notes-shown.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/20-form-required-validation-mixed-lang.jpg b/examples/app-showcase/docs/test/screenshots/20-form-required-validation-mixed-lang.jpg deleted file mode 100644 index ab42321d89..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/20-form-required-validation-mixed-lang.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/21-cascade-lookup-table-picker-unfiltered.jpg b/examples/app-showcase/docs/test/screenshots/21-cascade-lookup-table-picker-unfiltered.jpg deleted file mode 100644 index 3eb065656b..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/21-cascade-lookup-table-picker-unfiltered.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/22-invoice-line-items-amount-calc.jpg b/examples/app-showcase/docs/test/screenshots/22-invoice-line-items-amount-calc.jpg deleted file mode 100644 index 9b6a24f8cc..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/22-invoice-line-items-amount-calc.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/23-invoice-paid-conditional-fields-work.jpg b/examples/app-showcase/docs/test/screenshots/23-invoice-paid-conditional-fields-work.jpg deleted file mode 100644 index 5a6d3d1d22..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/23-invoice-paid-conditional-fields-work.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/24-forms-route-tabbed-also-broken.jpg b/examples/app-showcase/docs/test/screenshots/24-forms-route-tabbed-also-broken.jpg deleted file mode 100644 index 0628313a62..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/24-forms-route-tabbed-also-broken.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/25-related-list-editable-grid-english-headers.jpg b/examples/app-showcase/docs/test/screenshots/25-related-list-editable-grid-english-headers.jpg deleted file mode 100644 index d826ef18af..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/25-related-list-editable-grid-english-headers.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/26-filter-status-done-2records.jpg b/examples/app-showcase/docs/test/screenshots/26-filter-status-done-2records.jpg deleted file mode 100644 index bcbfcd91bc..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/26-filter-status-done-2records.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/27-group-by-status-english-group-headers.jpg b/examples/app-showcase/docs/test/screenshots/27-group-by-status-english-group-headers.jpg deleted file mode 100644 index 842cd67a7d..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/27-group-by-status-english-group-headers.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/28-kanban-visualization.jpg b/examples/app-showcase/docs/test/screenshots/28-kanban-visualization.jpg deleted file mode 100644 index 13aec69b1c..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/28-kanban-visualization.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/30-gallery-covers-loaded-ok.jpg b/examples/app-showcase/docs/test/screenshots/30-gallery-covers-loaded-ok.jpg deleted file mode 100644 index 02308cca73..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/30-gallery-covers-loaded-ok.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/31-calendar-visualization-ok.jpg b/examples/app-showcase/docs/test/screenshots/31-calendar-visualization-ok.jpg deleted file mode 100644 index 56b514589d..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/31-calendar-visualization-ok.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/32-timeline-visualization-ok.jpg b/examples/app-showcase/docs/test/screenshots/32-timeline-visualization-ok.jpg deleted file mode 100644 index f019aac735..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/32-timeline-visualization-ok.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/33-gantt-visualization-ok.jpg b/examples/app-showcase/docs/test/screenshots/33-gantt-visualization-ok.jpg deleted file mode 100644 index d1d8ec2258..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/33-gantt-visualization-ok.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/34-row-flow-reassign-same-id-error-plus-done-toast.jpg b/examples/app-showcase/docs/test/screenshots/34-row-flow-reassign-same-id-error-plus-done-toast.jpg deleted file mode 100644 index b2d5c13b67..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/34-row-flow-reassign-same-id-error-plus-done-toast.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/35-view-route-tabular-renders-default-config.jpg b/examples/app-showcase/docs/test/screenshots/35-view-route-tabular-renders-default-config.jpg deleted file mode 100644 index c6bcf6fad3..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/35-view-route-tabular-renders-default-config.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/36-tabular-view-active-userfilters-not-rendered.jpg b/examples/app-showcase/docs/test/screenshots/36-tabular-view-active-userfilters-not-rendered.jpg deleted file mode 100644 index 5a93266b93..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/36-tabular-view-active-userfilters-not-rendered.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/37-pagination-bar-appears-page1of2-footer-count-wrong.jpg b/examples/app-showcase/docs/test/screenshots/37-pagination-bar-appears-page1of2-footer-count-wrong.jpg deleted file mode 100644 index 4ff97e227a..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/37-pagination-bar-appears-page1of2-footer-count-wrong.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/screenshots/38-pagination-page2-rows101-120-footer-shows-page-rows.jpg b/examples/app-showcase/docs/test/screenshots/38-pagination-page2-rows101-120-footer-shows-page-rows.jpg deleted file mode 100644 index 3e71ebfa2e..0000000000 Binary files a/examples/app-showcase/docs/test/screenshots/38-pagination-page2-rows101-120-footer-shows-page-rows.jpg and /dev/null differ diff --git a/examples/app-showcase/docs/test/showcase-console-capability-test-report.docx b/examples/app-showcase/docs/test/showcase-console-capability-test-report.docx deleted file mode 100644 index 1c22c951ea..0000000000 Binary files a/examples/app-showcase/docs/test/showcase-console-capability-test-report.docx and /dev/null differ