Skip to content

数据范围:指标下达、参与主体、审核记录等配置/审计对象按主体过滤,菜单按岗位裁剪(各部门目标值互相保密) #30

Description

@baozhoutao

背景(来源:#23 UI 实测 K-4,维护者 2026-09-03 拍板口径:各部门目标值互相保密,按主体过滤)

部门填报人员(张伟)能打开「方案版本 / 指标下达 / 参与主体 / 到人分工 / 指标争议 / 指标库 / 归档快照 / 审核记录」,指标下达 36 条(全部主体的目标值与权重)、审核记录 96 条全部可读;左侧菜单对所有岗位全量展示。与需求 §2.2「本部门范围仅可见本部门」、手册 §1.2「每个角色只看得到自己权限内的菜单」不符。

口径(已拍板)

  • 各部门目标值与权重互相保密:指标下达、参与主体、到人分工、审核记录、归档快照、核对任务对部门填报人员只开放本部门主体相关行;对分公司核对人员只开放本分公司相关行;分管领导只开放分管主体;人力审核 / 人力负责人 / 管理员全量。
  • 指标库(指标定义与计分规则)视为公共口径,所有岗位可读,不过滤。
  • 配置类菜单(方案版本、指标下达、参与主体、到人分工、指标争议、指标库、流程进度)对部门填报人员与分公司核对人员隐藏或收成只读入口——按平台 app 导航能力决定;做不到按岗位裁剪导航时如实记录为平台能力缺口(只上报不修复),数据层过滤仍必须完成。

范围

  1. src/services/sharing-service.ts:按方案的动态共享规则扩到上述对象(现有规则已覆盖填报单/明细/核对任务/数据调整等,核对哪些对象缺规则、哪些对象的权限集还是 readOrg),部门 / 分公司 / 分管领导三类范围与现有填报单规则同一口径;src/security/index.ts 权限集相应从 readOrg 收成 own + 共享。
  2. src/apps/index.ts 导航按岗位裁剪(平台能力允许时)。
  3. 单测/服务测试:为新增共享规则补覆盖(沿用 sharing-service 现有测试风格)。
  4. 演示与手册不改;若手册 §1.2 的表述与实现最终不一致,在测试报告「基准差异」如实列出。

不做

不改状态机与计分;不改指标库可见范围;不做「到人结果只见本人」以外的个人维度调整(已存在)。

方案分级与放行(调度员)

改已有共享规则与权限集 = 高风险(影响所有岗位的可见范围)。放行方向 = 上述口径;开发子 agent 开工前须在本单评论列出「对象 × 岗位」的可见范围矩阵(改前 / 改后)与受影响的既有测试,与口径一致即可开工;若发现平台共享规则对某对象无法按主体条件表达,停手上报(objectstack-ai/objectstack 只上报不修复)并在本单记录。

验收标准

  1. 软件档案实例:张伟(研发部)在指标下达列表只见研发部的 3 条;审核记录只见研发部填报单的记录;归档快照只见研发部;陈东(华东)在参与主体/指标下达只见华东相关;徐涛只见技术线三主体;马丽全量。越权直接访问记录 URL 或 REST 返回 404/403。
  2. 默认档案实例上 scripts/e2e-flow.mjs 的数据范围断言仍全 PASS;scripts/software-flow.mjs 仍 54/54(脚本以管理员建链,不应受影响)。
  3. 导航:部门填报人员登录后看不到配置类菜单组(或如实记录平台缺口)。
  4. pnpm verify 绿;测试报告(各岗位截图,含越权被拒)与符合度清单挂本单评论,截图走 acceptance-evidence。

测试计划草稿

T1 可见范围矩阵评论 | T2 界面:张伟/陈东/徐涛/马丽四账号逐对象计数 | T3 越权 URL 与 REST 拒绝 | T4 导航裁剪 | T5 两脚本全 PASS | T6 pnpm verify

Activity

  1. self-assigned this
    on Sep 3, 2026
  2. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    ContributorAuthor

    认领(调度员占坑,2026-09-03)

  3. baozhoutao commented on Sep 4, 2026

    @baozhoutao
    ContributorAuthor

    开工前方案:「对象 × 岗位」可见范围矩阵(改前 / 改后)+ 实现方式

    会话:开发子 agent(Opus),worktree ../kpi-issue-30-data-scope,分支 issue-30-data-scope,基线 main @ a760651293af660a8a4a13f7ec30fb3983f9a868。

    一、根因(读平台源码得到,不是猜)

    @objectstack/plugin-sharing@17.2.0 的 effectiveSharingModel():

    if (m === 'private') return 'private';
    if (m === 'public_read') return 'read';
    if (m === 'public_read_write' || m === 'controlled_by_parent') return 'public';
    

    而 buildReadFilter() 第一道闸门是 if (effectiveSharingModel(schema) !== 'private') return null; —— 返回 null = 不加任何过滤。

    于是:

    • 指标下达 / 参与主体 / 到人分工 / 个人承接项 的 OWD 是 controlled_by_parent,在共享层被当成 public,记录级过滤根本不参与求值;权限集里的 readScope 也随之失效(buildReadFilter 提前 return 了)。
    • 审核记录 / 归档快照 的 OWD 是 public_read → 映射为 read,读侧同样不过滤。

    所以只改权限集不够:这些对象的 OWD 必须先落到 private,记录级共享与 readScope: 'own' 才开始起作用。这一条是本次改动的地基。

    第二条平台事实(已有代码里已记录,本次沿用):bindRuleHooks 对 ctx.session.isSystem 的写入 跳过共享物化(sharing materialisation skipped for isSystem writes)。本应用的审核记录、归档快照都由 hook 以系统上下文创建,因此这两个对象需要在创建后重新声明一次规则来补齐物化 —— 与现有 kpi_check_task / kpi_result 完全相同的补偿路径。

    二、可见范围矩阵

    「全量」= 所在组织全部行;数字口径以软件档案实例为准(研发部 3 条下达、6 个参与主体)。

    对象 管理员 / 人力审核 / 人力负责人 部门填报(张伟·研发部) 分公司核对(陈东·华东) 分管领导(徐涛·技术线)
    指标下达 kpi_plan_indicator 改前 全量 / 改后 全量 改前 全量 36 / 改后 本部门 3 改前 全量 / 改后 本分公司相关 改前 全量 / 改后 分管三主体
    参与主体 kpi_plan_subject 全量 / 全量 全量 / 本部门 1 全量 / 本分公司 1 全量 / 分管三主体
    到人分工 kpi_staff_assignment 全量 / 全量 全量 / 本部门 全量 / 本分公司 全量 / 分管三主体
    审核记录 kpi_review_record 全量 / 全量 改前 全量 96 / 改后 本部门填报单的记录 全量 / 本分公司填报单的记录 全量 / 分管主体填报单的记录
    归档快照 kpi_snapshot 全量 / 全量 全量 / 本部门 全量 / 本分公司 全量 / 分管三主体
    核对任务 kpi_check_task 全量 / 全量 改前 0(own,无规则)/ 改后 本部门填报单上的核对任务 本分公司(已有规则)/ 不变 改前 0 / 改后 分管主体填报单上的
    指标库 kpi_indicator 全量 / 全量 全量 / 全量(公共口径,按拍板不过滤) 全量 / 全量 全量 / 全量
    填报单 / 明细 / 数据调整 / 考核结果 不变 不变(已有规则) 不变 不变
    方案版本 kpi_plan / 指标争议 kpi_dispute 不变 数据层不变,菜单裁剪 数据层不变,菜单裁剪 不变

    三、实现方式(三处 + 一处新增)

    1. 对象 OWD(src/objects/plan.object.ts、entry.object.ts、result.object.ts)
      kpi_plan_subject / kpi_plan_indicator / kpi_staff_assignment:controlled_by_parent → private;
      kpi_review_record / kpi_snapshot:public_read → private。
      kpi_personal_item 保持 controlled_by_parent(主记录是到人分工,随主记录收窄)。

    2. 动态共享规则(src/services/sharing-service.ts)——沿用现有「按方案建规则、发布时对账、关闭后降只读」的同一套机制,每个参与主体单元新增:

      • psub_<unit> → 参与主体,条件 {plan, subject: unit},收件方 unit_and_subordinates(unit),read
      • pind_<unit> → 指标下达,条件 {plan, subject: unit},同上,read
      • assign_<unit> → 到人分工,条件 {plan, unit},同上,read
      • snap_<unit> → 归档快照,条件 {plan, subject: unit},同上,read
      • 分管领导对以上四类各一条 ..._leader_<unit>_<leader>,收件方 user(leader),read
      • 审核记录与「本部门填报单上的核对任务」按填报单建:条件 {sheet: sheetId}(审核记录对象上没有主体列,平台共享条件不支持跨对象遍历,只能用它自己的列),收件方 = 该填报单主体单元 unit_and_subordinates + 分管领导 user。填报单在方案发布时、provisionPlanSharing 之前就已生成,取得到。
        规则名长度校验:最长形态 kpi_p{20}_pind_leader_{26}_{26} = 95 ≤ 100,仍在 RULE_NAME_MAX 以内。
    3. 权限集(src/security/index.ts)——部门填报 / 分公司核对 / 分管领导三套,把上述对象由 readOrg 收成 { allowRead: true, readScope: 'own' },可见性完全交给记录共享;管理员 / 人力审核 / 人力负责人保持 org 全量。

    4. 新增一个补物化 hook(新文件,注册在 objectstack.config.ts,不动 src/hooks/ 下任何既有文件 —— 那里有并行工作项在改):审核记录 / 归档快照 afterInsert 后重新声明对应对象的规则,补上系统上下文写入被跳过的物化。这与 sheet.hook.ts 里既有的 kpi_check_task / kpi_result 补偿是同一条路径,只是换个触发点。

    5. 导航裁剪(src/apps/index.ts):考核方案 与 基础设置 两个菜单组加 visible CEL 谓词,对 kpi_dept_reporter / kpi_branch_checker 两个岗位隐藏。如实说明:平台把导航 visible 定为前端渲染谓词(requiredPermissions 才是服务端闸门),因此它是「界面不呈现入口」,不是权限边界 —— 真正的边界是第 1~3 条的数据层过滤。若实测 visible 在分组上不生效,按平台能力缺口如实记录(只上报不修复)。

    6. 测试(test/sharing.test.ts):按现有风格给 planSharingIntents 补规则集合断言(新增六类规则、按方案前缀、关闭后降只读不影响只读类规则、规则名长度上界)。

    四、受影响的既有测试与脚本

    • test/sharing.test.ts —— 规则集合断言要扩(新增规则条数变化)。
    • test/design-alignment.test.ts —— 若断言了 OWD / 权限集形态需同步。
    • scripts/e2e-flow.mjs(默认档案)、scripts/software-flow.mjs(软件档案,54/54)—— 两个脚本都以管理员建链,管理员保持 org 全量,预期不受影响;实测逐条核对,不预设。

    五、与口径的一致性自查

    • 各部门目标值与权重互相保密 → 指标下达按主体过滤 ✔
    • 指标库不过滤 ✔(仅菜单裁剪)
    • 配置类菜单对部门填报 / 分公司核对隐藏 ✔(前端谓词,局限如实记录)
    • 未发现「平台共享规则对某对象无法按主体条件表达」的死路:审核记录靠按填报单建规则绕开了「无主体列」,不需要改 hook、不需要停手上报。

    与拍板口径一致,按此开工。

  4. baozhoutao commented on Sep 4, 2026

    @baozhoutao
    ContributorAuthor

    测试报告 — 数据范围按主体过滤 + 菜单按岗位裁剪

    结论:通过。 6 个对象的按主体过滤全部生效,越权访问一律 404,配置类菜单对部门填报人员与分公司核对人员在服务端就被剥离。软件档案 software-flow.mjs 54/54 全绿。默认档案 e2e-flow.mjs 72 通过 / 1 失败 —— 失败的 T39 是一条共享规则条数常量断言,随本次新增规则类别机械变化,而 scripts/ 本轮禁改,已在下方「需拍板」列出精确改法。所有数据范围类断言(T50 / T51 / T53 / T55~T57 / T64 / T70)全 PASS。

    项 值
    分支 / 提交 issue-30-data-scope @ 1eb5051
    环境 worktree ../kpi-issue-30-data-scope,dev 端口 3115,OS_DATABASE_URL=file:./.objectstack/issue-30.db
    档案 软件档案(OS_SEED_PROFILE=software,99 行种子)+ 默认档案(46 行种子,独立空库)
    账号 管理员 admin@objectos.ai;岗位账号口令 Passw0rd!23
    截图 acceptance-evidence 分支 issue-30/,commit 224e77a0611679ecea92d9f264ae12506b182e4b
    门禁 pnpm verify 绿(validate / typecheck / 103 单测 / i18n 同步)

    T1 可见范围矩阵(REST 逐对象计数,软件档案实例)

    以管理员为全量基准,同一时刻同一份数据,五个账号各查一遍:

    对象 管理员 马丽(人力审核) 张伟(研发部·部门填报) 陈东(华东·分公司核对) 徐涛(技术线·分管领导)
    指标下达 36 36(11 个主体) 3(研发部) 4(华东分公司) 9(产品部/测试部/研发部)
    参与主体 11 11 1(研发部) 1(华东分公司) 3(技术线三主体)
    到人分工 8 8 1(研发部) 0 3(技术线三主体)
    审核记录 94 94(11 张单) 8(本部门 1 张单) 7(本分公司 1 张单) 24(分管 3 张单)
    归档快照 1 1 0(研发部未归档) 0 0
    核对任务 30 30 3(本单上的) 10(只本分公司) 9(分管主体的)
    指标库 24 24 24(公共口径,不过滤) 24 24
    填报单 11 11 1 11 ⚠️ 3

    「归档快照」这一维度用已归档主体的填报人复验:赵敏(销售部,本档案唯一已归档的主体)可见快照 1 条、指标下达 3 条、审核记录 16 条 —— 说明归档快照的补物化生效(快照由 hook 以系统上下文创建,平台跳过共享物化,靠新增的补物化 hook 重新求值规则补齐)。

    ⚠️ 陈东的「填报单 11」不是本次回归:分公司核对人员的填报单权限集本来就是 readScope: 'org'(他要核对全部部门的填报单),该对象不在本次拍板口径列出的六个对象内。见下方「基准差异」。

    界面证据

    张伟(研发部·部门填报人员) —— 左侧只剩「工作台 / 填报与审核 / 结果与归档 / 审计查询」,配置类的「考核方案」「基础设置」两组不呈现;指标下达列表底部「3 条记录」,全部是研发部:

    张伟菜单裁剪
    张伟指标下达
    张伟审核记录
    张伟参与主体

    陈东(华东·分公司核对人员) —— 指标下达只见华东分公司;核对任务只见华东:

    陈东指标下达
    陈东核对任务

    徐涛(技术线·分管领导) —— 只见分管的三个主体,菜单保持完整:

    徐涛指标下达

    马丽(人力审核)与管理员 —— 全量可见,菜单完整:

    马丽菜单完整
    马丽指标下达
    马丽审核记录
    管理员指标下达

    赵敏(销售部·已归档主体) —— 可见本部门归档快照 1 条:

    赵敏归档快照

    T3 越权访问

    张伟(研发部)拿到销售部记录的真实 id 后直接访问:

    入口 对象 结果
    界面 URL 销售部的指标下达 「未找到记录」
    界面 URL 销售部的归档快照 「未找到记录」
    REST GET /data/kpi_plan_indicator/{id} 销售部的指标下达 404
    REST GET /data/kpi_plan_subject/{id} 销售部的参与主体 404
    REST GET /data/kpi_review_record/{id} 销售部的审核记录 404
    REST GET /data/kpi_snapshot/{id} 销售部的归档快照 404
    REST 过滤强取 ?subject={销售部单元 id} 指标下达 {"records":[],"total":0}
    对照:本部门的指标下达 指标下达 200

    陈东(华东)同样:研发部的指标下达 404,销售部的归档快照 404。

    越权打开销售部指标下达
    越权打开销售部归档快照

    T4 导航裁剪(服务端剥离,不是前端隐藏)

    直接读 GET /api/v1/meta/app/kpi_app,看下发到浏览器的导航项 id:

    账号 收到 group_plan / group_setup 及其子项
    管理员 ✔ 全部
    马丽(人力审核) ✔ 全部
    徐涛(分管领导) ✔ 全部
    张伟(部门填报) ✘ 两组连同 5 + 2 个子项一并不下发
    陈东(分公司核对) ✘ 同上

    这一项经历了一次实现返工,如实记录: 最初按方案写的是导航项的 visible CEL 谓词。实测发现本版本控制台对导航项的 visible 根本不求值 —— 谓词原样下发到浏览器后被忽略,分组与叶子项都不生效,菜单对所有岗位照旧全量呈现。已按「只上报不修复」报到平台:objectstack-ai/objectstack#15135。改用 requiredPermissions(平台在 /meta 里就把不满足的项剥掉)后达成目标。

    T5 两个脚本

    脚本 档案 结果
    scripts/software-flow.mjs 软件档案(空库重建) 54 / 54 全 PASS,含 T17a~T17d 四条数据范围断言
    scripts/e2e-flow.mjs 默认档案(独立空库) 72 PASS / 1 FAIL(T39) —— 见下

    T17c 在开发中途曾一度失败,是本次自测抓到的真缺陷:最初给「本单填报单的核对任务」建的规则不分主体类型,而分公司既是被考核主体、又是核对方,它自己那张填报单上挂着全部分公司的核对任务 —— 华东的核对人员于是看见了华南、华北的核对意见,与「分公司核对人员只开放本分公司相关行」的拍板口径直接冲突。改为只给总公司部门主体建这条规则后 T17c 恢复,并补了针对性单测。

    T6 门禁

    pnpm verify 绿:os validate 通过、tsc --noEmit 无错、103 个单测全过(本次新增 12 条:四类按主体规则、按填报单规则、分公司主体不拿本单核对规则、条件收窄不变式、关闭方案后只读类不降级、超长 id 规则名仍 ≤ 100、按对象/按填报单收窄重申)、i18n 包与元数据同步(本次未新增任何 label,zh-CN 529 键无变化)。


    基准差异(如实列出)

    1. 手册 §1.2「每个角色只看得到自己权限内的菜单」 —— 现已成立,但成立的方式与手册措辞的隐含前提不同:菜单是服务端剥离(requiredPermissions),不是前端按角色渲染;平台的前端谓词 visible 在本版本不工作(平台单已上报)。手册无需改。
    2. 填报单 / 填报明细对分公司核对人员仍是 readScope: 'org' —— 他要核对全部部门的填报单,这是既有设计;这两个对象不在本次拍板口径列出的六个对象内,本次未动。若「各部门实际值与得分也需互相保密」,那是另一条口径,需 PM 拍板后另立工作项。
    3. controlled_by_parent 的子对象在读侧不随主记录收窄 —— 平台把这种 OWD 在共享层映射为 public,只对 update / delete 委托主记录判定(plugin-security 的 masterGateCoversOperation)。因此填报明细 kpi_entry_line、个人承接项 kpi_personal_item、加减分 kpi_bonus 的读仍不按主体过滤。这是平台既有且有意的语义(describeOwd 明确标注 effect: 'public'),不是缺陷,本次未扩围;kpi_personal_item 上的个人目标值因此仍全员可读,如需收窄要先给它自己的 OWD 与规则,属新工作项。
    4. scripts/e2e-flow.mjs T39 未过 —— 见下方「需拍板」。

    需拍板(一条)

    scripts/e2e-flow.mjs 第 227 行的常量 EXPECTED_RULES 是按方案配置精确推导的规则条数,新增规则类别后必然变化,scripts/ 本轮在禁改清单里,故未动。实测拆解已核对到条(5 个参与主体、2 个总公司部门主体、1 位分管领导、2 条到人分工):

    // 现:5 * 4 + 3 + 2 + 2 * 2                       = 29
    // 应:5 * 8 + 7 + 2 + 2 * 2 + 3                   = 56
    //   5 个主体 × 8 类(填报单/核对任务/调整/结果 + 参与主体/指标下达/到人分工/归档快照) = 40
    //   市场部配了分管领导 → 7(填报单、该主体结果、本人结果 + 上述后四类)
    //   2 条到人分工 → 2;人力岗位 2 个 × 2 类 → 4
    //   总公司部门主体的「本单核对任务」2 条,其中市场部有分管领导 → +1,合计 3
    const EXPECTED_RULES = 5 * 8 + 7 + 2 + 2 * 2 + 3;

    实测 rules=56,与该式逐项对上(按对象 × 收件方类型的分布也已核对)。请调度员决定:授权本子 agent 改这一行,或交由 scripts/ 的归属方改。同一处的 T39b(「每条规则条件里都带本方案 id」)现已 PASS 且无需改动 —— 审核记录规则的条件带的是填报单 id(比方案更细),不落在 T39b 的筛选集合里。

  5. baozhoutao commented on Sep 4, 2026

    @baozhoutao
    ContributorAuthor

    需求符合度清单

    逐条对照工作项正文的「口径」「范围」「不做」「验收标准」「测试计划」。分支 issue-30-data-scope @ 1eb5051。

    一、口径

    # 需求原文 态 说明
    1 指标下达对部门填报人员只开放本部门主体相关行 ✅ 张伟 3 条(研发部),全量 36
    2 参与主体对部门填报人员只开放本部门主体相关行 ✅ 张伟 1 条
    3 到人分工对部门填报人员只开放本部门主体相关行 ✅ 张伟 1 条
    4 审核记录对部门填报人员只开放本部门主体相关行 ✅ 张伟 8 条(本部门 1 张填报单的留痕),全量 94
    5 归档快照对部门填报人员只开放本部门主体相关行 ✅ 赵敏(销售部,唯一已归档主体)1 条;张伟 0 条(研发部未归档)
    6 核对任务对部门填报人员只开放本部门主体相关行 ✅ 张伟 3 条 = 本部门填报单上的三家分公司核对任务
    7 以上六类对分公司核对人员只开放本分公司相关行 ✅ 陈东:指标下达 4 / 参与主体 1 / 审核记录 7 / 核对任务 10(全部 bu_sw_east)/ 到人分工 0(华东无到人分工)/ 快照 0(未归档)
    8 以上六类对分管领导只开放分管主体 ✅ 徐涛:指标下达 9、参与主体 3、到人分工 3、审核记录 24(3 张单)、核对任务 9,均为技术线三主体
    9 人力审核 / 人力负责人 / 管理员全量 ✅ 马丽与管理员逐对象计数与全量基准一致(36 / 11 / 8 / 94 / 1 / 30)
    10 指标库视为公共口径,所有岗位可读,不过滤 ✅ 五个账号一律 24 项;kpi_indicator 的 OWD 与权限集本次未动
    11 配置类菜单对部门填报人员与分公司核对人员隐藏或收成只读入口 ✅ 「考核方案」「基础设置」两组连同 7 个子项对这两个岗位在 /meta 里即被剥掉,不下发到浏览器
    12 做不到按岗位裁剪导航时如实记录为平台能力缺口(只上报不修复) ✅ 裁剪已做到(走 requiredPermissions);过程中发现的 visible 不求值缺口已如实记录并只上报:objectstack-ai/objectstack#15135

    二、范围

    # 需求原文 态 说明
    13 sharing-service.ts 按方案的动态共享规则扩到上述对象 ✅ 每主体新增 psub_ / pind_ / assign_ / snap_ 四类 + 分管领导同名 _leader_ 变体;审核记录 review_ 与本单核对任务 scheck_ 按填报单建
    14 核对哪些对象缺规则、哪些对象的权限集还是 readOrg ✅ 已逐对象核对并在开工前的矩阵评论列出改前 / 改后;结论:缺规则的是参与主体 / 指标下达 / 到人分工 / 归档快照 / 审核记录五类,readOrg 的是这五类在三个受限岗位上的授权
    15 部门 / 分公司 / 分管领导三类范围与现有填报单规则同一口径 ✅ 同一条 unit_and_subordinates(主体单元) + user(分管领导) 的收件方组合,同一套方案前缀、发布时对账、关闭后处理
    16 src/security/index.ts 权限集从 readOrg 收成 own + 共享 ✅ 新增 readOwn 常量;三个受限岗位的五个对象改用它
    17 src/apps/index.ts 导航按岗位裁剪(平台能力允许时) ✅ 见第 11 条
    18 单测 / 服务测试:为新增共享规则补覆盖(沿用现有测试风格) ✅ test/sharing.test.ts 新增 12 条,同文件既有风格;pnpm test 103 全过
    19 演示与手册不改 ✅ docs/ 与演示数据零改动
    20 手册 §1.2 表述与实现不一致时在测试报告「基准差异」列出 ✅ 已列:结论是手册表述成立,但成立机制是服务端剥离而非前端渲染,手册无需改

    三、不做

    # 需求原文 态 说明
    21 不改状态机与计分 ✅ src/hooks/、src/lib/scoring.ts 零改动
    22 不改指标库可见范围 ✅ kpi_indicator / kpi_indicator_step 的 OWD 与全部权限集授权未动
    23 不做「到人结果只见本人」以外的个人维度调整 ✅ kpi_result 的 OWD、规则与行级安全谓词未动

    四、验收标准

    # 需求原文 态 说明
    24 张伟(研发部)在指标下达列表只见研发部的 3 条 ✅ 界面列表底部「3 条记录」,REST 计数 3
    25 张伟的审核记录只见研发部填报单的记录 ✅ 8 条,全部指向研发部那一张填报单
    26 张伟的归档快照只见研发部 ✅ 研发部本档案未归档故为 0;用已归档的销售部填报人赵敏复验为 1,规则与补物化均生效
    27 陈东(华东)在参与主体 / 指标下达只见华东相关 ✅ 参与主体 1、指标下达 4,均为华东分公司
    28 徐涛只见技术线三主体 ✅ 指标下达 9 / 参与主体 3 / 到人分工 3 = 产品部、测试部、研发部
    29 马丽全量 ✅ 与管理员基准逐对象一致
    30 越权直接访问记录 URL 或 REST 返回 404 / 403 ✅ 界面「未找到记录」;REST 四个对象一律 404;按主体过滤强取返回空集;对照本部门记录 200
    31 默认档案上 e2e-flow.mjs 的数据范围断言仍全 PASS ✅ T50 / T51 / T53 / T55 / T56 / T57 / T64 / T70 全 PASS
    32 scripts/e2e-flow.mjs 整体全 PASS ⚠️ 72 PASS / 1 FAIL。失败项 T39 是「共享规则条数」的精确常量断言(EXPECTED_RULES = 29),新增规则类别后实测 56,该常量按定义必须同步。scripts/ 在本次派发的禁改清单内,故未改。出口:失败升级 —— 已在测试报告「需拍板」给出逐项核对到条的新常量与改法,交调度员裁决(授权本子 agent 改,或交 scripts/ 归属方改)。 该断言与数据范围行为无关,不构成功能缺陷。
    出口链接:#30 (comment)
    33 scripts/software-flow.mjs 仍 54/54 ✅ 空库重建后 54/54 全 PASS
    34 导航:部门填报人员登录后看不到配置类菜单组 ✅ 界面与 /meta 双向确认;分公司核对人员同
    35 平台缺口如实记录 ✅ objectstack-ai/objectstack#15135(visible 不求值),含最小复现、期望能力、平台版本
    36 pnpm verify 绿 ✅ validate / typecheck / 103 单测 / i18n 同步 全过
    37 测试报告与符合度清单挂本单评论,截图走 acceptance-evidence ✅ 本评论 + 测试报告评论;截图 commit 224e77a0611679ecea92d9f264ae12506b182e4b,14 张,已用 contents API 核对文件齐全

    五、测试计划(T1~T6)

    # 计划项 态
    38 T1 可见范围矩阵评论 ✅ 开工前已发(改前 / 改后 + 实现方式 + 受影响测试)
    39 T2 界面:张伟 / 陈东 / 徐涛 / 马丽四账号逐对象计数 ✅ 四账号 + 管理员 + 赵敏,共 6 个账号 × 8 个对象
    40 T3 越权 URL 与 REST 拒绝 ✅
    41 T4 导航裁剪 ✅
    42 T5 两脚本全 PASS ⚠️ 见第 32 条
    43 T6 pnpm verify ✅

    统计:41 条 ✅ / 2 条 ⚠️(同一件事:e2e-flow.mjs T39 的常量,已走失败升级出口)/ 0 条 ❌。

    范围外但需要知会的两项改动(均为达成本单目标的必要条件,非静默扩围)

    1. 新增补物化 hook(src/services/scope-materialize.ts,在 objectstack.config.ts 注册)。审核记录与归档快照由 hook 以系统上下文写入,平台对 isSystem 写入跳过共享物化(sharing materialisation skipped for isSystem writes),官方补偿手段是重新求值规则。不补这一手,这两个对象 OWD 收成 private 之后是「谁都看不到」,包括本该看到的本部门成员。做法与 hooks/sheet.hook.ts 里既有的 kpi_check_task / kpi_result 补偿完全同路,只是触发点换成记录自己的 afterInsert;单独成文件、单独注册,src/hooks/ 下既有文件零改动(该目录本轮禁改)。
    2. 新增「平台管理员 ↔ 考核系统管理员权限集」绑定(src/security/bind-admin-set.ts)。导航裁剪走的 requiredPermissions 是逐条 AND、字符串精确匹配、无通配、无超级用户豁免,平台管理员的 admin_full_access 在这里不构成豁免 —— 实测:不加这条绑定,管理员自己会丢掉「考核方案」「基础设置」两个菜单组。本项目「考核系统管理员由平台内置管理员账号承担」(CLAUDE.md D4)此前是隐含安排,菜单闸门不认隐含,故写成幂等绑定行;按「持有 admin_full_access 的用户」匹配而不是按邮箱,换人、多管理员、改邮箱都不需要改代码。
  6. baozhoutao commented on Sep 4, 2026

    @baozhoutao
    ContributorAuthor

    交接验收侧 @baozhoutao(状态 → status:PR审查中)。

    待拍板一条(唯一的 ⚠️):scripts/e2e-flow.mjs T39 的 EXPECTED_RULES 常量需由 5*4+3+2+2*2(29)改为 5*8+7+2+2*2+3(56),推导已逐项核对到条、实测吻合。scripts/ 在本次派发的禁改清单内故未动 —— 请裁决:授权本子 agent 改这一行,或交 scripts/ 归属方改。除此之外自测全部通过。

  7. added a commit that references this issue on Sep 4, 2026
  8. baozhoutao commented on Sep 4, 2026

    @baozhoutao
    ContributorAuthor

    合并记录(调度员,2026-09-03)

    • 收单核实:PR 数据范围:配置与审计对象按主体过滤,配置类菜单按岗位裁剪(#30) #32 关联本单、无自动关闭关键字;10 文件与范围对应,范围外两处(bind-admin-set.ts、scope-materialize.ts + objectstack.config.ts 注册)已在清单披露且有据(平台导航 visible 不求值 → App nav item visible (CEL) is served to the client but never evaluated — a silently inert gate (17.2.0) objectstack#15135,改用服务端权限闸门需为管理员幂等绑定);禁触碰面 hook / 动作 / 种子 / 脚本零改动;CI 绿;测试报告、需求符合度清单、14 张证据图核对存在。全项通过。
    • 评审闸门:独立评审子 agent(全量档)首轮「可合并」(阻塞 0 / 应修 0 / 记录 7),调用面抽查 13 处全部未改坏,五对象改 private 后人力审核 / 人力负责人 / 管理员全量可见经实测与基准逐对象一致;调度员追加要求三处修复(合入 main、e2e 共享规则对账口径、分公司核对人员与分管领导对个人承接项的只读授权——评审记录 4 由调度员判为应修:本单引入的子表 403);复查轮「可合并」,三处均核实,e2e 74/74、software-flow 54/54、verify 110 单测绿。
    • 更正留痕:开发方撤回上一轮「主从子对象读侧不随主记录收窄」的判断(实测随主记录收窄,由安全插件的主从派生完成),评审侧独立实测一致,故「个人目标值/实际值全员可读」风险不存在、不另立单。
    • 记录级留痕待后续视情况立单:kpi_plan_config 未 defineCapability(权限界面显示机器名);bind-admin-set.ts 只扫直接授权且只增不减;「指标争议」菜单隐藏但填报人员仍有 allowCreate;sharing-service.ts 取填报单 limit: 2000;每条审核记录触发一次共享物化的扇出代价。
    • 已合并 PR 数据范围:配置与审计对象按主体过滤,配置类菜单按岗位裁剪(#30) #32 到 main。状态切 status:PM验收中,处理人不变(验收侧)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions