ObjectStackObjectStack

Schema Definition

In ObjectQL, you do not write CREATE TABLE statements, nor do you define Mongoose Schemas or TypeORM Classes. Instead, you define Objects using a standard YAML (or JSON) protocol.

This Schema is the Single Source of Truth. It drives not only the Database structure but also the API validation, the UI generation, and the permission checking.

1. The Object Protocol

An Object in ObjectQL represents a business entity (e.g., Project, Invoice, Employee). It maps roughly to a table in a relational database or a collection in a document database.

Basic Structure

# src/objects/project.object.yml
name: project               # Unique API identifier (snake_case)
label: Project              # Human-readable label
table_name: projects        # (Optional) Physical table name override
icon: standard:account      # Icon for ObjectUI
description: A high-level container for tasks and resources.
hidden: false               # If true, hidden from the API discovery

2. Fields

Fields define the columns and properties of the object. ObjectQL supports Enterprise Data Types out of the box, ensuring consistency across different underlying databases.

Core Data Types

TypeDescriptionMaps to (Postgres)Maps to (Mongo)
textSingle line stringVARCHARString
textareaMulti-line textTEXTString
htmlRich textTEXTString
numberDouble precisionNUMERICNumber
currencyHigh-precision moneyDECIMAL(18, 2)Decimal128
booleanTrue/FalseBOOLEANBoolean
dateDate onlyDATEDate
datetimeDate and TimeTIMESTAMPDate
selectEnum / DropdownVARCHARString

Field Configuration

fields:
  name:
    type: text
    label: Project Name
    required: true
    searchable: true        # Creates a database index automatically
    index: true

  status:
    type: select
    options:
      - label: Planning
        value: planning
      - label: In Progress
        value: in_progress
      - label: Completed
        value: completed
    default: planning

  budget:
    type: currency
    scale: 2
    precision: 18

3. Relationships

ObjectQL handles relationships by treating them as Field Types. The compiler automatically generates the necessary Foreign Keys and JOIN logic.

Lookup (Many-to-One)

The most common relationship. A task belongs to a project.

# src/objects/task.object.yml
fields:
  project:
    type: lookup
    reference_to: project   # Points to the 'name' of the target Object
    required: true
  • Database Effect: Creates a project column (FK) in the tasks table.
  • UI Effect: Renders a searchable dropdown or modal picker.

Master-Detail (Strong Ownership)

Similar to Lookup, but implies ownership. If the Master record is deleted, the Detail records are deleted (Cascade Delete).

# src/objects/invoice_line.object.yml
fields:
  invoice:
    type: master_detail
    reference_to: invoice
    write_requires_master_read: true # Security inheritance

Hierarchical (Self-Reference)

An object linking to itself (e.g., an Org Chart or Folder Tree).

fields:
  parent_task:
    type: lookup
    reference_to: task

4. Virtual Fields (Computed)

This is where ObjectQL shines as a Compiler. You can define fields that do not exist in the database but are calculated on-the-fly during the query.

Formula Fields

Compiles to a SQL expression injected into the SELECT clause.

fields:
  # Logic: (Total - Cost) / Total
  margin_percentage:
    type: formula
    data_type: number
    formula: "({amount} - {cost}) / {amount}"
    scale: 2

Summary Fields (Rollups)

Compiles to a SQL Subquery or Aggregation.

# src/objects/project.object.yml
fields:
  # Counts all tasks linked to this project where status = 'closed'
  closed_task_count:
    type: summary
    summary_object: task
    summary_type: count
    summary_field: _id
    filters: [["status", "=", "closed"]]

5. The Compilation Process

When you start the ObjectOS engine, it reads these YAML files and performs a Schema Diff:

  1. Parse: Convert YAML to AST.
  2. Compare: Check AST against current Database Information Schema.
  3. Migrate: Generate SQL DDL (CREATE, ALTER) to synchronize the DB.

Example Output

For the YAML above, the Postgres driver might execute:

CREATE TABLE projects (
    _id VARCHAR(50) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    status VARCHAR(50) DEFAULT 'planning',
    budget DECIMAL(18, 2)
);

CREATE INDEX idx_projects_name ON projects(name);

:::info Database Agnostic Because the definition is in YAML, switching from PostgreSQL to MySQL requires zero changes to your schema files. You only change the Driver configuration. :::

On this page