先说结论
Odoo 项目的 privacy_visibility,绝不是一个“公开 / 私密”的简单开关。
从 /home/ubuntu/odoo-temp/addons/project/tests/test_access_rights.py 和 models/project_project.py 可以看出,官方实际上在维护一套分层访问模型:
followersinvited_usersemployeesportal
而且它影响的也不只是“能不能看到项目”,还包括:
- 能不能读任务
- 能不能创建任务
- 能不能改任务
- 订阅项目后权限是否会传播到新任务
- 门户用户是否能进入、能看到多少、能不能编辑
所以理解项目可见性时,千万别只盯着前台有没有入口,而要看:
项目访问、任务访问、订阅关系和门户能力是一起设计的。
第一层:为什么“看得见项目”不等于“能看任务”
很多系统把项目访问做成单层:
- 能进项目 = 能看所有任务
Odoo 没这么粗糙。
测试明确说明了不同 visibility 下,项目与任务的读写不一定完全同步。
特别是在:
followersportal
这类模式下,谁是 follower、谁是内部用户、谁是门户用户,会直接影响任务可见性和操作能力。
这背后的思想很重要:
- 项目是容器
- 任务是执行对象
- 容器可见,不代表每个对象都可随意操作
第二层:followers 模式为什么最容易被误用
followers 模式的核心不是“只有少数人能看”,而是:
- 被邀请 / 被订阅的人才有读权限基础
- 但这不天然等于他们就能改项目本身
测试里反复验证:
- 订阅项目后,不代表就能写项目
- 也不代表能删项目
- 对已有任务的权限传播也有边界
这个模式非常适合:
- 内部小范围协作
- 需要精确控制谁被拉进来
但很不适合拿来偷懒替代角色设计。
如果你把 followers 模式当“万能私有模式”,结果往往是:
- 大家都在订阅
- 权限解释越来越乱
- 新任务谁能看、旧任务谁还能看变得难以预测
第三层:为什么订阅项目不会自动给旧任务补权限
测试里有一个非常关键的点:
- 订阅项目,不会把该权限倒灌到已有任务上
- 但新建任务会继承项目层面的关注链或默认可见关系
这个设计特别聪明。
如果一订阅项目就把历史任务全部开放,风险很高:
- 旧数据可能不该让新参与者看到
- 历史沟通上下文可能过宽暴露
Odoo 选择的是更克制的方式:
- 历史任务不轻易追溯性开放
- 新任务按当前协作关系传播
这既支持协作扩容,也控制了历史权限爆炸。
第四层:portal 模式为什么也不是“客户全能看”
portal 相关测试非常能打破误解。
很多人以为:
- 项目设成 portal
- 客户就能看这个项目所有任务
实际不是。
模型帮助文案和测试都说明:
- 门户用户通常仍需要是被邀请 / 被关注的一方
- 不同 portal access level 还可能决定只读还是有限编辑
- 内部用户与门户用户本来就不是同一条权限线
所以 portal 更多是:
- 给外部协作者开受控入口
而不是:
- 把项目整个扔给客户看
第五层:employees 模式为什么最直白,但也最宽
employees 模式相对最好理解:
- 所有内部用户可访问
- 门户用户不因此获得访问权
这种模式通常适合:
- 公司内部协作项目
- 不需要按 follower 精细裁剪访问
- 更重视内部透明,而不是最小可见原则
但它的代价也很明显:
- 可见范围更宽
- 更依赖组织本身的内部边界清晰
第六层:排错时,先分清“权限对象”再看模式
项目访问出问题时,最容易犯的错是只看 visibility 字段,不看用户类型和订阅关系。
更有效的顺序是:
- 先确认对象是项目还是任务
- 再确认当前用户是内部用户、门户用户还是公共用户
- 再看 visibility 模式
- 再看是否为 follower / 是否被订阅
- 最后看是读问题、写问题还是创建问题
因为这几个问题的答案并不总是同步。
实施建议:不要把 visibility 当万能权限开关
更稳的做法是:
- 用 visibility 决定大框架
- 用 follower / collaborator / portal invitation 决定细粒度范围
- 用角色和组权限决定谁能改什么
也就是说:
- visibility 决定“默认大门怎么开”
- follower 和角色决定“进门后能做什么”
最后一句
Odoo 项目可见性设计得复杂,不是因为想把权限搞难,而是因为现实协作本来就不是单层的。
你真正要理解的是四个维度:
- 项目能不能看
- 任务能不能看
- 能不能改
- 权限会不会因订阅传播到新对象
把这四个问题分开,followers、portal、employees 的差别才会真正清楚。
DISCUSSION
评论区