Skip to content

enfyra/server

Repository files navigation

Enfyra Backend

Enfyra is the open-source backend platform.
We’re building the flexibility backend framework that automatically generates APIs from your database. You create tables through a visual interface, and Enfyra instantly provides REST & GraphQL APIs for them - no coding required. It's like having a backend developer that never sleeps.

Documentation

For full documentation, visit docs

To see how to contribute, visit Contributing

Community & Support

How it works

Architecture

Enfyra is a self-hosted and locally developed, easy-to-install. Cloud coming soon.

  • Query Engine: high-performance engine for filtering, joins, aggregates, and search directly through your API.
  • Realtime: push updates to clients when rows change using websockets.
  • REST/GraphQL API: automatically generated from your schema.
  • Auth Service: JWT-based authentication API for sign-ups, logins, and session management.
  • Storage: RESTful API for managing files and permissions.
  • Functions: run server-side code close to your data.

Database Migrations

Enfyra supports schema and data migrations through JSON configuration files.

Schema Migration (data/snapshot.json)

Define your database schema (tables, columns, relations):

{
  "my_table": {
    "name": "my_table",
    "description": "My custom table",
    "columns": [
      { "name": "id", "type": "int", "isPrimary": true, "isGenerated": true },
      { "name": "name", "type": "varchar", "isNullable": false }
    ],
    "relations": []
  }
}

Run schema migration:

npx ts-node scripts/init-db.ts

Schema Migration (data/snapshot-migration.json)

For dangerous operations (remove, modify/rename). Adding is handled automatically by snapshot.json.

{
  "tables": [
    {
      "_unique": { "name": { "_eq": "users" } },
      "columnsToModify": [
        { "from": { "name": "email" }, "to": { "name": "userEmail" } }
      ],
      "columnsToRemove": ["deprecated_field"],
      "relationsToModify": [
        { "from": { "propertyName": "oldRelation" }, "to": { "propertyName": "newRelation" } }
      ],
      "relationsToRemove": ["deprecated_relation"]
    }
  ],
  "tablesToDrop": ["old_table_name"]
}

Operations:

Field Description Data Loss Risk
columnsToModify Rename or change column properties Low (rename preserves data)
columnsToRemove Remove columns HIGH
relationsToModify Rename or change relation properties Low
relationsToRemove Remove relations (drops FK column) HIGH
tablesToDrop Drop entire tables HIGH

Flow:

  1. Physical DB changes (init-db script or app bootstrap)
  2. Metadata updates (provision service)
  3. Both read from same snapshot-migration.json → consistent

Usage Examples

1. Rename a column (preserves data)

{
  "tables": [{
    "_unique": { "name": { "_eq": "users" } },
    "columnsToModify": [
      { "from": { "name": "email" }, "to": { "name": "userEmail" } }
    ]
  }]
}

Result: Column email renamed to userEmail, data preserved.

2. Change column properties

{
  "tables": [{
    "_unique": { "name": { "_eq": "users" } },
    "columnsToModify": [
      {
        "from": { "name": "status", "isNullable": true },
        "to": { "name": "status", "isNullable": false }
      }
    ]
  }]
}

Result: Column status becomes NOT NULL.

3. Remove deprecated column (⚠️ data loss)

{
  "tables": [{
    "_unique": { "name": { "_eq": "users" } },
    "columnsToRemove": ["old_legacy_field"]
  }]
}

Result: Column old_legacy_field dropped, all data in this column lost.

4. Rename a relation (preserves FK data)

{
  "tables": [{
    "_unique": { "name": { "_eq": "orders" } },
    "relationsToModify": [
      { "from": { "propertyName": "approvedBy" }, "to": { "propertyName": "approver" } }
    ]
  }]
}

Result: FK column approvedById renamed to approverId, data preserved.

5. Remove a relation (⚠️ FK data loss)

{
  "tables": [{
    "_unique": { "name": { "_eq": "orders" } },
    "relationsToRemove": ["legacyRelation"]
  }]
}

Result: FK column dropped, all FK references lost.

6. Drop entire table (⚠️ all data lost)

{
  "tablesToDrop": ["deprecated_table", "legacy_data"]
}

Result: Tables completely removed from database.

When to Use

Scenario File to Modify
Add new table snapshot.json
Add new column snapshot.json
Add new relation snapshot.json
Rename column snapshot-migration.json
Remove column snapshot-migration.json
Rename relation snapshot-migration.json
Remove relation snapshot-migration.json
Drop table snapshot-migration.json

How It Works

┌─────────────────────────────────────┐
│     snapshot-migration.json         │
│         (single source)             │
└──────────────┬──────────────────────┘
               │
       ┌───────┴───────┐
       ▼               ▼
┌──────────────┐ ┌──────────────────┐
│  init-db.ts  │ │  provision service│
│              │ │  (app bootstrap)  │
│ Physical DB  │ │   Metadata DB     │
│  (tables,    │ │  (table_def,      │
│   columns,   │ │   column_def,     │
│   FKs)       │ │   relation_def)   │
└──────────────┘ └──────────────────┘
       │               │
       └───────┬───────┘
               ▼
         ✅ Consistent

Both physical DB and metadata are updated from the same source, ensuring consistency.

Data Migration (data/data-migration.json)

Migrate existing data when the system is already initialized:

{
  "_deletedTables": ["deprecated_table"],
  "role_definition": [
    {
      "name": "Admin",
      "description": "Updated admin description",
      "_unique": { "name": { "_eq": "Admin" } }
    }
  ]
}
  • _deletedTables: Array of table names to delete all data from
  • Table entries: Data to migrate, using _unique to identify existing records

Migration Flow

  1. First Init (isInit = false):

    • Schema is created from snapshot.json
    • Default data is inserted from default-data.json
    • System sets isInit = true
  2. Subsequent Starts (isInit = true):

    • Schema is synced from snapshot.json (auto-add new columns/relations)
    • Schema migrations run from snapshot-migration.json (remove/modify)
    • Data migrations run from data-migration.json

Supported Databases

  • SQL: MySQL, PostgreSQL, MariaDB
  • NoSQL: MongoDB

About

Enfyra – an open-source, self-hosted BaaS with built-in clustering, letting you build fast, scale easily, and customize without limits.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors