Early access
gqlith is in private early access — the code is not publicly available yet.
These docs preview the surface so you know what to expect.
Join the list →
Docs / Batteries
Custom fields
Tenant-definable custom fields, generated — a governed catalog, typed values, inline atomic writes, filtering and sorting, discoverable on GraphQL, REST and MCP.
Every serious B2B app eventually gets the ticket: “let each customer add their own fields.” Hand-built, that’s a metadata table, a JSONB bag, a bespoke validation layer, and a filtering story that never quite works. In gqlith it’s one tag:
COMMENT ON TABLE tasks IS '@gqlith.customFields';
That generates the whole subsystem:
- A governed catalog — tenants (or whatever scope levels you configure via
customFields.scopeLevels) define their own fields at runtime: kind, label, required, defaults. The catalog itself is protected by RLS and scope-aware access rules. - A typed value surface — custom-field values are not an opaque JSON blob on the wire. GraphQL exposes them through a typed value interface with
@oneOfwrite inputs; REST and MCP expose typed values plus a/schemadiscovery endpoint, so a client (or an AI agent) can learn a tenant’s fields at runtime and render real form controls. - Inline, atomic writes — set custom fields in the same
create/updatemutation as the entity’s own columns; the write persists atomically with the row.requiredfields are enforced partial-write-safe. - Filtering and sorting — custom fields ride the same filter engine as real columns, with structured
whereoperator parity for every field kind and JSONB-backed predicates under the hood. The same expressions work in FiltrQL on REST and MCP. - Governance and adoption — per-field enforcement hardening, plus an adopt mode for bringing an existing JSONB bag under management.
Values live in a JSONB column with a GIN index, written by generated reference DDL — no extra tables to design, no EAV maze, and the whole thing obeys the same tenancy, RBAC and audit model as the rest of the API.