Schema reference
A table schema declares its fields, primary key, and optional foreign keys. This reference covers managed relational tables. TaruviBase stores a Frictionless descriptor with each table and maps it to a managed PostgreSQL table.
Storage and schema compatibility#
Every table records a storage mode and a schema format. The Database workflows in this documentation use:
| Setting | Required value |
|---|---|
| Storage mode | flat_table |
| Schema format | frictionless |
| Materialization state | is_materialized: true |
flat_table maps declared fields to PostgreSQL columns and supported
constraints. A field declared as {"type":"object"} becomes one JSONB column
inside the managed table. Whole-table JSONB
storage follows
a different record and query contract, so apply the SDK examples here only to
tables that match the settings above.
Before applying these examples to an existing table, confirm that
provider_type is flat_table, schema_format is frictionless, and
is_materialized is true.
Descriptor#
{
"title": "Tasks",
"description": "Work tracked by the application",
"fields": [
{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
},
{
"name": "title",
"type": "string",
"constraints": {
"required": true,
"maxLength": 200
}
}
],
"primaryKey": ["id"],
"foreignKeys": []
}
| Property | Type | Purpose |
|---|---|---|
fields | array | Fields stored in every record |
primaryKey | array containing one field name | Field used to identify a record in SDK and REST operations |
foreignKeys | array | Connections from local fields to another table |
title | string | Optional display title |
description | string | Optional explanation of the table |
Declare primaryKey as an array, including when the table has one key.
Fields#
Every item in fields has a name and type:
{
"name": "priority",
"type": "integer",
"description": "Priority from 1 to 5",
"constraints": {
"required": true,
"minimum": 1,
"maximum": 5
}
}
| Property | Required | Purpose |
|---|---|---|
name | Yes | Key used in records and queries |
type | Yes | Logical value type |
format | No | Type refinement, such as uuid for a string |
arrayItem | For typed arrays | Declares the type stored in each array element |
constraints | No | Required, unique, length, range, or enum rules |
description | No | Human-readable field description |
x-pg-type | For range-family fields | Declares a PostgreSQL range or multirange type |
Use names that start with a letter or underscore and contain only letters,
numbers, and underscores. Lowercase snake_case is the recommended
convention for every interface.
Field types#
For a managed flat table, these declarations produce:
| Schema declaration | PostgreSQL value |
|---|---|
{"type":"string"} | Text, or bounded text with maxLength |
{"type":"string","format":"uuid"} | UUID |
{"type":"integer"} | Integer |
{"type":"number"} | Numeric |
{"type":"boolean"} | Boolean |
{"type":"date"} | Date |
{"type":"datetime"} | Timestamp |
{"type":"object"} | PostgreSQL JSONB column containing a JSON object |
{"type":"array"} | PostgreSQL text array |
{"type":"array","arrayItem":{"type":"integer"}} | PostgreSQL big-integer array |
{"type":"any","x-pg-type":"numrange"} | PostgreSQL range |
Managed flat tables also accept these provisioned field declarations:
| Declaration | PostgreSQL value |
|---|---|
{"type":"time"} | Time |
{"type":"year"} | Integer year |
{"type":"geojson"} | JSONB |
Text#
maxLength creates bounded text. minLength adds a minimum-length check:
{
"name": "code",
"type": "string",
"constraints": {
"minLength": 3,
"maxLength": 20
}
}
UUID#
Declare UUID values as strings with the uuid format:
{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}
TaruviBase generates the UUID when it is omitted. Supply one with an SDK or REST write when the application owns record identity.
JSON objects#
Use object for a structured JSON value in an otherwise ordinary flat table.
Database stores this field in a PostgreSQL JSONB column:
{
"name": "preferences",
"type": "object"
}
Send an object in the record payload, not an encoded JSON string. This field
type is distinct from choosing the whole-table jsonb storage mode.
Portable Database queries treat the object as one field. Promote values that
need independent filtering or sorting into typed flat-table fields.
Arrays#
Use array with arrayItem when every element has a known type:
{
"name": "priority_ids",
"type": "array",
"arrayItem": {
"type": "integer"
}
}
Database maps these arrayItem.type values:
arrayItem.type | PostgreSQL element type |
|---|---|
string | Text |
integer | Big integer |
number | Numeric |
boolean | Boolean |
date | Date |
datetime | Timestamp |
If arrayItem is omitted or its type is not recognized, TaruviBase uses text
elements. Send the field value as a JSON array in record payloads.
PostgreSQL ranges#
Ranges use type: "any" with x-pg-type:
{
"name": "active_window",
"type": "any",
"x-pg-type": "tstzrange"
}
Database accepts these PostgreSQL range declarations:
| Range | x-pg-type |
|---|---|
| Numeric | numrange |
| Integer | int4range |
| Big integer | int8range |
| Date | daterange |
| Timestamp | tsrange |
| Timestamp with time zone | tstzrange |
Use the range declarations above when an application needs PostgreSQL range operators. Keep the field's value shape consistent across every interface that reads or writes it.
Constraints#
Constraints belong inside a field's constraints object:
{
"name": "status",
"type": "string",
"constraints": {
"required": true,
"enum": ["open", "active", "done"]
}
}
| Constraint | Applies to | Effect |
|---|---|---|
required | all field types | Stores a non-null value |
unique | database-compatible field types | Prevents duplicate values |
minLength | string | Sets the minimum text length |
maxLength | string | Sets the maximum text length |
minimum | integer, number | Sets the minimum numeric value |
maximum | integer, number | Sets the maximum numeric value |
enum | string | Limits values to the declared list |
Constraint failures from the Database API use the structured error shape described in Requests, responses, and errors.
Primary keys#
Declare the key field in fields, then list it in primaryKey:
{
"fields": [
{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}
],
"primaryKey": ["id"]
}
Use one UUID key named id for new application tables. TaruviBase generates its
value when a create omits it; an SDK or REST client can supply a UUID when the
application owns record identity.
A schema descriptor can represent more than one primary-key field, and TaruviBase uses that shape for some junction tables. The public record routes address a record through one path value, so this guide does not define composite-key CRUD behavior.
Foreign keys#
Each foreign key names the local field and the referenced table and field:
{
"fields": [
{
"name": "project_id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}
],
"foreignKeys": [
{
"fields": ["project_id"],
"reference": {
"resource": "projects",
"fields": ["id"]
},
"x-actions": {
"onDelete": "NO ACTION"
}
}
]
}
reference.resource uses the logical table name. Local and referenced field
types must be compatible.
onDelete value | Result when the referenced record is deleted |
|---|---|
NO ACTION | Keep the reference protected |
RESTRICT | Reject the delete while dependent values exist |
CASCADE | Delete dependent values |
SET NULL | Clear nullable local fields |
TaruviBase defaults to NO ACTION. SET NULL requires nullable local fields.
Test CASCADE with representative data before using it in an important
environment.
Schema design conventions#
Use these conventions for schemas that must work consistently across the SDK, REST, Console, and Refine paths:
| Requirement | Pattern |
|---|---|
| Default values | Generate the value in application code and include it in the record payload |
| Foreign-key deletion | Choose NO ACTION, RESTRICT, CASCADE, or SET NULL |
| Pattern validation | Validate the pattern in application code before sending the record |
| Custom indexing | Keep custom index definitions out of application-supplied descriptors; see Plan indexes |
| Record identity | Use the generated UUID id; supply a UUID only when the application owns the identity |
| Schema changes | Follow Plan schema changes |