Tables Overview
Tables define your data models. Each table is a distinct entity (users, products, orders) whose fields declare the columns that records can store. Tables are the foundation of a Sovrium app: pages render their records, forms write to them, automations react to their changes, and the REST/MCP APIs expose them.
A table has at minimum an id, a name, and a fields array. Everything else — primary keys, indexes, constraints, views, permissions, webhooks, and AI exposure — is optional and layered on top.
tables:
- id: 1
name: Contacts
fields:
- { id: 1, name: email, type: email, required: true, unique: true }
- { id: 2, name: full_name, type: single-line-text, required: true }
- { id: 3, name: created_at, type: created-at, indexed: true }
Table Properties
Each entry in the tables array accepts the following properties.
| Property | Description |
|---|---|
id |
Unique integer identifier for the table. Auto-generated when omitted. |
name |
User-friendly table name. Can contain spaces and mixed case; sanitized for database use (lowercase with underscores). Maximum 63 characters. |
fields |
Array of field definitions. At least one field is required. Field names and IDs must be unique within the table. |
primaryKey |
Primary key configuration. Defaults to an auto-generated id column. See Indexes & Constraints. |
unique |
Array of top-level unique-constraint declarations. Each entry covers one or more fields (e.g. [{ fields: [slug] }]). |
indexes |
Array of index definitions for query performance and uniqueness enforcement. |
uniqueConstraints |
(via unique) Multi-field uniqueness. Single-field entries fold into field.unique; composite entries become unique btree indexes. |
foreignKeys |
Composite (multi-column) foreign key definitions. Single-column foreign keys are created automatically from relationship fields. |
constraints |
Array of CHECK constraints with SQL expressions for cross-field data validation. |
views |
Saved views with pre-configured filters, sorting, grouping, and visible fields. See Views. |
permissions |
RBAC permissions controlling create, read, update, delete, restore, comment, and per-field access. See Permissions. |
rowLevelPermissions |
Server-side when predicates per CRUD operation for defense-in-depth row scoping. |
webhooks |
Outgoing webhooks fired on record create/update/delete events. See Webhooks. |
comments |
Comment-system configuration (guest commenting, moderation, threading). |
aiAccess |
Declares the table eligible for exposure via Sovrium's MCP server so AI assistants can list/read/write records (subject to RBAC). |
allowDestructive |
Boolean. When true, allows destructive schema migrations (column drops, type changes). Defaults to false. |
allowForceDelete |
Boolean. Per-table opt-in permitting hard-delete via the admin dashboard (GDPR erasure). Defaults to false. See note below. |
Soft-delete by default. Deleting a record sets deleted_at/deleted_by and leaves the row recoverable via /restore. Set allowForceDelete: true only when a table needs irreversible hard-delete (e.g. GDPR right-to-erasure on an HR table). Financial ledgers and audit-adjacent tables should leave it at the false default — the admin force-delete endpoint returns 404 when force-delete is not allowed.
Base Field Properties
Every field — regardless of type — extends a common base. These properties are available on all 49 field types.
| Property | Description |
|---|---|
id |
Unique integer identifier for the field within the table. Auto-generated sequentially when omitted. |
name |
Column identifier. Must start with a letter and contain only lowercase letters, digits, and underscores (^[a-z][a-z0-9_]*). Maximum 63 chars. |
type |
One of the 49 available field types (e.g. single-line-text, integer, relationship). See Field Types. |
required |
Boolean. When true, the field must have a value for every record. |
unique |
Boolean. When true, no two records can share the same value. |
indexed |
Boolean. When true, creates a database index on this field for faster queries. |
searchWeight |
PostgreSQL full-text-search relevance weight: A (highest) to D (lowest). Only effective when indexed: true and the data source uses FTS. |
storage |
Storage configuration object. storage.compression (boolean) enables compression for large text or attachment values. |
default is type-specific, not a base property. Most value-carrying fields (text, numeric, selection, date, color, …) expose a default whose value type matches the field. System fields (created-at, relational, computed, AI) do not. Each field-type page lists whether default is available.
Example: a richer table
tables:
- id: 2
name: Products
fields:
- { id: 1, name: sku, type: single-line-text, required: true, unique: true }
- {
id: 2,
name: title,
type: single-line-text,
required: true,
searchWeight: A,
indexed: true,
}
- { id: 3, name: description, type: long-text, searchWeight: B }
- { id: 4, name: price, type: currency, required: true, currency: USD }
- { id: 5, name: in_stock, type: checkbox, default: true }
primaryKey: { type: auto-increment, field: id }
indexes:
- { name: idx_products_sku, fields: [sku], unique: true }
permissions:
read: all
create: [admin, editor]
update: [admin, editor]
delete: [admin]
Related Pages
- Field Types Overview — all 49 field types by category.
- Permissions — RBAC and per-field access control.
- Indexes & Constraints — primary keys, indexes, CHECK constraints.
- Relationships — linking tables together.
- Views — saved filters, sorts, and grouping.
- Validation — field- and table-level validation rules.
- Webhooks — outgoing HTTP on record events.