Entity types and custom_fields registry
The Accounting substrate query_records surface reads a fixed whitelist of CRM and Commerce entity types. This registry describes that read contract; it is not a catalog of every entity in the platform.
Entity registry
entity_type | Source table | Pillar |
|---|---|---|
crm_contact | crm.contacts | Customer 360 |
crm_company | crm.companies | Customer 360 |
crm_activity | crm.activities | Customer 360 |
commerce_order | commerce.orders | Commerce |
commerce_product | commerce.products | Commerce |
commerce_fulfillment | commerce.fulfillments | Commerce |
Unknown values are rejected. Names such as contact, order, invoice, and journal_entry are not valid query_records entity types.
Query behavior
query_records reads the live OLTP tables and returns substrate: "oltp" with an as_of timestamp. Tenant isolation comes from row-level security after the service sets the tenant database context.
| Input | Behavior |
|---|---|
limit omitted or less than 1 | Uses 100 |
limit greater than 1,000 | Clamps to 1,000 |
Negative offset | Clamps to 0 |
Empty cel_filter | No filter |
freshness_required_seconds | Passed to Class B formula enrichment; it does not select a different data store |
Filterable typed fields
Only the following typed fields can appear on the left side of a CEL predicate.
| Entity type | Typed fields |
|---|---|
crm_contact | first_name, last_name, display_name, company_id, job_title, email, phone, status, lifetime_revenue, lifetime_orders, last_order_at, last_invoice_at, last_payment_at, last_activity_at, created_at, updated_at |
crm_company | name, legal_name, website, industry, email, phone, status, tax_id, tax_exempt, lifetime_revenue, outstanding_balance, contact_count, created_at, updated_at |
crm_activity | contact_id, company_id, activity_type, source_product, source_stream, actor_type, actor_id, summary, occurred_at, created_at |
commerce_order | channel_id, external_id, order_number, status, customer_id, subtotal, shipping_cost, tax, total, currency, shipped_at, delivered_at, created_at, updated_at |
commerce_product | sku, name, type, status, description, short_description, created_at, updated_at |
commerce_fulfillment | order_id, warehouse_id, status, tracking_number, carrier, shipping_method, shipping_cost, shipped_at, delivered_at, created_at, updated_at |
Tenant IDs are deliberately excluded. Array and unrelated JSONB fields are also excluded from the typed whitelist.
Custom fields
The CEL translator permits explicit access to a key in the custom_fields JSONB object:
custom_fields.referred_by == "Instagram"An unrecognized bare identifier does not fall back to JSONB. Use the custom_fields.<key> path explicitly.
Custom-field values are extracted as text on this surface. Compare them with string literals unless the field has a separate typed-column declaration.
Supported CEL subset
The shared translator supports:
- Comparisons:
==,!=,<,<=,>,>= - Boolean composition:
&&,||,! - Membership:
field in ["a", "b"] - Time builders:
timestamp("RFC3339"),now(), and supported duration arithmetic - String operations:
startsWith,endsWith,contains,matches, andsize
Examples:
status == "paid" && total >= 100created_at >= now() - duration("720h")email.endsWith("@example.com")custom_fields.region in ["north", "west"]Literal values are bound as SQL parameters. Unsupported but syntactically valid CEL features map to a 501 subset error; malformed filters and unknown columns map to 400.
Write scope
The update_record tool may use the same entity-type vocabulary, but write support and approval tier are enforced separately. Read support on this page does not guarantee that every returned field is writable.