nenu-lang / entities
Stable

Entities

  • An entity is a nominal type whose values can become durable records.
  • Decorators describe storage behavior; validators reject invalid field values.
  • Construction creates an in-memory entity value, while save makes it durable.

Entity Definition Syntax

entities/Room.entity.nenu
1entity Room {2  name: string @unique3  active: bool4}

An entity file defines one PascalCase entity. Field names are lowercase identifiers followed by a type. The file may also contain shared value types, enums, defaults, and functions, but it cannot contain top-level runnable steps or a second entity.

The Room Expense Model

code
1entity Room {2  name: string @unique3  active: bool4}

The application owns Room, Expense, ExpenseStatus, and Settlement. A draft is still being edited; an open expense is ready for normal room accounting; submitted, approved, and rejected represent review; settled means no further balance remains. The model references the existing platform User type for people and never declares that type itself.

Field Decorators

DecoratorPurposeExample
@uniqueRequire a unique stored value and enable exact named-field lookup.name: string @unique
@indexIndex a value used by filters, joins, or relationship lookups.room_id: string @index
@default(...)Provide a storage-level field default.reviewed_at: time @default(now)
@accessAttach entity-level access behavior.Placed before entity.
code
1@access2entity PrivateReceipt {3  expense_id: string @unique4  receipt_file: file5}

Field Transforms

code
1type ExpenseInput {2  title: string | trim3  category: string | trim | lowercase4  reference: string | uppercase5}
TransformAllowed fieldEffect
| trimstring or string?Remove surrounding whitespace.
| lowercasestring or string?Normalize letters to lowercase.
| uppercasestring or string?Normalize letters to uppercase.

Transforms follow a field type in structural type definitions and metadata-backed contracts, using one pipe per rule. Entity fields accept decorators and validators, not transform pipes. A transform on a number, boolean, time, collection, media value, or unsupported named type is rejected.

Field Validators

code
1type ExpenseInput {2  title: string | trim ! not_empty ! max_length(120)3  reference: string | lowercase ! slug4  contact_email: string? | trim | lowercase ! email5  amount: number ! positive ! max(1000000)6}
FamilyValidatorsAllowed field
String formatemail, phone, url, uuid, slug, no_whitespace, alphanumeric, lowercase, uppercasestring or string?
String contentmin_length(n), max_length(n), length(n), regex("pattern"), has("text")string or string?
Presencenot_emptyStrings, arrays, maps, named values, and structural shapes, including optional wrappers.
Number rangemin(n), max(n), positive, negativenumber or number?

Each validator begins with !; several validators may follow one field. Length arguments are positive integers, numeric bounds must be finite safe numbers, and regex and has take string literals. Unknown rules and rules used on an incompatible field type are compile-time errors.

Managed Fields

Invalid field declarationReason
id: stringIdentity is platform-managed.
createdAt: timeCreation time is platform-managed.
updatedAt: timeUpdate time is platform-managed.
Declaring the platform User typeUser is platform-owned, not an application entity.

Constructing Is Not Saving

code
1Expense expense = Expense {2  room_id: room.id3  payer4  title: request.title5  amount: request.amount6  note: ?7  receipt: ?8  status: ExpenseStatus.Draft9}1011expense.title = expense.title.trim()12save(expense)

Expense { ... } constructs an in-memory value. Assignment changes fields on that value. save(expense) is the explicit durable write. Expense(request.id) is not construction; inside need, it is a fetch form.

Common Mistakes

WrongCorrect
Two entities in one fileOne entity definition per entity file.
Top-level save beside an entity definitionPut executable steps in a runnable file.
new Expense { ... }Expense { ... }
Assume construction persistsCall save in the owning backend workflow.
Declare UserReference the platform-provided User type.

Continue Learning