跳至内容

第13章 面向中国企业的权限增强模块设计

本章是后续模块的设计草案,不是要求第一版全部实现。模型名暂用 odoocc.auth.* 表示候选命名,真正开发前应结合仓库规范再定。

13.1 中国大陆企业常见使用习惯

大量企业管理员并不以 Odoo 的“技术组 + domain”思考,而是以这些概念工作:

  • 岗位:销售员、区域经理、采购主管、出纳、会计、仓库主管。
  • 组织:集团、法人公司、事业部、工厂、部门、科室、项目组。
  • 兼岗:同一人在不同公司或组织承担多个角色。
  • 数据范围:本人、本部门、本部门及下级、直属下属、指定部门、指定人员、本公司、指定公司、全部。
  • 流程能力:提交、审核、复核、过账、付款、作废、导入、导出、打印。
  • 临时授权:请假代理、项目期授权、紧急提权、到期自动收回。
  • 内控:申请与审批分离、制单与过账分离、供应商维护与付款审批分离。
  • 操作习惯:按岗位发权限、复制同岗位人员、Excel 批量配置、企业微信/钉钉/飞书同步组织与审批。
  • 管理期望:能回答“这个人为什么有权”“撤掉某岗位会失去什么”“这条权限何时到期”。

原生权限底座能执行其中一部分,但没有把这些概念组织成面向业务管理员的产品。

13.2 先建立五条设计原则

原则 1:技术能力与业务岗位分开

原生 res.groups 继续表示稳定技术能力;业务角色/岗位是面向管理员的模板,可以映射一个或多个原生组、数据范围和业务能力。

业务角色“华东销售经理”
  -> 原生组:销售 / 看全部线索、销售 / 管理员
  -> 数据范围:华东事业部及下级
  -> 业务能力:订单折扣审批(限额 20%)
  -> 公司范围:上海公司、苏州公司

不要把部门、每个临时授权或每个员工都变成 res.groups

原则 2:原生 ACL 是能力上限

第一阶段增强授权不应突破用户原生 ACL 上限:

增强层说“可看本部门”
AND 原生没有模型 read ACL
= 仍然不能看

需要新增模型能力时,通过受治理的角色映射授予原生组,而不是让动态范围引擎偷偷绕过 ACL。

原则 3:强制边界只能收紧

增强数据范围应与原生结果做 AND,不能替换或与全局公司规则 OR:

最终范围 = 原生规则范围 AND 增强组织范围

同一用户的多个合法 assignment 可以在增强层内部 OR,但每个 OR 分支必须把该 assignment 的 capability、公司、数据范围、额度和条件绑定在一起;不能先把所有 capability 做 OR、再把所有 scope 做 OR。公司与合规强制边界仍在外层 AND。

原则 4:显示和执行使用同一决策来源

UI 可以根据同一 capability 决策显示按钮,但安全校验必须在服务端再次执行。不能分别维护“一套按钮 groups”和“一套 Python if”,否则必然漂移。

原则 5:先做可解释治理,再做通用策略引擎

第一版最有价值的往往不是接管所有 ORM 查询,而是:

  • 展示用户有效组、ACL、全局规则和组规则组合。
  • 展示授权来源和到期时间。
  • 模拟某用户是否能访问样例记录。
  • 做角色矩阵、冲突检查和变更预览。

在没有真实客户重复验证前,不要一开始全局重写 ir.rule

13.3 建议架构

                组织/人员主数据
      res.company   组织树   employee/user/job
                     |
                     v
业务角色模板 ----> 授权申请/审批 ----> 生效 Assignment
    |                                      |
    |                                      +--> 公司与组织数据范围
    +--> 原生 res.groups 投影              +--> 有效期/来源/代理
    +--> capability 列表                   +--> 审计事件
                     |                     |
                     v                     v
              原生 ACL / rules      增强 scope/capability 决策
                     \                   /
                      \                 /
                       v               v
                最终服务端授权结果
                       |
             UI 展示 / 原因解释 / 影响预览

推荐判定公式:

NativeAllowed =
    原生 ACL grant
    AND 原生全局规则
    AND(无原生组规则 OR 原生组规则 OR)

EnhancedAllowed(action, record) = OR_i (
    Assignment_i 当前有效
    AND Assignment_i 授予 action 所需 capability/CRUD
    AND record 属于 Assignment_i 的公司范围
    AND record 属于 Assignment_i 的组织/数据范围
    AND Assignment_i 的额度、SoD 等条件通过
)

Allowed = NativeAllowed
          AND EnhancedAllowed(仅对已进入 enforce 的模型/动作)
          AND 状态迁移等不可放宽业务不变量

其中 capability 只在相应业务动作需要,不应让普通 read 也无条件检查一个无关能力。关键是以 assignment 为授权元组:不能让“A 岗位的全公司 read 范围”与“B 岗位的付款 capability”拼成一条任何岗位都未实际授予的全公司付款权限。

建议把默认语义写死并纳入测试:

  • 未注册 adapter 的模型保持 Odoo 原生行为。
  • 每个 adapter 显式声明 subject_types,默认只包含 Internal User。当前主体不在集合中时,该 adapter 不接管 CRUD/scope,保持 Odoo 原生结果。
  • 主体在集合中时,shadow 模式只记录决策差异,不改变结果;进入 enforce 后,没有匹配的有效 assignment 就拒绝增强授权。
  • 受保护 capability 的方法注册独立于 CRUD/scope adapter。任何能到达该方法的主体若没有匹配 capability 都默认拒绝,不能因为不在 subject_types 中就回退成“有原生 write 即可执行”。
  • 因而 Portal/Public 默认保留原生 CRUD 和记录规则,但不能绕过受保护方法;只有经过独立威胁建模和显式适配后,才参与 assignment/capability。
  • su=True 是系统旁路,不是业务角色。受信任的私有系统路径可显式旁路增强检查,但公开方法和 controller 必须在 sudo 前按真实调用者授权;高风险旁路记录 uid、原始主体、原因和调用点,且原因不能来自 RPC 可控 context。

13.4 候选核心模型

odoocc.auth.role:业务角色模板

建议字段:

字段 作用
code 稳定唯一编码,不以中文名作为集成键
name 中文业务名称
active 稳定角色身份是否可创建新版本
current_version_id 当前推荐版本,不改变既有 assignment
owner_user_id 角色负责人/定期复核人

角色模板不是 res.groups 的简单别名。另建不可变的 odoocc.auth.role.version 保存 group_idscapability_version_ids、默认 scope 版本、risk_level、业务边界说明和版本号;已批准版本不得原地修改,变更要创建新版本、生成影响预览并重新审批迁移。

odoocc.auth.assignment:生效授权

建议字段:

字段 作用
user_id / employee_id 授权对象;明确哪个是运行时主体
role_id / role_version_id 稳定角色身份与批准时固定的不可变版本
organization_id 岗位所在组织
company_ids 授权声明覆盖的法人公司
scope_policy_version_id 批准时固定的不可变数据范围版本
effective_from / effective_to 精确生效与失效时间
state draft/requested/approved/active/expired/revoked
source_type 岗位、兼岗、临时、代理、紧急、手工
request_id 来源审批单
reason 业务理由
revision 并发控制与缓存版本

不要直接把所有 assignment 展开为一条用户专属 ir.rule。大量用户会造成规则爆炸和 OR SQL 膨胀。assignment 必须固定指向获批版本;否则管理员修改共享模板会让所有历史授权在没有新审批的情况下静默增权。

odoocc.auth.scope.policy:结构化数据范围

建议字段:

字段 作用
code / name 稳定标识和中文名
active / current_version_id 稳定策略身份与当前推荐版本

范围明细放在不可变 scope.version 中,包括 scope_typeorganization_idsuser_idscompany_idsinclude_unassigned。不要让普通管理员直接编辑任意 Python domain;范围类型应由受测试的 adapter 转成 domain。

odoocc.auth.model.adapter:业务模型适配器

同样的“本人”在不同模型上可能是:

sale.order.user_id
crm.lead.user_id
hr.expense.employee_id.user_id
stock.picking.user_id 或 picking_type/warehouse 责任关系

适配器应显式登记:

字段 例子
model_id sale.order
operation read/write/create/unlink
subject_types 默认仅 Internal;显式选择 Portal/Public
owner_field_path user_id
department_field_path user_id.employee_id.department_id 或业务专用字段
company_field_path company_id
shared_field_path 受控的业务成员字段,如 member_user_ids
scope_types_supported 本人、部门及下级等
adapter_code 受审计的 Python builder,不是任意 safe_eval

每个业务模型显式适配,虽然看起来不如“万能字段猜测”炫目,但更可测试、更可解释。不要默认把 chatter 的 message_partner_ids 当成安全成员字段:关注者经常能被用户或自动化修改,只有业务模型明确保护其写入时才能专门适配。

odoocc.auth.capability:业务操作

capability 也应采用“稳定身份 + 不可变版本”。稳定 code 例如:

sale.order.confirm
sale.order.cancel
sale.order.discount_approve
account.move.post
account.payment.approve
stock.picking.validate
base.data.export_sensitive
report.financial.print

odoocc.auth.capability.version 固定 model_idmethod_name、风险级别、SoD 要求、是否可临时授权、审计级别和执行契约版本;role version 引用具体 capability version。方法实现仍属于代码,部署代码变化时要用契约版本或代码映射做兼容检查。

即使 role/capability/scope 都版本化,group_ids 指向的原生组语义仍会随 implied_ids、ACL、规则、动作和模块升级变化。因此“不可变版本”只冻结批准时的引用集合,不等于冻结全部运行时授权语义。安装/升级或安全元数据变化后必须重新展开授权面、生成差异、记录审计,并对高风险增权要求重新验证或审批。

请求、审批、职责分离与审计

模型 作用
odoocc.auth.request 新增、变更、撤销、续期、代理、紧急授权申请
odoocc.auth.approval 多级审批记录和意见
odoocc.auth.sod.rule 角色/能力互斥、不得自批、双人复核
odoocc.auth.audit.event 授权和敏感操作的追加式事件
odoocc.auth.review 周期性权限复核和确认

这些模型可逐阶段实现,不要求 MVP 同时完成。

13.5 公司、组织、岗位必须分开

不要把集团、法人、分公司、事业部、工厂、部门全部塞进 res.company

  • res.company 主要表达法人/账套和多公司上下文。
  • 组织单元应有独立树,建议 _parent_store=Trueparent_pathcompany_id 和组织类型。
  • hr.department 已有部门树,可按依赖范围复用或做轻量扩展。
  • hr.job 更接近职位资料,不天然等于“某人在某组织的岗位任职关系”。
  • 同一用户可以在不同公司对应不同员工记录,跨公司取员工关系时必须明确。

建议的授权公司范围永远是交集:

有效公司 = assignment.company_ids
         ∩ user.company_ids
         ∩ env.companies

授权模块不得偷偷把公司加入 allowed_company_ids,也不得用 sudo 跳过这个交集。

还必须正视原生组的全局性:res.users.groups_id 是用户级全局 M2M,不带公司维度。若用户同时有“C1 会计”和“C2 销售经理”两个 assignment,而系统把两个角色都投影成原生组,那么会计组和销售经理组会同时存在,并可能在 C1、C2 的所有原生规则允许范围内生效。assignment.company_ids 只是声明字段,并不会自动约束原生组。因而只做组投影的阶段只能支持明确标记为全局的角色;公司/组织 scoped 角色必须等运行时保护覆盖其完整授权面后才能启用。界面应区分“声明范围”和“运行时已强制范围”,不能把前者展示成安全保证。

这里的“完整授权面”不能只看试点主模型。投影前要展开根组及全部 implied groups,盘点它们授予的每个模型 ACL、记录规则、动作、菜单和配置能力;每项结果都必须被相应 adapter/capability 强制,或经过风险评审明确接受为全局授权,否则禁止该技术组用于 scoped role。优先为业务包设计窄技术组,不要直接投影授权面宽泛的官方 Manager 组。

13.6 首批数据范围模板

第一版只做结构化、容易解释的范围:

  1. 本人。
  2. 本部门。
  3. 本部门及下级。
  4. 指定部门。
  5. 指定部门及下级。
  6. 直属下属。
  7. 指定人员。
  8. 本公司。
  9. 指定公司。
  10. 用户全部允许公司。

对一个用户的多个 assignment,必须按完整授权元组求 OR:

AssignmentAllowed_i =
    Assignment_i 有效
    AND 本次 capability/CRUD 属于 Assignment_i
    AND 本次公司属于 Assignment_i.company_ids
    AND 记录匹配 Assignment_i.scope
    AND Assignment_i 的额度/SoD 条件通过

增强授权 = AssignmentAllowed_1 OR AssignmentAllowed_2 OR ...
最终授权 = 原生强制范围 AND 增强授权 AND 业务不变量

不能分别计算“所有岗位 capability 的并集”和“所有岗位 scope 的并集”,否则窄范围高风险能力会借用另一岗位的宽范围。强制合规规则也不能混入内部 OR。例如“冻结记录任何销售人员不可修改”如果放成普通组规则,另一条 TRUE 组规则可能把它放宽;它应成为全局规则或业务方法硬约束。

13.7 原生组投影与来源保留

角色映射原生组时,需要独立来源表或 assignment-to-group 投影记录:

用户 U 拥有 group_sale_user 的来源:
  - 岗位角色 R1
  - 另一个长期角色 R2
  - 原生手工授予

撤销 R1 时,R2 或手工来源仍在,就不能从 groups_id 删除该组。同步算法应:

  • 展开 role 的 group 与 implied groups 做冲突分析。
  • 只管理增强模块拥有的投影来源。
  • 对手工/外部模块组保留边界。
  • 幂等,可重复 reconcile。
  • 变更前生成 add/remove 影响预览。
  • 写入后触发原生权限缓存失效。

但“增加一张来源表”本身仍不够。可执行的所有权协议至少包括:

  1. 配置 managed root group allowlist;增强模块只负责这些明确登记的根组,不能接管任意第三方组。
  2. 启用模块时做基线迁移。已有 managed group 关系保守记为手工/外部基线,除非管理员在差异预览后显式交给模块管理;不得因为无法识别来源就自动删除。
  3. 只为根组记录 assignment 来源,隐含组由 Odoo 展开并在影响预览中解释,不为每个物化 implied relation 伪造来源。
  4. 用户表单、导入和 RPC 对 managed roots 的直接写应被阻止或路由到授权申请;模块内部 reconcile 使用不可由 RPC context 伪造的私有路径。
  5. 组应在“至少一个 assignment 投影来源、保留的手工基线或其他根组继承路径”存在时保留,只有全部来源归零后才撤销。
  6. 对外部模块、原始 SQL 和安装脚本无法经过入口的修改做漂移检测、告警和人工认领;不能宣称来源百分之百完整。

撤销不能只对根组做 Command.unlink()。Odoo 的用户组 write 会补加当前根组的传递 implied groups,但移除根组不会自动完整清除所有孤立的物化叶子关系,见 odoo/addons/base/models/res_users.py:1571-1589。reconcile 要计算变更前后的完整传递闭包,对差集逐项确认:不在手工/外部基线中、不被任何剩余根组蕴含、也没有其他来源时,才显式移除。至少覆盖菱形继承、两个根共享同一隐含组、手工直授叶子组和模块升级改变 implied 图四类测试。

不要仅凭当前 groups_id 反推来源,因为原生表已经把直接组和隐含组物化到同一关系中并丢失路径。

13.8 动态范围应如何接入原生规则

可选路线有三种:

路线 优点 风险 建议阶段
原生组 + 静态规则模板 稳定、升级风险低 动态范围表达有限 MVP 首选
针对少数模型的显式 adapter 可控、可测试 每模型要开发 业务试点
全局扩展 ir.rule._compute_domain() 统一、表达力强 缓存、性能、升级与全局影响大 多项目验证后

若最终扩展 _compute_domain(),下面只能看作组合约束的伪代码,不能直接复制到生产模块:

native_domain = super()._compute_domain(model_name, mode)
enhanced_domain = policy_service.domain_for_current_user(model_name, mode)
return expression.AND([native_domain, enhanced_domain])

绝不能用 enhanced domain 替换 native domain。还要处理:

  • 只对注册适配器的模型生效。
  • 规则缓存键和授权 revision。
  • assignment/部门/岗位变更的即时失效。
  • 精确到期,不依赖低频 cron 才收权。
  • 多 worker、并发事务和回滚。
  • search/count/read_group/导出一致性。
  • 复杂组织树的 SQL 与索引。

在 revision 的生成与传播、事务提交后跨 worker 失效、时间到期机制和双 worker 回归测试都有可执行方案以前,不应全局覆盖 _compute_domain()。仅把一个不会随时间自动变化的 revision 加入缓存键,不能解决“到点失效”;同一事务中已经开始的操作也不会被另一个事务的撤销强行中止。

阶段 1 不提供会扩大原生组、CRUD 或数据范围的临时授权。若真实试点必须提前验证临时能力,只允许把它限制在业务 capability,并在每次服务端 capability 决策中查询精确有效期;它不能投影新增原生组,也不能放宽通用数据范围。完整临时授权仍留到阶段 3。

13.9 业务能力的统一执行方式

建议提供服务:

self.env["odoocc.auth.policy"].check_capability(
    "sale.order.confirm",
    records=self,
    values=None,
)

一个 decision 至少考虑:

  • 当前 uid/su;
  • 生效 assignment 和有效期;
  • 公司、组织、数据范围;
  • capability;
  • 记录 ACL/规则;
  • 当前状态和输入值;
  • SoD 与额度;
  • 紧急授权标志。

然后业务方法仍显式调用:

def action_confirm(self):
    self.check_access("write")
    self.env["odoocc.auth.policy"].check_capability(
        "sale.order.confirm", records=self
    )
    return super().action_confirm()

UI 通过同一个只读 decision API 决定是否显示/禁用按钮,但直接 RPC 会再次经过服务端方法。不要信任 context 中的“按钮已检查”标志。

对普通 write({'state': ...}) 的旁路也要封堵,否则 capability 只保护按钮方法,不保护直接写状态。业务适配包要定义允许的状态迁移入口。

13.10 临时授权、代理和紧急权限

三者不应混成同一种 assignment:

类型 特点 必要控制
临时授权 到期自动结束 起止时间、审批、不可无限续期
请假代理 代表某人的部分待办 业务范围、原提交人/代理人双重审计
紧急提权 高风险短时 break-glass 强理由、二次认证、实时告警、事后复核

状态机建议:

draft -> requested -> approving -> approved -> active
                                            -> expired
                                            -> revoked
requested/approving -> rejected/cancelled

关键要求:

  • 生效前全部审批完成。
  • 申请人不能审批自己的高风险授权。
  • effective_to 在运行时决策中同步检查;cron 负责投影清理,不是唯一防线。
  • 临时 assignment 默认不得投影会扩权的原生组。只有该组及全部 implied groups 的传递授权面都被同步运行时决策保护时,才允许例外;否则临时授权只能授予每次服务端检查的 capability/scope。
  • cron 只能清理过期状态和残留投影,不能承担安全失效;未受运行时保护的原生组即使“稍后会被 cron 删除”也仍是越权窗口。
  • 撤销事务提交后,对新请求和新决策立即失效并清缓存;不能承诺终止另一个已经在执行的数据库事务。
  • 所有延期创建新审批事件,不直接静默改日期。
  • 紧急授权默认最小范围和最短时间。

13.11 职责分离 SoD

优先内置的中国企业常见冲突:

  • 供应商维护 vs 付款审批。
  • 采购申请/制单 vs 采购审批。
  • 会计制单 vs 会计过账。
  • 报销提交 vs 报销审批/付款。
  • 销售折扣申请 vs 超限折扣审批。
  • 用户授权管理员 vs 权限审计员。

冲突检查必须展开 role 映射组及 implied_ids 后判断。因为 ACL 是加法授权,正确做法是在分配/审批时阻止冲突,或要求例外审批;不能创建一个“禁止付款组”指望覆盖已有付款 grant。

SoD 还应区分:

  • 静态冲突:同一人不能同时拥有两个角色。
  • 动态冲突:可以拥有两个角色,但不能对同一业务对象既创建又审批。
  • 额度冲突:金额超过阈值需第二审批人。

13.12 权限解释与模拟

增强模块最值得先做的页面应回答:

用户为什么能 read sale.order #123?

身份:张三,非 sudo
模型 ACL:销售用户组授予 read
全局规则:公司 C1,通过
组规则:本人订单规则,通过;经理全部规则,不适用
增强范围:华东事业部及下级,通过
字段:amount_total 可读;margin 无字段组权限
来源:岗位“青岛区销售”,2026-01-01 生效

拒绝原因也应分层:缺组、无 ACL、全局规则失败、所有组规则失败、增强范围失败、字段受限、状态不允许、SoD 冲突。

“模拟某用户”必须真正使用 with_user() 和相同公司 context 做只读决策,不能因为管理员在看页面就全程 sudo 并泄露样例记录名称。普通用户的错误说明也不应暴露他无权知道的规则和记录细节。

13.13 变更影响预览

授权前展示:

  • 将新增/移除哪些原生组。
  • ACL 四种能力如何变化。
  • 数据范围从什么变成什么。
  • 哪些 capability 新增/丢失。
  • 与哪些 SoD 规则冲突。
  • 影响哪些公司、组织和到期时间。
  • 是否可能放宽全局共享或导出权限。

影响预览必须标记“静态可计算”和“需要样例记录验证”的差别,不能承诺精确列出海量业务记录。

13.14 审计设计

至少记录以下事件:

  • 申请、每级审批、拒绝、撤回。
  • 激活、到期、撤销、续期。
  • 组织调动导致的权限变化。
  • 角色/范围/能力模板变更。
  • SoD 冲突和例外批准。
  • 紧急提权、代理执行。
  • 敏感方法、导入、导出、打印。
  • 权限拒绝和可疑重复尝试。

事件字段建议包括:操作者、原始请求人、目标用户、事件类型、业务原因、审批单、前后值摘要、公司、有效期、请求 ID、来源 IP/设备(在合规必要且告知的范围内)。

注意:

  • 失败事务中的 ORM 审计记录会一同回滚,拒绝事件宜写结构化日志或外部接收端。
  • 不要把密码、token、完整身份证号等敏感值写入审计。
  • 设置符合业务与中国数据合规要求的最小保留期限和访问控制。
  • “不可修改”不能只靠视图 readonly,要撤销 write/unlink ACL,并考虑数据库/外部日志防篡改。

13.15 企业微信、钉钉、飞书与 Excel

组织同步建议:

  • 使用平台稳定 external ID,不用中文名称做主键。
  • 明确哪个系统是员工、组织、岗位、停用状态的权威来源。
  • 先 dry-run 显示新增、移动、停用和冲突,再提交。
  • 删除采用停用/隔离和人工复核,避免一次同步清空权限。
  • 保留外部 ID 映射和上次成功游标,支持幂等重试。
  • 平台组织不一定等于法人公司,必须做映射层。

审批集成建议:外部审批结果只是授权工作流的输入,Odoo 端仍验证申请版本、审批人身份、签名/回调、防重放和当前 SoD 状态。

Excel 适合批量录入和对账,但只应导入成待校验草稿。导入时检查用户、角色、公司、组织、日期、冲突和重复来源,预览通过后再审批生效。Excel 不是未经验证的权限真相。

13.16 面向中国管理员的界面

建议提供三种视角:

  1. 以人为中心:某用户拥有哪些岗位、来源、公司、范围、到期和冲突。
  2. 以角色为中心:某角色授予谁,映射哪些组/能力,最近谁修改。
  3. 以资源为中心:某模型/业务动作有哪些角色能做,数据范围是什么。

权限矩阵明确分栏:

入口可见 | 模型 CRUD | 数据范围 | 字段读写 | 业务能力 | 报表/导出 | 公司 | 有效期

“复制某用户权限”应改成“引用同一角色模板并生成新 assignment”,让来源清晰;不要复制用户最终 groups_id,否则会把隐含组、个人例外和过期授权一并复制。

13.17 性能与可靠性设计

  • 组织树使用 parent_path 和合适索引。
  • 常用 owner、department、company、state 字段建立索引。
  • 避免每用户一组、每用户一规则。
  • 避免长期保存超长 ID 列表 domain。
  • policy decision 记录 query count 和耗时指标,但日志中不泄露敏感记录。
  • 授权变更使用事务和幂等 reconcile。
  • 多 worker 明确 registry/cache signaling。
  • 定期扫描孤儿投影、过期 assignment、未复核高风险角色。
  • 版本升级前跑完整权限矩阵和 SQL 计划基线。

13.18 不建议第一版做的事情

  • 全局替换 Odoo ir.rule
  • 支持普通管理员输入任意 Python/domain。
  • 自研一套与原生 groups/ACL 平行的完整 ORM。
  • 一开始覆盖销售、采购、库存、财务、人事所有模块。
  • 用大量 per-user groups/rules 实现灵活性。
  • 只靠按钮隐藏保护 capability。
  • 只靠 cron 在到期后回收高权限。
  • 把所有组织都建成 res.company
  • 未有真实需求就做复杂外部审批编排平台。

老赵解读

面向中国企业做权限增强,第一版最需要克制。先解决组织、岗位、业务角色、数据范围、临时授权和“为什么有权”这几个高频问题,并把结果投影到原生组与规则。不要一开始就承诺万能审批平台或任意表达式引擎;权限产品一旦表达力超过可解释和可测试能力,灵活性反而会成为风险。

额定值
0 0

目前没有任何评论。

成为第一个发表评论的人。