news 2026/9/15 21:57:40

OpenProject 开发 FAQ 深度解读:数据库变更策略、插件开发入门与 2FA SMS 短信网关

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenProject 开发 FAQ 深度解读:数据库变更策略、插件开发入门与 2FA SMS 短信网关

OpenProject 开发 FAQ 深度解读:数据库变更策略、插件开发入门与 2FA SMS 短信网关

【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject

OpenProject 开发 FAQ 汇集了社区开发者最常问的三个核心问题:数据库层面能否直接集成、如何开发自己的插件、以及两步验证(2FA)的短信网关机制。本文以 docs/development/faq/README.md 为主体骨架,结合 OpenProject 仓库中的生成器源码、two_factor_authentication 模块实现与安装配置文档,逐条给出解答、原理剖析与可落地的操作指引,帮助你快速绕开开发中的常见误区。

一、OpenProject 有数据库 ER 图(实体关系图)吗?

结论:没有,官方也不建议从数据库层面做集成。

FAQ 明确指出,OpenProject 的数据库布局处于持续变化之中,即便是从一个补丁版本升级到下一个补丁版本,也可能改变数据库结构。因此:

  • 官方不提供 ER 图;
  • 官方不建议在数据库层面进行集成(例如用于数据仓库 Data Warehousing 或仪表盘 Dashboard 开发)。

为什么数据库结构如此不稳定?

从仓库结构可以印证这一结论:db/migrate/目录下积累了 269 个迁移文件(db/migrate),OpenProject 通过 Rails 的 ActiveRecord Migration 机制持续演进表结构。迁移文件会随版本不断新增,任何表结构、索引、外键的调整都会直接反映到迁移历史中,因此以"某个版本的 ER 图"为基准做数据库集成,几乎必然在下一次升级时失效。

开发者应该怎么做?

官方推荐的集成路径是通过 OpenProject 的 API 层(位于 lib/api,以API::V3命名空间为主)进行数据交互,而不是直连数据库。API 提供了稳定的、版本化的契约,能够屏蔽底层表结构的持续变化。如果你的需求是数据仓库/BI 集成,可以优先评估官方 API 或导出能力,而不是解析数据库 schema。

二、如何开发自己的 OpenProject 插件?

FAQ 的答复是:插件开发文档目前确实有限,官方主要提供两处资源:

  1. 创建 OpenProject 插件(原文档中的../create-openproject-plugin目录);
  2. 一个原型插件仓库openproject-proto_plugin,其中演示了添加菜单项、挂钩视图、定义项目菜单等基础能力。

2.1 插件本质上是什么?

OpenProject 插件是特殊的 Ruby Gem,通过Gemfile.plugins引入,与普通 Gem 一样获得版本管理和依赖解析能力。生成插件的命令为:

bundle exec rails generate open_project:plugin my_plugin ../plugins/

该命令会在../plugins/openproject-my_plugin目录下生成一个 Rails Engine 形式的插件骨架。命令背后的实现是 lib/generators/open_project/plugin/plugin_generator.rb,从中可以看到生成器的工作方式:

  • 默认插件名openproject-new-plugin,默认输出目录vendor/gems(plugin_generator.rb);
  • 通过full_name统一拼装为openproject-<plugin_name>命名(plugin_generator.rb);
  • 会依次生成插件根目录、lib目录和bin目录(plugin_generator.rb)。

生成后,建议更新插件根目录下的openproject-my_plugin.gemspec

提示:除了生成新插件,也可以直接克隆openproject-proto_plugin示例插件并在此基础上改造。

2.2 如何把插件接入 OpenProject?

在根目录的Gemfile.plugins中声明依赖即可(参考 创建 OpenProject 插件):

group :opf_plugins do gem "openproject-my_plugin", :path => '../plugins/openproject-my_plugin' end

如果文件中已有opf_plugins组,只需把gem行加入该组。随后安装:

bundle install

2.3 生产环境如何部署插件?

FAQ 链接指向两种生产部署方式:

  • Docker 容器:在 Docker 安装方式中挂载插件,详见 Docker 安装文档;
  • DEB/RPM 打包安装:详见 添加插件(DEB/RPM 包)。

DEB/RPM 方式的核心步骤如下(来自 plugins 配置文档):

  1. 创建自定义 Gemfile(例如/etc/openproject/Gemfile.custom):
group :opf_plugins do gem 'openproject-gitlab_integration', git: 'https://github.com/btey/openproject-gitlab-integration.git' end
  1. 通过配置项告知安装包使用该 Gemfile:
openproject config:set CUSTOM_PLUGIN_GEMFILE="/etc/openproject/Gemfile.custom"
  1. 若插件涉及 Angular 前端代码,还需重新编译前端资源(会安装 npm 依赖并显著增加磁盘与内存消耗,官方提示 Angular CLI 生产构建至少需要 4GB 内存):
openproject config:set RECOMPILE_ANGULAR_ASSETS="true"
  1. 重新运行安装器完成重新打包、迁移与资源预编译:
sudo openproject configure

2.4 插件类型与发布流程

创建插件文档中还给出了值得注意的类型划分:

  • 纯后端插件:Rails Engine 形式的 Gem;
  • 前端插件:以 npm 模块形式打包,需在插件根目录包含package.json,自己负责加载图片、样式和 I18n 翻译(翻译经 Rails 从config/locales/js-<locale>.js拾取);
  • 混合插件(Hybrid):同时包含Gem::Specificationpackage.json,既扩展 Rails 又扩展前端,在Gemfile.plugins:opf_plugins组中声明后运行bundle install,前端构建管线(Angular CLI + esbuild)会自动打包其资源。注意:混合插件的 npm 依赖解析目前尚未完善。

发布插件的流程要点包括:代码审查、解决许可与版权问题(可借助rake copyright:authors:show['../Path/to/repository/']rake copyright:update['path_to_plugin']任务)、完善 README 与 gemspec、创建 release 标签(如release/1.0.2)、gem build <name>.gemspecgem push <name>-<version>.gem发布到 RubyGems。

三、OpenProject 的 2FA 短信网关用的是哪家?可以改吗?

结论:OpenProject 使用 MessageBird 作为 SMS 短信网关,FAQ 撰写时该配置不可更换。

不过,从当前仓库的源码来看,2FA 模块实际上已经抽象出了可插拔的 Token Strategy 机制,存在多个实现——FAQ 的结论需要结合这一现状来理解。

3.1 源码证据:MessageBird 策略实现

MessageBird 策略的实现位于 modules/two_factor_authentication/lib/open_project/two_factor_authentication/token_strategy/message_bird.rb,关键信息:

  • 标识符为:message_bird,支持smsvoice两种通道(message_bird.rb);
  • 通过message_bird_client以配置中的apikey创建客户端(message_bird.rb);
  • 发送 SMS 时设置validity: 720(720 秒 = 15 分钟登录令牌有效期减 3 分钟缓冲),并检查totalDeliveryFailedCount判断投递是否失败(message_bird.rb);
  • 语音通道通过voice_message_create发送,支持多达 26 种语言(含zh-cn),并利用<break>标签为 TTS 播报加入停顿(message_bird.rb);
  • 发起方(originator)固定为"OpenProject",代码中留有 TODO 提示其长度不能超过 11 个字符(message_bird.rb);
  • 收件人手机号会去除+与空格后再传给 MessageBird(message_bird.rb)。

3.2 策略选择机制:并非只有一家

token_strategy目录下共有 6 个策略文件:base.rbdeveloper.rbmessage_bird.rbsns.rbtotp.rbwebauthn.rb(见 token_strategy 目录)。其中:

  • Sns策略通过 AWS SDK(aws-sdk-sns)发送短信,要求配置access_key_idsecret_access_keyregion三项(sns.rb);
  • Developer策略是开发环境专用,直接拒绝在生产环境使用(见 developer.rb)。

策略的管理与校验集中在 token_strategy_manager.rb:它遍历已注册的活动策略并逐一执行validate!,同时保证每种设备类型只被一个策略注册。因此,从源码结构看,短信/语音网关已经具备可替换的策略抽象——实际可用的网关取决于当前构建中注册并激活的策略。

3.3 SMS 设备模型

SMS 作为 2FA 设备,其模型位于 modules/two_factor_authentication/app/models/two_factor_authentication/device/sms.rb,约束包括:

  • phone_number必填、对同一用户唯一,且必须匹配\A(?:\+(?:[0-9][- ]?)+[0-9])?\z的国际格式(sms.rb);
  • 默认通道为sms,可切换为voice(sms.rb);
  • 界面展示时会脱敏手机号,仅保留首尾(redacted_identifier,sms.rb)。

3.4 对 FAQ 结论的正确理解

综合来看,FAQ 中"使用 MessageBird、目前无法更换"的表述,反映的是当时默认/内置网关即为 MessageBird 的现状;而从当前代码可以推断,网关实现已被抽象为 Token Strategy 并可扩展。若你需要在生产环境使用其他短信服务商,应优先查阅当前版本的 2FA 配置文档与策略注册机制,确认你所用版本支持哪些策略,而不是假设只有 MessageBird 一条路。

四、总结:三个 FAQ 问题的快速索引

问题官方结论仓库依据
有没有数据库 ER 图?没有,数据库结构随升级持续变化,不建议数据库层集成db/migrate 下 269 个迁移文件
插件开发文档在哪?文档有限,以 创建 OpenProject 插件 与openproject-proto_plugin示例为主lib/generators/open_project/plugin/plugin_generator.rb
2FA 短信网关是哪家?MessageBird,FAQ 撰写时不可更改modules/two_factor_authentication 中的 token_strategy 实现

开发者在做数据库集成、插件扩展或 2FA 改造前,建议先通读上述源码与文档,以当前版本的实际实现为准——OpenProject 的演进速度决定了"文档结论"与"代码现状"之间可能存在的时差,源码才是最终的事实来源。

【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 20:01:17

Unity正式包防调试代码混入:条件编译与日志治理实战

先问一个很现实的问题&#xff1a;你上一次在 Unity 的正式包里发现 Debug.Log 刷屏、调试图标乱入、甚至按住屏幕某个角落就能呼出作弊菜单&#xff0c;是什么时候&#xff1f;如果你心想"啊&#xff0c;还好没人发现"&#xff0c;那这篇就是给你写的。调试代码混进…

作者头像 李华
网站建设 2026/9/14 20:00:35

从零跑通NVIDIA Cosmos:四步生成你的第一个物理世界视频

从零跑通NVIDIA Cosmos&#xff1a;四步生成你的第一个物理世界视频 【免费下载链接】cosmos NVIDIA Cosmos is an open platform of world models, datasets, and tools that enables developers to build Physical AI for robots, autonomous vehicles, smart infrastructure…

作者头像 李华
网站建设 2026/9/15 21:57:12

数据中心微网两阶段鲁棒优化与Matlab实现

1. 数据中心微网规划的核心挑战在数字化转型浪潮下&#xff0c;数据中心作为算力基础设施正面临前所未有的能耗挑战。一个中型数据中心的年耗电量相当于5万户家庭的用电量&#xff0c;而电力成本占其运营支出的40%以上。传统规划方法往往基于确定性假设&#xff0c;但实际运行中…

作者头像 李华
网站建设 2026/9/14 19:59:37

C语言数据类型与位运算实战技巧

1. C语言基础概念解析C语言作为一门接近硬件层面的编程语言&#xff0c;其数据类型系统直接映射计算机的存储结构。理解数据类型是掌握C语言的基础&#xff0c;这就像盖房子前必须了解砖块的种类和特性一样。在32位系统中&#xff0c;int类型通常占4字节&#xff08;32位&#…

作者头像 李华
网站建设 2026/9/15 21:57:18

深入理解AbortController:前端请求取消与超时控制实战

最近在做一个内部后台系统时&#xff0c;遇到一个非常典型的问题&#xff1a;用户在搜索框里输入关键字&#xff0c;每敲一个字母都会发一次请求。防抖加了&#xff0c;可当我快速切换筛选条件时&#xff0c;上一次较慢的请求仍然可能后返回&#xff0c;把新数据直接覆盖掉。为…

作者头像 李华