Files
upstream-twenty/packages/twenty-docs/l/ja/developers/extend/apps/data/system-fields.mdx
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00

202 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: システムメタデータのターゲット指定
description: Twenty がすべてのオブジェクトに自動的にプロビジョニングするメタデータの決定論的なユニバーサル識別子を解決し、アプリがハードコーディングせずに参照できるようにします。
icon: gears
---
Twenty のすべてのオブジェクトには、フィールドのセットや、そのカラムを持つメインのリストビューなど、あなた自身が宣言する必要のない **システムメタデータ** が付属しています。 オブジェクトがプロビジョニングされるときに、そのすべてをサーバーが作成し、そのセットは Twenty の拡張に合わせて増えていきます。
あなたがそれを宣言しないため、インポートできる `universalIdentifier` 定数は存在しません。 その代わりに、サーバーはそれぞれの識別子を決定論的に**導出**し、`twenty-sdk` が同じ導出処理を公開することで、マニフェストがサーバーで使用される正確な値を解決できるようにします。
## システムフィールド
すべてのオブジェクトに存在し、いずれも [`defineField()`](/l/ja/developers/extend/apps/data/extending-objects) で宣言しないスカラー フィールドは次のとおりです。
`id`, `createdAt`, `updatedAt`, `deletedAt`, `createdBy`, `updatedBy`, `position`, `searchVector`
では、[view](/l/ja/developers/extend/apps/layout/views) で `createdAt` をカラムとしてどのように参照すればよいのでしょうか。
### 問題
Twenty 2.19 以降、システムフィールドのユニバーサル識別子は、アプリケーションのユニバーサル識別子、オブジェクトのユニバーサル識別子、およびフィールド名という 3 つの入力からサーバーによって **決定的に導出** されます。 id を独自に作成してハードコードしても機能しません。サーバー上のどの値とも一致せず、同期時にそのぶら下がった参照は拒否されます。
```
Dev sync failed: viewField: INVALID_VIEW_DATA: Field metadata not found
```
### 解決策
<Note>
`getFieldUniversalIdentifier` は `twenty-sdk` 2.21 以降で利用可能です。
</Note>
`getFieldUniversalIdentifier` を使用して、サーバーが使用するものとまったく同じ値を解決します。 この関数は 3 つの入力を受け取り、フィールドのユニバーサル識別子を返します。
```ts
import { getFieldUniversalIdentifier } from 'twenty-sdk/define';
const createdAtFieldId = getFieldUniversalIdentifier({
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
name: 'createdAt',
});
```
* `applicationUniversalIdentifier` はあなたのアプリの識別子であり、[`defineApplication()`](/l/ja/developers/extend/apps/config/application) に渡すものです。
* `objectUniversalIdentifier` は、そのフィールドが属するオブジェクトの識別子です。
* `name` はシステムフィールド名であり、上に挙げた値のいずれかです。
### 例: ビュー内の createdAt カラム
典型的なケースは、カスタムオブジェクトの 1 つのビューに `createdAt` カラムを追加することです。 フィールド id を解決し、他の `fieldMetadataUniversalIdentifier` と同様にそれを参照します。
```ts src/views/example-view.ts
import {
defineView,
getFieldUniversalIdentifier,
} from 'twenty-sdk/define';
const APPLICATION_UNIVERSAL_IDENTIFIER =
'0b04e15c-27b2-4741-9046-b32e07469072';
const MY_OBJECT_UNIVERSAL_IDENTIFIER =
'c782b61c-70fd-4c88-9cd6-4e61ab8d7591';
export default defineView({
universalIdentifier: '70f10d44-144a-4da8-8c6f-3ec2422138c0',
name: 'All records',
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
icon: 'IconList',
position: 0,
fields: [
{
universalIdentifier: '75a90bc4-d901-4df4-85e0-af29db5e0104',
fieldMetadataUniversalIdentifier: getFieldUniversalIdentifier({
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
name: 'createdAt',
}),
position: 0,
isVisible: true,
size: 200,
},
],
});
```
同じように解決された id は、`fieldMetadataUniversalIdentifier` が必要とされるあらゆる場所、すなわちビューのフィールド、フィルター、ソート、グループ、ページレイアウトウィジェットでそのまま使用できます。
<Note>
id は解決して、ハードコードしないでください。 サーバーはその値をアプリケーション id、オブジェクト id、フィールド名から導出するため、`getFieldUniversalIdentifier` を呼び出すことで、それらの入力が変更された場合でも参照を正しい状態に保ち、導出方法が将来変わった場合のずれも防ぐことができます。
</Note>
### システムリレーションフィールド
<Note>
`getSystemRelationFieldUniversalIdentifier` は `twenty-sdk`
2.23 以降で利用可能であり、バージョン 2.23 以降の Twenty サーバーが必要です。
</Note>
上記のスカラー型システムフィールドに加えて、サーバーはすべてのオブジェクトに対して 4 つの**システムリレーションフィールド**を提供します。`timelineActivities`、`attachments`、`noteTargets`、`taskTargets` であり、それぞれが対応する標準リレーションオブジェクトを参照します。
これらのフィールドは `getFieldUniversalIdentifier` では解決されません。フィールドを保持しているオブジェクトと、そのフィールドが参照するオブジェクトから、**名前に依存せず**識別子が導出されます。 この方法により、オブジェクトの名称を変更しても、そのリレーションフィールドの識別子は決して変わりません。
それらを解決するには、`getSystemRelationFieldUniversalIdentifier` を使用します。
```ts
import {
getSystemRelationFieldUniversalIdentifier,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-sdk/define';
// rocket.attachments — the relation field hosted on your custom object
const rocketAttachmentsFieldId = getSystemRelationFieldUniversalIdentifier({
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
objectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
relationTargetObjectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.attachment.universalIdentifier,
});
```
* `objectUniversalIdentifier` は、そのフィールドを **保持している** オブジェクトです。
* `relationTargetObjectUniversalIdentifier` は、そのフィールドが **参照している** オブジェクトです。
方向は引数の順序によってエンコードされます。 逆方向(例: `attachment.targetRocket`。これは、標準リレーションオブジェクト上でサーバーが作成する morph フィールド)を解決するには、2 つを入れ替えます。
```ts
// attachment.targetRocket — the reverse morph field on Attachment
const attachmentTargetRocketFieldId =
getSystemRelationFieldUniversalIdentifier({
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
objectUniversalIdentifier:
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.attachment.universalIdentifier,
relationTargetObjectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
});
```
スカラーのシステムフィールドと同様に、解決された ID は `fieldMetadataUniversalIdentifier` が想定されるあらゆる場所で使用できます。
## システムビュー
<Note>
`getSystemViewUniversalIdentifier` と `getSystemViewFieldUniversalIdentifier` は `twenty-sdk` 2.26 以降で利用可能であり、バージョン 2.26 以降の Twenty サーバーが必要です。
</Note>
サーバーは、すべてのオブジェクトに対して **システムビュー** もプロビジョニングします。つまり、表示可能なフィールドごとに 1 つのカラムを持つメインのリストビュー(`All {objectLabelPlural}`、キーは `ViewKey.INDEX`(`SYSTEM_VIEW_KEYS.INDEX` から導出))です。 システムリレーションフィールドと同様に、それらの識別子は **名前に依存しない** 形で導出されるため、オブジェクトやフィールドの名前を変更しても識別子は変わりません。
ビューを解決するには、`getSystemViewUniversalIdentifier` を使用します。
```ts
import {
getSystemViewUniversalIdentifier,
SYSTEM_VIEW_KEYS,
} from 'twenty-sdk/define';
const rocketIndexViewId = getSystemViewUniversalIdentifier({
objectMetadataApplicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
objectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
viewKey: SYSTEM_VIEW_KEYS.INDEX,
});
```
* `objectMetadataApplicationUniversalIdentifier` は **オブジェクト** を所有しているアプリケーションであり、ビューが名前空間分割されている単位です。
* `objectUniversalIdentifier` は、そのビューがリストするオブジェクトです。
* `viewKey` はシステムビューを識別するための判別子です。メインのリストビューには `SYSTEM_VIEW_KEYS.INDEX`、レコードページのフィールドウィジェットのビューには `SYSTEM_VIEW_KEYS.FIELDS_WIDGET` を使用します。 これは導出のキーとなる値であり、ビューの行に保存されるのは `INDEX` のみです。
解決された ID は、[`NavigationMenuItemType.VIEW`](/l/ja/developers/extend/apps/layout/navigation-menu-items) のサイドバーエントリなど、`viewUniversalIdentifier` が必要とされるあらゆる場所で使用できます。 オブジェクトのメインリストを単に開くだけであれば、導出が不要な `NavigationMenuItemType.OBJECT` と `targetObjectUniversalIdentifier` を優先して使用してください。
`getSystemViewFieldUniversalIdentifier` は、ビューとそのビューが表示するフィールドから、システムビュー上の 1 つの**カラム**を解決します。
```ts
import { getSystemViewFieldUniversalIdentifier } from 'twenty-sdk/define';
const rocketNameColumnId = getSystemViewFieldUniversalIdentifier({
fieldMetadataApplicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
viewUniversalIdentifier: rocketIndexViewId,
fieldMetadataUniversalIdentifier: ROCKET_NAME_FIELD_UNIVERSAL_IDENTIFIER,
});
```
最初の引数に注目してください。カラムは、そのビューではなく、**表示しているフィールド** を所有するアプリケーションで名前空間分割されます。 あなたのアプリが標準オブジェクトに追加したフィールドは、Twenty が所有するビュー上で、そのアプリケーションの名前空間の下にカラムが導出されます。
<Warning>
システムビューとそのカラムは **サーバー所有** です。これらの識別子は、宣言ではなく参照のためにのみ解決してください。 [`defineView()`](/l/ja/developers/extend/apps/layout/views) の `key` は非推奨で無視されます。そのため、マニフェストのビューが `INDEX` キーを主張することはできません。また、サーバーはあなたが追加するすべてのフィールドに対してすでにカラムをプロビジョニングしているため、同じフィールドについてシステムビュー上で独自の `defineViewField()` を宣言すると競合が発生します。
</Warning>
## 標準の Twenty オブジェクト
**標準** の Twenty オブジェクト(Person、Company、Opportunity など)の場合、何も導出する必要はありません。フィールドおよびビューの識別子は、あらかじめ計算された定数として用意されており、直接インポートできます。
```ts
import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk/define';
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.createdAt.universalIdentifier
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.fields.updatedAt.universalIdentifier
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.views.allPeople.universalIdentifier
```
[`defineObject()`](/l/ja/developers/extend/apps/data/objects) で **あなたのアプリ** が定義するオブジェクトのように、そのような定数が存在しない場合には、ここまでで紹介したヘルパーを使用してください。
<Note>
`name` はシステムフィールドではなく、**デフォルト** フィールドです。 このフィールドは独自のハードコードされたユニバーサル識別子を持ち、`getFieldUniversalIdentifier` で解決されることはありません。 あなたが定義したオブジェクトでは、`name` フィールドは `defineObject()` で与えた識別子で参照してください。
</Note>