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 Custom Column is a per-workspace, per-root virtual column a user adds to a records table (e.g. a ‘Risk level’ column on companies). It holds the column definition only — name, type, position, and the AI/formula/format config — while the computed cell values live in custom_column_values. Custom columns are workspace-scoped and namespaced by records root; they are NOT Hasura columns and NOT governed DATA_VIEW_ROOTS, so they sit behind the records table as an overlay rather than as a queryable entity of their own.
NamingValue
ObjectCustom Column
Resource type (JSON:API type)custom_column
Collection / records root(not a records root)
REST base/v1/custom-columns
Entity classCustomColumn
Internal object. Not currently exposed on the public REST API. The operations below describe the intended contract.

API operations

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

Data model

Attributes

FieldTypeRequiredConstraintsAllowed valuesDescription
custom_column_idstring, UUID, 🔒 system✅ Yesunique; gen_random_uuid()Public identifier of the column definition. Internal pk is never exposed.
rootstring✅ Yesmax 50 chars; part of partial-unique keyA records root (companies, invoices, transactions, …)The data-view root this column is attached to. Scopes the column to one records table.
namestring✅ Yesmax 255 charsHuman-readable column header shown in the records table.
field_keystring✅ Yesmax 100 chars; part of partial-unique key; slugified from nameStable machine key for the column, slugified from name at creation. Unique per (workspace, root).
typestring (CustomColumnTypeEnum)✅ Yesnative enum custom_column_type_enum; default ‘text’text, number, amount, single_select, multi_select, aiColumn data type. ‘ai’ (and rules_config-bearing columns) are auto-computed; others may be manually entered.
positionnumber (int)⚪ Nodefault 0Display order of the column within the records table.
iconstring⚪ Nomax 100 chars; nullableOptional icon identifier rendered in the column header.
rules_configjsonb⚪ NonullableAI compute rules. When set, the column is auto-computed by the enrichment pipeline (Anthropic Haiku) for every record.
formula_configjsonb⚪ NonullableFormula configuration for computed (non-AI) columns.
format_configjsonb⚪ NonullableDisplay/format configuration (e.g. select options, number format).
created_atISO 8601, 🔒 systemonCreate hookCreation timestamp.
updated_atISO 8601, 🔒 systemonCreate + onUpdate hooksLast-update timestamp.
deleted_atISO 8601, 🔒 systemnullable; soft deleteSoft-delete tombstone; null when active.

Relationships

NameTypeRequiredDescription
workspaceto-one (workspace)✅ YesOwning workspace — the per-workspace scope of the column.
valuesto-many (custom_column_value)⚪ NoComputed/entered cell values for this column, one per record (cascade-deleted with the column).

System-computed

  • custom_column_id generated by gen_random_uuid()
  • field_key slugified from name at creation (slugifyFieldKey)
  • Partial unique index on (workspace_pk, root, field_key) WHERE deleted_at IS NULL — managed in a raw-SQL migration, not @Index (MikroORM cannot express partial indexes)
  • type defaults to ‘text’; position defaults to 0
  • created_at via onCreate; updated_at via onCreate + onUpdate hooks
  • Soft-delete via deleted_at
  • On create: autoProvisionPresets(workspace, root) may seed preset AI columns; fire-and-forget recompute over existing records
  • On rules_config / formula_config / format_config change: enqueueRecompute → recompute all records for the column
  • AI columns (type=‘ai’ or rules_config present) compute via EnrichmentTask (CUSTOM_COLUMN) → Cloud Task → Anthropic Haiku, with anti-prompt-injection guards

Example

{
  "data": {
    "type": "custom_column",
    "id": "7c1f9a02-4d3b-4e21-9a77-2f0c11aa33bc",
    "attributes": {
      "custom_column_id": "7c1f9a02-4d3b-4e21-9a77-2f0c11aa33bc",
      "root": "companies",
      "name": "Risk level",
      "field_key": "risk_level",
      "type": "single_select",
      "position": 3,
      "icon": "shield-alert",
      "rules_config": "{\"prompt\":\"Classify the company risk as low, medium, or high based on its industry and country.\"}",
      "formula_config": null,
      "format_config": "{\"options\":[\"low\",\"medium\",\"high\"]}",
      "created_at": "2026-05-20T09:14:00.000Z",
      "updated_at": "2026-05-28T11:02:00.000Z",
      "deleted_at": null
    }
  },
  "relationships": {
    "workspace": {
      "data": {
        "type": "workspace",
        "id": "a1b2c3d4-0000-4000-8000-000000000001"
      }
    }
  }
}
Source: apps/api/src/database/entities/CustomColumn.ts · domain: records / data-views · tier: Infrastructure