跳到主要内容

理解数据驱动的元模型

大多数 EA 工具将其对象模型硬编码在应用程序源代码中。Canopy 采取了不同的方式:所有结构性概念——卡片类型、字段、子类型、关系、利益相关者角色和计算字段——均以数据形式存储在数据库中,而非代码。本页解释这一决策背后的原因及其在实践中的意义。

元模型是什么

元模型是您的 EA 模型的架构定义。它定义了:

  • 卡片类型——您追踪的实体类别(Application、BusinessCapability、Initiative 等)
  • 字段——这些实体可以持有的属性(生命周期状态、成本、负责人、技术栈等)
  • 子类型——共享相同字段集的某一类型的细粒度变体(例如 Application → Microservice、SaaS、AI Agent)
  • 关系类型——类型之间允许的边(Application「运行在」ITComponent 上,Initiative「实现」BusinessCapability 等)
  • 利益相关者角色——用户可在特定卡片上持有的角色(技术负责人、业务负责人、数据管理员等)
  • 计算字段——在保存时从其他数据派生字段值的公式

所有这些都是 card_typesrelation_types 及相关 JSONB 列中的数据行。修改它们均无需更改代码或重启应用程序。

为何选择数据而非代码?

无需分叉即可定制

不同组织的 EA 元模型差异极大。有些团队追踪「供应商」、「许可证」和「SLA」;另一些则追踪「数据域」、「ESG 能力」和「价值流」。如果元模型是代码,每次定制都需要分叉产品或构建插件系统——两者的维护成本都很高。

有了数据驱动的元模型,管理员可以在几分钟内通过界面或 API 添加新字段、重命名卡片类型或定义自定义关系类型。前端会自动适应:库存表格增加新列,卡片详情页显示新节,报告可以按新字段筛选。无需重新部署。

无需为每位客户执行迁移即可演进架构

当 Canopy 推出新的内置卡片类型或字段时,它通过 seed.py 实现——这是一个启动例程,检查内置行是否存在,仅在缺失时才创建。现有定制内容从不受影响。这意味着:

  • 升级 Canopy 不会覆盖您的自定义字段
  • 内置类型仍可编辑(您可以更改「Application」的图标、颜色或标签,无需分叉)
  • 如果内置默认值偏离了原始值,有条件的 Alembic 迁移仅会修正未被修改的行

单一代码库支持多租户

由于元模型是数据,单次 Canopy 部署可以为拥有完全不同对象模型的团队提供服务——或者同一部署可以完全重新配置,而无需触碰代码库。

fields_schema 结构

每种卡片类型将其字段定义存储为的 JSONB 数组:

[
{
"section": "Technology",
"columns": 2,
"fields": [
{
"key": "techStack",
"label": "Technology Stack",
"type": "multiple_select",
"options": [{"key": "java", "label": "Java"}, {"key": "python", "label": "Python"}],
"weight": 2
}
]
}
]

每个字段上的 weight 决定数据质量评分——卡片根据已填写的加权字段数量被评分为 0–100%。这将元模型转变为质量管控机制:通过为最重要的字段分配更高权重来定义「良好」数据的标准。

无法通过元模型更改的内容

元模型控制的是形状,而非行为。以下内容仍保留在代码中:

  • 计算引擎——用于评估公式的安全沙盒是一个 Python 库(simpleeval)。公式本身是数据,但评估器是代码。
  • 权限系统——有效权限键的集合是 backend/app/core/permissions.py 中的允许列表。添加新的权限键(而不仅仅是授予它)需要更改代码。
  • 数据库架构——添加新的顶级表(例如 PPM 或 GRC 等新模块)需要 Alembic 迁移。卡片属性架构可以在不迁移的情况下扩展,因为属性是 JSONB。

另请参阅