Basefyio Data Engine

The Basefyio Data Engine is a document data plane that runs alongside your existing dedicated databases. Store flexible, schema-driven documents with nested objects, arrays, versioning, soft-delete, and automatic multi-tenant isolation.

The Data Engine supports two storage providers — a dedicated NoSQL store for production workloads and a database JSONB fallback for development. Both implement the same interface; your application code works identically regardless of which provider is active.

Key Features

  • Schema-driven documents — Define entities with typed fields. Documents are validated against your schema on every write.
  • Nested data — Objects inside objects, arrays of objects, repeatable sections. No flattening required.
  • Document versioning — Every document carries a _version and _eventSequence. Optimistic concurrency via If-Match.
  • Soft delete — Deleted documents are recoverable. Query with includeSoftDeleted to see them.
  • Multi-tenant isolation — Every query has _projectId injected server-side. Project A can never read Project B's data.
  • Event system — Every write produces an outbox event: document.created, document.updated, document.deleted.
  • Provider-agnostic — Switch between NoSQL store and database with a single environment variable.

Document Envelope

Every stored document carries these reserved fields automatically:

{
  "_id": "patients::550e8400-e29b-41d4-a716-446655440000",
  "_entity": "patients",
  "_projectId": "prj_abc123",
  "_schemaVersion": 1,
  "_version": 5,
  "_eventSequence": 5,
  "_status": "active",
  "_createdAt": "2026-06-09T10:00:00.000Z",
  "_updatedAt": "2026-06-09T15:30:00.000Z",
  "_createdBy": "user_456",
  "_deletedAt": null,
  "firstName": "John",
  "lastName": "Smith",
  "address": {
    "city": "Istanbul",
    "country": "TR"
  }
}
FieldTypeDescription
_idstringUnique document identifier
_entitystringEntity type name
_projectIdstringOwning project (injected server-side, cannot be overridden)
_schemaVersionnumberSchema version this document was written under
_versionnumberOptimistic concurrency token (CAS)
_eventSequencenumberMonotonic counter per document (for offline sync)
_statusstringactive, draft, archived, deleted, or pending_approval
_createdAtISO 8601Creation timestamp
_updatedAtISO 8601Last modification timestamp
_createdBystringUser ID who created the document
_deletedAtISO 8601 | nullSoft-delete timestamp (null if active)

User schemas cannot define fields starting with _. The system rejects them with HTTP 422.

REST API

Base path: https://api.basefyio.com/v1/projects/:projectId

Entity Management

MethodPathDescription
GET/entitiesList all entity definitions
POST/entitiesCreate an entity definition
GET/entities/:entityGet entity definition with fields and rules

Document CRUD

MethodPathDescription
POST/data/:entityCreate a document
GET/data/:entityList/query documents (filter, sort, paginate)
GET/data/:entity/:idGet document by ID
PATCH/data/:entity/:idPartial update (merge fields)
PUT/data/:entity/:idFull replacement
DELETE/data/:entity/:idSoft delete

Query Parameters

ParameterTypeExample
filterJSON string{"status":"active","address.city":"Istanbul"}
sortJSON string[{"path":"_createdAt","direction":"desc"}]
limitnumber50 (max 1000)
offsetnumber0

SDK Usage

import { createClient } from 'basefyio-js'

const bf = createClient({ projectId: '...', apiKey: '...' })

// Create an entity
await bf.data.createEntity({
  logicalName: 'patients',
  displayName: 'Patients',
  fields: [
    { name: 'firstName', kind: 'scalar', type: 'text', required: true },
    { name: 'lastName', kind: 'scalar', type: 'text', required: true },
    { name: 'address', kind: 'object', children: [
      { name: 'city', kind: 'scalar', type: 'text', required: true },
      { name: 'country', kind: 'scalar', type: 'text', required: true },
    ]},
    { name: 'tags', kind: 'array', itemSchema: {
      name: 'tag', kind: 'scalar', type: 'text'
    }},
  ],
})

// Insert a document
const { data: patient } = await bf.data.collection('patients').insert({
  firstName: 'John',
  lastName: 'Smith',
  address: { city: 'Istanbul', country: 'TR' },
  tags: ['cardiology', 'vip'],
})

// Find documents with nested filter
const { data: results } = await bf.data.collection('patients')
  .find({ 'address.city': 'Istanbul' })
  .sort('_createdAt', 'desc')
  .limit(20)

// Get by ID
const { data: doc } = await bf.data.collection('patients').get(patient._id)

// Partial update (merge)
await bf.data.collection('patients').update(patient._id, {
  tags: ['cardiology', 'vip', 'follow-up'],
})

// Soft delete
await bf.data.collection('patients').delete(patient._id)

// List entities
const { data: entities } = await bf.data.listEntities()

// Health check
const { data: health } = await bf.data.health()
// => { available: true, reachable: true }

Entity Schema System

Entity definitions live in database metadata, not in the document store. Each entity has typed fields that compile to JSON Schema for validation.

Field Kinds

KindDescriptionExample
scalarSimple value (text, number, boolean, date, email, phone, url)firstName: text
objectNested object with child fieldsaddress: { city, country }
arrayArray with item schematags: [text]
lookupReference to another entitydoctorId → doctors
mediaRich media (url, dimensions, duration)avatar: media
counterNumeric counter updated via eventsviews: counter
attachmentFile reference (url, mimeType, size)report: attachment

Nested Data Example

// An entity with nested objects and arrays
{
  logicalName: 'orders',
  fields: [
    { name: 'customer', kind: 'object', children: [
      { name: 'name', kind: 'scalar', type: 'text', required: true },
      { name: 'address', kind: 'object', children: [
        { name: 'city', kind: 'scalar', type: 'text' },
        { name: 'country', kind: 'scalar', type: 'text' },
        { name: 'zip', kind: 'scalar', type: 'text' },
      ]},
    ]},
    { name: 'lineItems', kind: 'array', itemSchema: {
      name: 'lineItem', kind: 'object', children: [
        { name: 'productId', kind: 'scalar', type: 'text', required: true },
        { name: 'quantity', kind: 'scalar', type: 'number', required: true },
        { name: 'price', kind: 'scalar', type: 'currency' },
      ]
    }},
    { name: 'total', kind: 'scalar', type: 'currency', required: true },
  ]
}

Storage Providers

ProviderWhen to UseConfiguration
NoSQL storeProduction — optimized for document workloads, full-text search, KV accessDATA_ENGINE_PROVIDER=nosql
databaseDevelopment — no extra infrastructure, uses existing project DBDATA_ENGINE_PROVIDER=database
DisabledSkip Data Engine entirely (existing features unaffected)DATA_ENGINE_PROVIDER=disabled

Configuration

VariableDefaultDescription
DATA_ENGINE_PROVIDERdisabledProvider: nosql, database, or disabled
NOSQL_CONNSTRNoSQL store connection string
NOSQL_USERNAMEStore admin username
NOSQL_PASSWORDStore admin password
DATA_ENGINE_CONTAINERbasefyio-appsTop-level container name
DATA_ENGINE_NAMESPACEprojectsDefault namespace
DATA_ENGINE_MAX_DOC_KB1024Max document size in KB
DATA_ENGINE_MAX_NESTING_DEPTH8Max schema nesting depth
DATA_ENGINE_MAX_ARRAY_ITEMS1000Max array items per field

Admin Dashboard — Data Tab

Each project's Data tab in the dashboard provides:

  • Entity sidebar — Browse all entities, see AI-generated badges, search by name
  • Document browser — Expandable JSON cards with envelope metadata (version, status, timestamps)
  • JSON filter — Filter documents with JSON syntax, e.g. {"status":"active"}
  • Insert / Edit / Delete — Full CRUD with JSON editors
  • Pagination — Server-side, 50 documents per page
  • Engine label — Read-only "Basefyio Data Engine" badge