Skip to content

feat(approvals): add 'position' approver type resolved via sys_user_position (ADR-0090 D3)#2738

Merged
os-zhuang merged 1 commit into
mainfrom
claude/festive-noether-jht8t6
Jul 10, 2026
Merged

feat(approvals): add 'position' approver type resolved via sys_user_position (ADR-0090 D3)#2738
os-zhuang merged 1 commit into
mainfrom
claude/festive-noether-jht8t6

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

问题

ADR-0090 D3 之后,审批的 role approver type 实际解析的是 better-auth 的组织成员级别(sys_member.role:owner/admin/member),而不是岗位。下游应用(如 hotcrm)写的 { type: 'role', value: 'sales_manager' } 会静默匹配不到任何人——展开落空后回退成 role:sales_manager 字面量,审批请求永远停在一个不可能行动的 approver 上。规范里没有任何方式把审批路由到一个岗位

方案

spec(packages/spec/src/automation/approval.zod.ts)

  • ApproverType 新增 'position':value = 岗位 machine name,经 sys_user_position 展开;
  • role 的注释/描述改为它实际的语义(membership tier),xRef picker map 增加 position 映射。

plugin-approvals(approval-service.ts)

  • expandApprovers 新增 position 分支:sys_user_positionsys_member.role 过渡源(ADR-0057 D4),与 plugin-sharing 的 PositionGraphService 语义完全一致——同一个岗位,审批路由到的人 = 共享引擎展开的人;
  • 顺带修正:spec 枚举值 department 之前在运行时只匹配 off-spec 的 business_unit/bu 方言,现在按规范拼写也能解析(方言分支保留,属既有债务)。

lint(新规则 validateApprovalApprovers,已接入 os lint)

  • approval-role-not-membership-tier(warning):role approver 的 value 不是 membership tier(owner/admin/member/guest)时告警,fix-it 直接给出 { type: 'position', ... } 改写;
  • approval-approver-type-unknown(warning):off-spec 的 approver type(含 business_unitdepartment 的 fix-it)。

文档 / skill / showcase

  • content/docs/automation/approvals.mdx 增加 position vs role 的 Callout;approvals/flows 文档、objectstack-automation SKILL(含 Approver Types 表)、showcase 示例里所有把岗位名写成 type: 'role' 的示例全部改为 type: 'position'(正是本 PR 要消灭的教学陷阱);
  • content/docs/references/automation/approval.mdxgen:docs 再生成。

测试

  • @objectstack/spec@objectstack/lint@objectstack/plugin-approvals@objectstack/cli 测试全绿(spec 6672 tests;新增 position 展开/租户隔离/过渡源并集/字面量回退、department 拼写、lint 规则 6 个用例);
  • showcase 示例经 turbo build 通过;check:skill-docs 同步检查通过;
  • 已合入最新 main(含 fix(spec): bump PROTOCOL_VERSION 12→13 to match spec major (unblock main CI) #2726 的 PROTOCOL_VERSION 修复)。

已附 changeset(spec/plugin-approvals/lint minor,cli patch)。

🤖 Generated with Claude Code

https://claude.ai/code/session_01DgP1vEK6nrkkvnwQxCPGbe


Generated by Claude Code

…osition (ADR-0090 D3)

Post ADR-0090 D3 the 'role' approver type resolves against the better-auth
org-membership tier (sys_member.role: owner/admin/member) — it was never a
position, so downstream apps authoring { type: 'role', value: 'sales_manager' }
silently routed approvals to nobody.

- spec: ApproverType gains 'position' (value = position machine name); the
  xRef picker map and value description follow. 'role' is documented as the
  membership tier it actually is.
- plugin-approvals: expandApprovers resolves 'position' via sys_user_position
  ∪ the sys_member.role transition source (ADR-0057 D4), mirroring
  PositionGraphService in plugin-sharing; the spec value 'department' is now
  honored alongside the pre-existing business_unit/bu dialect.
- lint: new validateApprovalApprovers rule — approval-role-not-membership-tier
  warns when a role approver's value is not a membership tier and prescribes
  the position rewrite; approval-approver-type-unknown flags off-spec approver
  types with a business_unit→department fix-it. Wired into os lint.
- docs/skill/showcase: approver examples switch to { type: 'position' }; the
  authoring skill's Approver Types table and the approvals guide call the
  trap out explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgP1vEK6nrkkvnwQxCPGbe
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 10, 2026 4:09am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, @objectstack/lint, @objectstack/plugin-approvals, @objectstack/spec.

97 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via packages/cli, @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/api/data-flow.mdx (via @objectstack/cli)
  • content/docs/api/environment-routing.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/plugin-approvals, packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/cli, packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via packages/cli)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/cli, packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/permissions/authentication.mdx (via @objectstack/cli)
  • content/docs/permissions/authorization.mdx (via @objectstack/lint, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/cli, @objectstack/plugin-approvals, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/protocol/objectos/realtime-protocol.mdx (via @objectstack/cli)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/cli, @objectstack/plugin-approvals, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-approvals, @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants