In this section
Objects
defineObject — declare new record types with their own fields.Extending Objects
defineField — add fields to standard or other apps’ objects.Relations
Bidirectional
MANY_TO_ONE / ONE_TO_MANY connections between objects.Entities at a glance
| Entity | Purpose | Defined with |
|---|---|---|
| Object | A new custom record type (e.g. PostCard, Invoice) with its own fields | defineObject() |
| Field | A column on an object. Standalone fields can extend objects you didn’t create (e.g. add loyaltyTier to Company) | defineField() |
| Relation | A bidirectional link between two objects — both sides declared as fields | defineField() with FieldType.RELATION |
| Index | A database index to speed up a recurring query on one of your objects | defineIndex() |
src/objects/, src/fields/, and src/indexes/. Stable universalIdentifier UUIDs tie everything together across deploys.
Indexes (optional)
Apps can ship indexes alongside their objects to keep recurring queries fast. The most common case is a status or foreign-key column that you read frequently.src/indexes/post-card-status.index.ts
Unique indexes
defineIndex accepts isUnique: true for both single- and multi-column uniqueness. This is the recommended primitive — defineField({ isUnique: true }) is deprecated and will be removed in a future release.
Other constraints
- Partial
WHEREclauses stay under admin control — apps can’t declare them. - Each object is capped at 10 custom indexes (the framework’s own indexes don’t count).
fields array the way Postgres should use it — leftmost column first, like a phone book. Indexes are not free: every write to the table updates them. Add one only when you have a query that needs it.