跳转到主要内容
Twenty 应用的 数据层(data layer) 是你的应用添加到工作区中的数据——它声明的新记录类型、它为现有对象添加的列,以及这些记录之间如何相互关联。
┌──────────────────────────────────────────────────┐
│ Object — a record type, e.g. PostCard            │
│    ├─ Field     (name, type, label)              │
│    ├─ Field                                      │
│    └─ Relation  (link to another object)         │
└──────────────────────────────────────────────────┘

            ├── lives in your app, OR


┌──────────────────────────────────────────────────┐
│ Standard / other apps' objects                   │
│    └─ Field added by your app via defineField    │
└──────────────────────────────────────────────────┘

本节内容

对象

defineObject —— 声明具有自有字段的新记录类型。

扩展对象

defineField —— 向标准对象或其他应用的对象添加字段。

关系

对象之间的双向 MANY_TO_ONE / ONE_TO_MANY 连接。

实体一览

实体目的定义方式
对象具有自有字段的新自定义记录类型(例如 PostCard、Invoice)defineObject()
字段对象上的一列。 独立字段可以扩展你未创建的对象(例如向 Company 添加 loyaltyTierdefineField()
关系两个对象之间的双向链接——双方都声明为字段使用 defineField() 并指定 FieldType.RELATION
索引用于加速在某个对象上经常执行的查询的数据库索引defineIndex()
SDK 会在构建时通过 AST 分析检测这些内容,因此文件组织方式由你决定——约定是使用 src/objects/src/fields/src/indexes/。 稳定的 universalIdentifier UUID 在不同部署之间将一切关联在一起。

索引(可选)

应用可以随对象一同提供索引,以确保经常执行的查询保持快速。 最常见的情况是某个你经常读取的状态列或外键列。
src/indexes/post-card-status.index.ts
import { defineIndex } from 'twenty-sdk/define';

import {
  POST_CARD_UNIVERSAL_IDENTIFIER,
  STATUS_FIELD_UNIVERSAL_IDENTIFIER,
} from '../objects/post-card.object';

export default defineIndex({
  universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff0',
  objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
  fields: [
    {
      universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff1',
      fieldUniversalIdentifier: STATUS_FIELD_UNIVERSAL_IDENTIFIER,
    },
  ],
});

唯一索引

defineIndex 接受 isUnique: true,可同时用于单列和多列表达唯一性约束。 这是推荐的基础方式——defineField({ isUnique: true }) 已被弃用,并将在未来的版本中移除。
defineIndex({
  universalIdentifier: '…',
  objectUniversalIdentifier: PERSON_UNIVERSAL_IDENTIFIER,
  isUnique: true,
  fields: [{ universalIdentifier: '…', fieldUniversalIdentifier: EMAIL_FIELD_UNIVERSAL_IDENTIFIER }],
});

其他约束

  • 部分 WHERE 子句由管理员控制——应用无法声明它们。
  • 每个对象最多只能有 10 个自定义索引(框架自身的索引不计入其中)。
按照 Postgres 使用索引的方式来排列 fields 数组——最左边的列放在最前面,就像电话簿一样。 索引不是免费的:对表的每一次写入都会更新索引。 只有当你确实有查询需要某个索引时才添加它。
在找 Application ConfigRoles & Permissions 吗? 这些描述的是应用本身而不是它添加的数据——相关内容位于 Config 下。 在找 Connections(Linear、GitHub、Slack OAuth)吗? 这些用于逻辑函数中调用,并位于 Logic 下。