Skip to content

列表行级 edit/delete 与批量删除未接入服务端 effective 操作集(#3391 遗漏的第四个面) #3720

Description

@os-zhuang

#3391 的遗漏项(前端,objectui 仓)。在收口 #3546 时扫描全仓调用点发现。

背景

/me/permissions 的 effective 操作集(apiOperations)目前已接入三个面:

但主列表的「行级 CRUD」走的是一条完全独立、从未接入的链路 —— 它不经过 resolveCrudAffordances,因此上面三轮改动一次都没覆盖到它。

问题

plugin-grid/src/rowCrudAffordances.ts:49resolveRowCrudAffordances() 签名里没有 effective 集参数。行级门(ObjectGrid.tsx:1479)只由三项决定:

operations ?? { update: !!onEdit, delete: !!onDelete }   // ← 默认全开
  ∧ userActions.{edit,delete} 显式 false 的 opt-out

ObjectView无条件下传 onEdit / onDelete 的,所以视图 JSON 未显式声明 operations 时该门恒为 true。另外:

  • ObjectGrideffectiveApiOps 只喂给 export(ObjectGrid.tsx:12662295);ListView.tsx:672 同理 —— 这正是 PR-4 当时的范围。
  • ObjectGrid 内唯一的权限调用是字段级 perms.checkField(1238),没有对象级 can()
  • 同一个 canDelete 还驱动批量删除(ObjectGrid.tsx:1615:canDelete && onBulkDelete → effectiveBulkActions = ['delete'])。

即:effective 集不含 update / delete 的调用者,主列表行 kebab 的 Edit/Delete 和批量删除仍然照常显示。批量删除是破坏性操作,风险高于 #3546 修的那批按钮。

顺带:该链路连 ADR-0103 的 bucket 锁也没接 —— rowCrudAffordances.ts 的注释写「bucket-level lock is applied upstream via the view's operations.*」,但上面的默认值说明并没有。建议一并确认。

复现(已验证)

写了一个针对真实 ObjectGrid 的组件级探针,mock usePermissions().getObjectApiOperations,带控制组:

用例 effective 集 行 Edit/Delete + 选择框
A 基线 ['get','list','create','update','delete'] 出现 ✅ 符合预期
B 本 issue ['get','list'] 仍然出现
C 控制组 full,但 userActions:{edit:false,delete:false} 消失 ✅

C 通过是关键:它证明断言确实能观测到「隐藏」,所以 B 不是假阳性。

服务端侧也确认状态 B 真实可达 —— annotateEffectiveApiOperations(plugin-hono-server/src/hono-plugin.ts:339)在对象 apiMethods 收紧曝光、或 allowExport:false 时就会下发受限数组。

⚠️ 说明:以上为组件级 + 服务端代码走查验证。未做端到端浏览器实测(本次会话缺少 preview 工具链),因此「真实 console 里点得到」这一步仍是推断。

范围(objectui)

  • resolveRowCrudAffordances() 增加 effective 操作集入参,canEditupdatecanDeletedelete
  • ObjectGrid 把已有的 effectiveApiOps(目前只喂 export)接到行级门 + 批量删除。
  • 确认 ListView / 移动端卡片等其他消费 rowActions 的面。
  • 确认 bucket 锁是否也需要在这条链路补上(见上)。
  • 测试:效仿 objectui#2876 的矩阵,并保留 userActions opt-out 的控制组用例。

保持与前三轮一致的语义:交集,永不并集;effective 缺失(全开对象 / 旧后端 / 未挂 PermissionProvider)回退现行为。

关联

#3391(跟踪)、#3546(detail/form 面)、objectui#2823(PR-4 工具栏)、objectui#2832、objectui#2876。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions