Skip to content
DocsSDKdefineEntityType

defineEntityType

Define entity type schemas for your domain

The defineEntityType function creates and validates entity type schema definitions. Each entity type is defined in its own file under the entity-types/ directory.

import { defineEntityType } from 'struere'

export default defineEntityType({
  name: "Teacher",
  slug: "teacher",
  schema: {
    type: "object",
    properties: {
      name: { type: "string", description: "Full name" },
      email: { type: "string", format: "email", description: "Email address" },
      subjects: {
        type: "array",
        items: { type: "string" },
        description: "Subjects they can teach",
      },
      hourlyRate: { type: "number", description: "Rate per hour in cents" },
    },
    required: ["name", "email"],
  },
  searchFields: ["name", "email"],
  displayConfig: {
    titleField: "name",
    subtitleField: "email",
  },
})

EntityTypeConfig

Field Type Required Description
name string Yes Display name for the entity type
slug string Yes URL-safe identifier, used in API queries and tool calls
schema JSONSchema Yes JSON Schema definition for entity data
searchFields string[] No Fields indexed for text search (defaults to [])
displayConfig object No Controls how entities are displayed in the dashboard
boundToRole string No Binds this entity type to a role name for automatic user linking
userIdField string No Field that stores the Clerk user ID (defaults to "userId" when boundToRole is set)

Validation

defineEntityType throws errors if:

  • name, slug, or schema is missing
  • schema.type is not "object"
  • Any nested object property is missing properties
  • boundToRole is an empty string
  • userIdField is set without boundToRole

JSON Schema

Entity schemas use the JSON Schema format with the following type system:

interface JSONSchema {
  type: 'object'
  properties: Record<string, JSONSchemaProperty>
  required?: string[]
}

interface JSONSchemaProperty {
  type: 'string' | 'number' | 'boolean' | 'array' | 'object'
  description?: string
  format?: string
  enum?: string[]
  items?: JSONSchemaProperty
  properties?: Record<string, JSONSchemaProperty>
  required?: string[]
}

The root schema must always be type: "object". Nested objects must declare their properties.

Supported Property Types

String fields:

{
  name: { type: "string", description: "Full name" },
  email: { type: "string", format: "email" },
  status: {
    type: "string",
    enum: ["active", "inactive", "suspended"],
  },
}

Number fields:

{
  hourlyRate: { type: "number", description: "Rate in cents" },
  age: { type: "number" },
}

Boolean fields:

{
  isActive: { type: "boolean", description: "Whether the record is active" },
}

Array fields:

{
  subjects: {
    type: "array",
    items: { type: "string" },
    description: "List of subjects",
  },
  tags: {
    type: "array",
    items: { type: "string", enum: ["math", "science", "english"] },
  },
}

Nested object fields:

{
  address: {
    type: "object",
    properties: {
      street: { type: "string" },
      city: { type: "string" },
      postalCode: { type: "string" },
    },
    required: ["street", "city"],
  },
}

Display Configuration

The displayConfig field controls how entities appear in the dashboard:

displayConfig: {
  titleField: "name",
  subtitleField: "email",
  descriptionField: "notes",
}
Field Description
titleField Primary display field (shown as heading)
subtitleField Secondary display field (shown below title)
descriptionField Extended description field

Search Fields

The searchFields array specifies which fields are indexed for text search via entity.query:

searchFields: ["name", "email", "phone"]

When an agent uses entity.query with a search term, only these fields are matched.

Role Binding

The boundToRole and userIdField fields create an automatic link between an entity type and a user role. When a user with the bound role logs in, they are associated with the matching entity:

export default defineEntityType({
  name: "Teacher",
  slug: "teacher",
  schema: {
    type: "object",
    properties: {
      name: { type: "string" },
      email: { type: "string", format: "email" },
      userId: { type: "string", description: "Clerk user ID" },
    },
    required: ["name", "email"],
  },
  boundToRole: "teacher",
  userIdField: "userId",
})

When boundToRole is set and userIdField is omitted, it defaults to "userId".

Full Examples

Student Entity Type

import { defineEntityType } from 'struere'

export default defineEntityType({
  name: "Student",
  slug: "student",
  schema: {
    type: "object",
    properties: {
      name: { type: "string" },
      grade: { type: "string" },
      subjects: {
        type: "array",
        items: { type: "string" },
      },
      notes: { type: "string" },
      guardianId: { type: "string" },
      preferredTeacherId: { type: "string" },
    },
    required: ["name"],
  },
  searchFields: ["name"],
  displayConfig: {
    titleField: "name",
    subtitleField: "grade",
  },
})

Session Entity Type

import { defineEntityType } from 'struere'

export default defineEntityType({
  name: "Session",
  slug: "session",
  schema: {
    type: "object",
    properties: {
      teacherId: { type: "string" },
      studentId: { type: "string" },
      guardianId: { type: "string" },
      startTime: { type: "number", description: "Unix timestamp" },
      duration: { type: "number", description: "Duration in minutes" },
      subject: { type: "string" },
      status: {
        type: "string",
        enum: [
          "pending_payment",
          "scheduled",
          "in_progress",
          "completed",
          "cancelled",
          "no_show",
        ],
      },
      notes: { type: "string" },
      teacherReport: { type: "string" },
    },
    required: ["teacherId", "studentId", "guardianId", "startTime", "duration"],
  },
  searchFields: ["subject"],
  displayConfig: {
    titleField: "subject",
    subtitleField: "status",
  },
})

Entitlement Entity Type (Credits System)

import { defineEntityType } from 'struere'

export default defineEntityType({
  name: "Entitlement",
  slug: "entitlement",
  schema: {
    type: "object",
    properties: {
      guardianId: { type: "string" },
      studentId: { type: "string" },
      totalCredits: { type: "number" },
      remainingCredits: { type: "number" },
      expiresAt: { type: "number", description: "Unix timestamp" },
    },
    required: ["guardianId", "studentId", "totalCredits", "remainingCredits"],
  },
  displayConfig: {
    titleField: "remainingCredits",
    subtitleField: "totalCredits",
  },
})