N NezamDocumentation

Data modeling#

Business Language has several data declaration forms. Use them according to ownership and runtime behavior.

Fields#

Top-level fields define reusable scalar types and constraints.

bl
public field VendorId: string {
  max_length: 40;
  key: true;
}

field Amount: decimal {
  validation {
    non_negative: value >= 0;
  }
}

Field blocks contain properties and validation blocks. Field validation entries are named expressions or calls to reusable rules.

Field block property names may contain multiple identifiers.

bl
field VendorName: string {
  display label: "Vendor name";
  search weight: 10;

  validation {
    present: value is not null;
    valid_name: rule RequiredText(value);
  }
}

Tables#

Tables define persisted records. The grammar accepts table and entity in table-declaration position, optional inheritance, fields, functions, events, computed fields, getter fields, UI declarations, constraints, indexes, and validations.

For the full table member syntax, see Table schema reference.

bl
public table Invoice inherits AuditedRecord {
  field invoice_id: uuid key origin;
  field vendor_id: VendorId key -> Vendor.vendor_id cascade;
  field amount: decimal required min(0) indexed;
  field status: string default("open");

  computed total: decimal = amount;
  get display_name => invoice_id;

  constraint primary key (invoice_id);
  unique (vendor_id, invoice_id);
  check (amount >= 0);

  index by_vendor on (vendor_id) {
    unique: false;
  }

  validation {
    positive_amount: amount >= 0;
  }
}

Field modifiers#

Common table and struct field modifiers include:

ModifierMeaning
required, optionalPresence intent
key, unique, indexedIdentity and indexing
default, default(...), default = exprDefault value
pattern expr, pattern = expr, max_length(...), min(...), max(...)Constraints
custom(...), custom = expr, custom exprExtension modifier forms

References use arrow syntax:

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

Tables have additional storage-oriented modifiers and schema members. See Table schema reference for the full table surface.

Entities#

Entity declarations model richer domain objects with inline fields, scoped functions, validations, business rules, and authorization sections.

bl
public entity Customer inherits Party implements Searchable {
  id: uuid key;
  email: email required unique indexed;
  name: string required;

  validation {
    valid_email: email is not null;
  }

  businessRules {
    active_only: status == "active";
  }

  authorization {
    can_read: user.hasRole("sales");
  }

  function display_name(): string {
    return name;
  }
}

Entity fields use inline name: Type declarations and can use entity-level modifiers such as key, required, optional, unique, primary, indexed, immutable, searchable, default(...), default = expr, pattern = "...", references = "...", computed = expr, upper, lower, capitalize, min = value, max = value, and associated(a, b).

Entity inline field types use fieldTypeSpec: a primitive type or named ID, with optional parenthesized literal or identifier parameters such as string(10), list(uuid), or map(string, int). Full typeExpression features such as unions, nullable suffixes, and angle or square generic suffixes belong in table, struct, class, function, or type declarations.

bl
entity VendorProfile {
  vendor_id: uuid key immutable;
  email: email optional unique indexed lower;
  status: string required default("active");
  external_code: string pattern = "^[A-Z0-9]+$";
  search_name: string computed = name;

  validation {
    valid_status: status is not null;
    configured: rule VendorConfigured(vendor_id);
  }
}

Entity functions are scoped members and can use either : or -> before the return type.

bl
entity Customer {
  id: uuid key;
  name: string required;

  function display_name() -> string {
    return name;
  }
}

Structs and type declarations#

Use structs for typed data shapes that are not tables.

bl
@payload(version: 1)
struct Address {
  @label("Street")
  field street: string required max_length(120);
  city: string optional
  country: string default("SA")
  vendor_id: VendorId -> Vendor.vendor_id cascade;
}

Struct members can use annotations, the optional field keyword, typed field declarations, modifiers, arrow references, optional cascade, and optional semicolon terminators.

Struct modifiers use the same compact field modifier style as table fields, including defaults, patterns, ranges, and custom modifier forms.

bl
struct ContactPayload {
  email: email required pattern = "^[^@]+@[^@]+$";
  display_name: string default = "Unknown";
  score: decimal min(0) max(100);
  external_id: string source "crm";
}

Use type for aliases or object-like type declarations:

bl
type Money: decimal;

type PaymentSummary {
  amount: decimal;
  currency: string;
}

Enums#

Use enums only for true invariants.

bl
public enum DebitCredit {
  debit = "D";
  credit = "C";
}

Enum members can have optional expression values. Members can be separated by commas or semicolons, with an optional trailing separator.

If the value set can vary by company, tenant, process, or date, use a configuration table instead of an enum.

Source: packages/business/language/data-modeling.md