N NezamDocumentation

Table schema reference#

Tables define persisted records and configuration rows. Use them for business data, tenant-owned policy, workflow configuration, and lookup data that can vary by company, country, process, or time.

Declaration shape#

bl
@audited
public table PostingPolicy inherits AuditedRecord {
  field company_code: CompanyCode key;
  field document_type: DocumentType key;
  field valid_from: date key;
  field valid_to: date optional;
  field active: bool required default(true);
}

A table can have annotations, an access modifier, a name, optional inheritance, and a body of table members.

PartShape
Annotation@audited
Accesspublic, private, protected, or internal
Declarationtable Name { ... }
Inheritanceinherits BaseRecord or a comma-separated type list
MembersFields, functions, events, computed fields, getter fields, UI, constraints, indexes, and validation

The table grammar also accepts entity in table-declaration position for persisted entity-shaped schemas.

Fields#

Table fields use field name: Type or the shorter name: Type form.

bl
table InvoiceLine {
  field invoice_id: uuid key;
  company_code: CompanyCode required indexed;
  amount: decimal required min(0) max(999999999);
  description: string optional max_length(240);
}

Field modifiers can appear before or after a reference.

bl
field vendor_id: VendorId key -> Vendor.vendor_id cascade indexed;

Field modifiers#

ModifierUse
required, optionalPresence intent
key, primary, unique, indexedIdentity and lookup behavior
default, default(...), default = exprDefault value
pattern expr, pattern = exprPattern constraint
max_length(...), min(...), max(...), range(...)Scalar constraints
searchable, immutableStorage and update semantics
upper, lower, capitalizeCase transforms
associated(a, b)Field association group
modifier(...), modifier = expr, modifier expr, modifierCustom modifier forms

Custom modifiers are syntax extensions. Use them for compiler/runtime metadata, not for hiding configurable ERP policy.

References#

References use arrow syntax and may include cascade.

bl
table CategoryAssignment {
  field vendor_id: VendorId -> Vendor.vendor_id;
  field parent_id: uuid optional -> Category.category_id cascade;
}

For explicit relational behavior, prefer a foreign-key constraint with a referential action.

bl
table VendorCategoryLink {
  field vendor_id: VendorId;
  field parent_id: uuid optional;

  foreign key (vendor_id) references Vendor (vendor_id) on delete restrict;
  foreign key (parent_id) references Category (category_id) on update cascade;
}

Supported referential actions are cascade, restrict, set null / set_null, set default, and no action / no_action.

Computed and getter fields#

Computed fields can be expression-based or use a block with named get entries.

bl
computed gross_amount: decimal = net_amount + tax_amount;

computed labels: Json {
  get en: invoice_id;
  get ar: invoice_id;
}

Getter fields are lightweight computed values.

bl
get display_name => invoice_id;
get lookup_key = company_code + ":" + document_type indexed;

Use computed and getter fields for derived values. Do not use them to replace explicit configuration resolution when the value is policy-owned.

Constraints#

Constraints can be written with or without the constraint keyword.

bl
constraint primary key (company_code, document_type, valid_from);
unique (company_code, document_type, valid_from);
check (valid_to is null || valid_to >= valid_from);
foreign key (company_code) references Company (company_code) on delete restrict;
ConstraintShape
Primary keyprimary key (field_a, field_b)
Uniqueunique (field_a, field_b)
Checkcheck (expression)
Foreign keyforeign key (local_field) references Target (target_field)

Use constraints for structural guarantees. Process policy still belongs in configuration tables plus resolver functions when it can vary.

Indexes#

Indexes have a name, a field list, and optional key-value options.

bl
index posting_policy_lookup on (company_code, document_type) {
  unique: false;
}

index by_status on status, company_code;

The field list can be parenthesized or written as a comma-separated identifier list.

Events#

Tables can declare named event collections for runtime fixtures and generated integrations.

bl
events PostingPolicyEvents {
  PostingPolicyActivated activated(policy_id: uuid);
  PostingPolicyExpired expired(policy_id: uuid, expired_on: date);
}

Use table events to describe event shapes. Use lifecycle subscriptions to attach handlers to insert, update, or delete operations.

Table UI#

The ui: table member accepts either an expression or a source UI layout block.

For a complete reference to groups, rows, row operations, and field operations, see Source UI layouts.

bl
table PostingPolicy {
  field company_code: CompanyCode key;
  field document_type: DocumentType key;
  field valid_from: date key;
  field valid_to: date optional;
  field active: bool required default(true);

  ui: {
    group "Posting policy" {
      columns: 2;

      row {
        field company_code;
        field document_type;
      }

      row {
        field valid_from;
        field valid_to;
      }

      readonly field active;
    }
  }
}

Source UI groups can contain group properties, rows, row operations, and field operations.

Validation#

Table validation sections contain named expressions or reusable validation rule references.

bl
validation {
  valid_range: valid_to is null || valid_to >= valid_from;
  active_policy: rule ActivePolicy(company_code, document_type);
}

Keep validation deterministic. Missing required configuration should raise a declared message-backed failure in the resolver or command layer, not silently pass validation with a default.

Source: packages/business/language/table-schema-reference.md