Doc spec

Twelve field types, four naming modes, and a schema/meta split that compiles to all 8 runtime artifacts.

What is a doc?

A business document template. Define your fields once — Rowly and your AI agent handle the rest.

Every business receives vendor invoices constantly — from suppliers, contractors, and service providers. They arrive in different formats: printed, handwritten, digital. Each one has to be read and manually entered into the system. With a VendorInvoice doc in Rowly, that changes completely.

Define the VendorInvoice doc once. Rowly creates the database table, validation rules, workflow states, and MCP tools automatically. Now your AI agent can handle the whole flow: receive a photo of any invoice → read the fields → create the record in Rowly. No typing required, regardless of the vendor's format.

Example — VendorInvoice doc

Field Type Example value
invoice_no Data (short text) INV-2025-042
vendor_name Data (short text) บริษัท ABC จำกัด
invoice_date Date 2025-04-27
amount Currency (money) ฿15,000
status Select (dropdown) "pending", "approved", "paid"

5 fields. Send a photo of any invoice to your AI agent — it reads the data and creates the record automatically. No typing, no format constraints.

Field types (v0.1 — 12 semantic)

12 types cover every common business field — text, numbers, money, dates, choices, files, and more.

  • Data — Short string (≤ 140 chars). Default for names, plates, codes.
  • Text — Long string / multi-line — descriptions, notes, addresses.
  • Int — Signed 64-bit integer. Use for counts and quantities.
  • Float — Double-precision number for non-money measurements.
  • Currency — Money — stored as integer minor units (satangs, cents).
  • Date — ISO date (YYYY-MM-DD). No time component.
  • Datetime — ISO datetime, always stored as UTC.
  • Link — Foreign-key reference to another doc record (options = target doc).
  • Select — One of a finite set of strings declared in options[].
  • Boolean — True / false, defaults to false unless set otherwise.
  • Attach — File attachment (R2 in v1.0; placeholder in v0.1).
  • Table — Child-table rows that belong to a parent record (line items pattern).

Schema vs meta

Schema shapes the data. Meta shapes how humans and AI use it.

Every field has two axes. The schema axistype, required, unique, default — determines how the value is stored and validated. The meta axislabel, description, placeholder, translatable, hidden, read_only — affects how the admin UI renders it and how the MCP tools describe it to agents.

{
  "name": "daily_rate",
  "type": "Currency",
  "required": true,
  "default": 1000,
  "label": "Daily rate",
  "description": "Rental price per day, in THB.",
  "translatable": false
}

Naming modes

How a new record gets its stable id.

  • autoincrement — Integer id per doc.
  • uuid — ULID (default; sortable + unique).
  • naming_series — Pattern like VEH-.YYYY.-.#####; gap-free counter per series.
  • field:<name> — Use a user-supplied field (e.g. a plate number) as the id.

Example — Vehicle doc

A minimal doc with permission overrides.

{
  "name": "Vehicle",
  "label": "Vehicle",
  "icon": "🚗",
  "fields": [
    { "name": "plate",      "type": "Data",     "required": true, "unique": true },
    { "name": "brand",      "type": "Link",     "options": "Brand" },
    { "name": "daily_rate", "type": "Currency", "required": true },
    { "name": "status",     "type": "Select",
      "options": ["available", "rented", "maintenance"] }
  ],
  "permissions_override": {
    "staff":  { "delete": false },
    "viewer": { "write": false, "create": false, "delete": false }
  }
}