packages/twenty-codex-plugin/references/develop-app/data-model.md
Use this reference for Twenty app objects, fields, relations, roles, and permissions.
Objects and fields define the records users will create, view, search, and automate. Model the user's workflow first, then add the smallest set of fields that makes the workflow usable.
When adding or modifying data model entities:
yarn twenty dev:add.When the user asks for a new object and does not explicitly restrict the request to schema only, make the object usable in the app by pairing data model work with the minimum layout/navigation surfaces:
src/objects/<name>.tssrc/views/all-<plural>.tssrc/navigation-menu-items/<name>.tssrc/page-layouts/<name>-record-page-layout.tssrc/views/<name>-record-page-fields.tsUse layout.md for view, navigation, and page layout details.
Objects support icon, but object color is not defined on defineObject(). Put color on the object navigation item:
import {
defineNavigationMenuItem,
NavigationMenuItemType,
} from 'twenty-sdk/define';
export default defineNavigationMenuItem({
universalIdentifier: '<uuid>',
name: '<name>',
icon: '<IconName>',
color: '<color>',
position: 0,
type: NavigationMenuItemType.OBJECT,
targetObjectUniversalIdentifier: '<object-uuid>',
});
import { defineObject, FieldType } from 'twenty-sdk/define';
export const OBJECT_UNIVERSAL_IDENTIFIER = '<uuid>';
export const NAME_FIELD_UNIVERSAL_IDENTIFIER = '<uuid>';
export default defineObject({
universalIdentifier: OBJECT_UNIVERSAL_IDENTIFIER,
nameSingular: '<name>',
namePlural: '<names>',
labelSingular: '<Name>',
labelPlural: '<Names>',
icon: '<IconName>',
labelIdentifierFieldMetadataUniversalIdentifier:
NAME_FIELD_UNIVERSAL_IDENTIFIER,
fields: [
{
universalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER,
type: FieldType.TEXT,
name: 'name',
label: 'Name',
icon: 'IconAbc',
},
],
});
Select and multi-select option value strings must be uppercase snake case:
{
type: FieldType.SELECT,
name: 'status',
label: 'Status',
defaultValue: "'PLANNED'",
options: [
{ position: 0, label: 'Planned', value: 'PLANNED', color: 'sky' },
{ position: 1, label: 'In build', value: 'IN_BUILD', color: 'orange' },
],
}
For select fields, default values must be quoted string expressions like "'PLANNED'", not plain strings like 'planned'.
Roles should match operational responsibility, not implementation convenience.
When adding permissions:
After data model changes, run the app and verify the objects, fields, and roles appear where the user will manage or use them.