Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt

Use this file to discover all available pages before exploring further.

A FieldRule stores a workspace-scoped AI grounding configuration for a single column (field_key) within a record root (e.g. invoices, companies). It carries three optional JSONB payloads — rules_config, formula_config, and format_config — each represented as a rich-text document tree (Tiptap/ProseMirror) or a plain-text prompt string. The entity is owned by the user: it is created or replaced via PUT /v1/field-rules/:root/:fieldKey and soft-deleted via DELETE on the same path. A partial unique index on (workspace_pk, root, field_key) WHERE deleted_at IS NULL enforces one active rule per field per workspace.
NamingValue
ObjectFieldRule
Resource type (JSON:API type)field_rule
Collection / records root(not a records root)
REST base/v1/field-rules
Entity classFieldRule
Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.

API operations

OperationMethod & pathStatus
ListGET /v1/field-rules🟡 Planned
RetrieveGET /v1/field-rules/{id}🟡 Planned
CreatePOST /v1/field-rules🟡 Planned
UpdatePATCH /v1/field-rules/{id}🟡 Planned
DeleteDELETE /v1/field-rules/{id}🟡 Planned

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
field_rule_idstring (UUID) — 🔒 system✅ Yesunique; default gen_random_uuid()Public stable identifier for the field rule. Generated by the database on creation.
rootstring✅ Yesmax length 50; part of partial-unique index (workspace_pk, root, field_key) WHERE deleted_at IS NULLThe record root this rule applies to (e.g. ‘invoices’, ‘companies’, ‘transactions’). Matches the root values accepted by /v1/records/query.
field_keystring✅ Yesmax length 255; part of partial-unique index (workspace_pk, root, field_key) WHERE deleted_at IS NULLDot-notation path identifying the target column within the root (e.g. ‘invoices.issuer.name’). Together with root and workspace, uniquely identifies one active rule.
column_namestring✅ Yesmax length 255Human-readable display label for the column this rule targets, used for context in AI grounding prompts.
column_typestring✅ Yesmax length 50Data type of the target column (e.g. ‘text’, ‘number’, ‘date’). Used to guide the AI extraction format.
rules_configjsonb (FieldRuleConfig — RichTextNode | string | null)⚪ NonullableAI grounding instructions for extraction rules. Stored as a Tiptap/ProseMirror rich-text document tree (RichTextNode) or a plain-text prompt string. Supports @-mention nodes in the document tree.
formula_configjsonb (FieldRuleConfig — RichTextNode | string | null)⚪ NonullableAI grounding configuration for formula-based computation of the field value. Same shape as rules_config — rich-text or plain string.
format_configjsonb (FieldRuleConfig — RichTextNode | string | null)⚪ NonullableAI grounding configuration for output formatting instructions (e.g. currency symbol placement, date format). Same shape as rules_config.
created_atdatetime — 🔒 system✅ Yesset on insert via onCreate hook; not nullTimestamp of row creation. Set automatically by the MikroORM onCreate lifecycle hook.
updated_atdatetime — 🔒 system✅ Yesset on insert and update via onCreate/onUpdate hooks; not nullTimestamp of last modification. Set automatically on every write.
deleted_atdatetime | null — 🔒 system⚪ Nonullable; soft-delete sentinel; included in the partial-unique index condition (WHERE deleted_at IS NULL)Soft-delete timestamp. When set, the rule is logically deleted and excluded from the active partial-unique index, allowing a new rule for the same (workspace, root, field_key) to be created.

Relationships

NameTypeRequiredDescription
workspaceto-one (ManyToOne)✅ YesThe workspace this field rule belongs to. FK: field_rules.workspace_pk → workspaces.pk. Enforces multi-tenant isolation — all queries are scoped to req.workspace. ON UPDATE CASCADE.

System-computed

  • field_rule_id: generated by gen_random_uuid() on insert; never client-provided
  • created_at: set by MikroORM onCreate hook to new Date() at insert time
  • updated_at: set by MikroORM onCreate and onUpdate hooks; reflects last write timestamp
  • deleted_at: written by FieldRuleService.deleteRule() for soft deletion; not a client-settable field
  • Partial unique index idx_field_rules_workspace_root_field_key enforces exactly one active rule per (workspace, root, field_key) when deleted_at IS NULL; soft-deleting a rule releases the slot for re-creation
  • Upsert semantics in FieldRuleService.upsertRule(): finds existing active rule by (root, field_key, workspace); updates in-place if found, creates a new row otherwise
  • On upsert, FieldRuleService.fireAndForgetRecompute() is triggered automatically to re-run AI extraction for affected records — this is a side effect not visible in the API response

Example

{
  "data": {
    "id": "a3f1b2c4-8e12-4d5a-9b3f-1c2e3d4f5a6b",
    "type": "field_rule",
    "attributes": {
      "field_rule_id": "a3f1b2c4-8e12-4d5a-9b3f-1c2e3d4f5a6b",
      "root": "invoices",
      "field_key": "invoices.issuer.name",
      "column_name": "Issuer",
      "column_type": "text",
      "rules_config": {
        "type": "doc",
        "content": [
          {
            "type": "paragraph",
            "content": [
              { "type": "text", "text": "Extract the legal company name from the document header." }
            ]
          }
        ]
      },
      "formula_config": null,
      "format_config": null,
      "created_at": "2026-04-01T10:30:00.000Z",
      "updated_at": "2026-05-15T14:22:00.000Z",
      "deleted_at": null
    },
    "relationships": {
      "workspace": {
        "data": { "id": "7e4c9a12-3b5d-4e6f-8a1b-2c3d4e5f6a7b", "type": "workspace" }
      }
    }
  }
}
Source: apps/api/src/database/entities/FieldRule.ts · domain: workspace · tier: Infrastructure