@mobtakronio/schemakit
Version:
Dynamic entity management system with runtime schema creation, validation, and CRUD operations for Node.js backends.
413 lines (318 loc) โข 13.3 kB
Markdown
*ship apps that adapt on the fly*
> โ ๏ธ **BETA VERSION** - Active development. Not recommended for production use yet.
> ๐ **NEW in v0.2.6**: Cleaner multi-tenancy (default tenant: `public`), removed in-memory adapter, improved error details with cause/context, and Postgres inserts now return the full inserted row via `RETURNING *`.
**SchemaKit is a runtime schema engine** that lets you build secure, multi-tenant backend applications where entities, permissions, and workflows are defined as data rather than code. Build business applications that can evolve without code deployments.
Unlike traditional ORMs that require code changes to add entities, SchemaKit stores your **schema as data**. Add new business entities, modify permissions, and create workflows through API calls - no code deployment needed.
```typescript
// Traditional ORM: Define entities in code
const userSchema = z.object({
name: z.string(),
email: z.string().email()
});
// SchemaKit: Entities are data, created at runtime
await schemaKit.defineEntity({
name: 'customer',
fields: {
name: { type: 'string', required: true },
department: { type: 'string' }
},
authorization: {
'manager': [{
conditions: [{
field: 'department',
operator: 'eq',
value: 'currentUser.department', // Dynamic filtering
exposed: false // Hidden from user
}]
}],
'analyst': [{
conditions: [{
field: 'priority',
operator: 'in',
value: ['high', 'urgent'],
exposed: true, // User can modify this filter
metadata: {
type: 'multiselect',
options: ['low', 'medium', 'high', 'urgent']
}
}]
}]
},
// Workflows coming in v0.3
// workflows: {
// 'after-create': ['send-notification', 'update-analytics']
// }
});
// Use immediately - no code deployment
const customer = await schemaKit.entity('customer', tenantId);
await customer.create({ name: 'ACME Corp', department: 'Sales' });
```
SchemaKit is built as a layered runtime engine:
```sql
system_entities -> Entity definitions stored as data
system_fields -> Field schemas with validation rules
system_permissions -> Business authorization rules
system_workflows -> Lifecycle automation definitions
system_views -> Query configurations
```
```typescript
EntityBuilder -> Dynamic entity creation from meta-schema
PermissionManager -> Business authorization with exposed/hidden filters
Validation (Adapter) -> Runtime data validation
RLS Integration -> Row-level security patterns
ViewManager -> Planned: Query configuration management
WorkflowManager -> Planned: Lifecycle event automation
```
### 3. **Adapter Layer** (Database Abstraction)
```typescript
DrizzleAdapter -> Unified adapter for Postgres, SQLite, MySQL (via Drizzle drivers)
```
### 4. **Interface Layer** (Future: Low-Code Tools)
```typescript
REST API -> Planned: Auto-generated endpoints
GraphQL API -> Planned: Dynamic schema generation
Admin UI -> Planned: Entity management interface
CLI Tools -> Planned: Schema migration utilities
```
## ๐ Key Innovations
### **Meta-Database Approach**
Store entity definitions as data, not code. Add new entity types through API calls:
```typescript
// Add a new entity type without deploying code
await schemaKit.defineEntity({
name: 'project',
fields: {
name: { type: 'string' },
status: { type: 'string', options: ['active', 'completed'] }
}
});
```
Hybrid permission system with enforced and user-controllable filters:
```typescript
// Some filters are enforced (security)
// Some filters are exposed (user experience)
authorization: {
'analyst': [{
conditions: [
{ field: 'department', exposed: false }, // Enforced by system
{ field: 'priority', exposed: true } // User can modify
]
}]
}
```
Create reusable query configurations:
```typescript
views: {
'active-customers': {
filters: { status: 'active' },
sorting: [{ field: 'created_at', direction: 'DESC' }],
fields: ['name', 'email', 'department']
}
}
```
Built-in tenant isolation at the database level:
```typescript
const customerEntity = await schemaKit.entity('customer', 'tenant-123');
// All operations automatically scoped to tenant-123
```
```bash
npm install @mobtakronio/schemakit
```
```typescript
import { SchemaKit } from '@mobtakronio/schemakit';
// Initialize with your preferred database
const schemaKit = new SchemaKit({
adapter: 'postgres', // or 'sqlite', 'mysql'
config: { url: process.env.DATABASE_URL }
});
// Get entity (auto-creates from meta-schema)
const user = await schemaKit.entity('users', 'tenant-id');
// Business operations with built-in authorization
await user.create({
name: 'John Doe',
email: 'john@example.com'
});
const users = await user.find(); // Automatically filtered by permissions
```
- **SaaS Applications** - Multi-tenant apps with dynamic requirements
- **Internal Tools** - Rapid development with business user configuration
- **Client Projects** - Agencies building customizable applications
- **Startups** - Need to move fast and adapt quickly
- **Low-Code Platforms** - Building configurable business applications
- **High-performance applications** - Use Drizzle/Prisma directly
- **Simple CRUD apps** - Traditional ORMs might be simpler
- **Static schemas** - If your schema never changes, code-first is fine
Goal: Establish foundational architecture and prove the runtime entity concept.
- โ
Meta-database architecture (system_entities, system_fields, etc.)
- โ
Runtime entity builder (schemaKit.entity('customer'))
- โ
Pluggable database adapter layer (Postgres, SQLite, InMemory)
- โ
Permission system (RLS-style with exposed/hidden filters)
- โ
Multi-tenancy context support
### **v0.2 - Views & Validation Layer**
Goal: Strengthen schema-powered querying and enforce data correctness.
- ๐ Views system โ dynamic runtime queries with permissions and filters
- ๐ Validation engine โ field-level + custom rule validation
- ๐ Improved error handling โ standard error codes, context-based messages
- ๐ Caching strategies for entity schema and permissions
- ๐งช Entity test utils (mockEntity(), runWithContext())
### **v0.3 - Developer Experience + Adapter Ecosystem**
- ๐ฏ DrizzleAdapter (for query optimization and joins)
- ๐ฏ Better transaction and query debugging across adapters
- ๐ฏ Type-safe entity access (through TypeScript enhancement layer)
### **v0.4 - API & External Interfaces**
- ๐งฌ Auto-generated REST API layer (based on runtime schema + permissions)
- ๐งฌ Audit logs for entity/schema/permission changes
- ๐งฌ Entity versioning (track schema changes over time)
### **v0.5 - Workflow & Events**
- ๐ฏ OpenAPI/Swagger generation
- ๐ฏ Workflow engine (basic lifecycle hooks)
- ๐ฏ Events layer (Webhooks, Queue support)
### **v0.6 - UI Builder (Optional Web Layer)**
- ๐ฏ Web-based entity/field builder UI (linked to system_entities)
- ๐ฏ Permission/role UI with exposed filters
- ๐ฏ Workflow visual editor (state-machine or flow-based)
- ๐ฏ Query builder for creating โviewsโ visually
### **v1.0๐ - Public/Enterprise Ready**
Goal: Full SaaS/enterprise use-case support with documentation and examples.
- ๐ฏ Tenant isolation strategies (shared DB, schema, or DB per tenant)
- ๐ฏ Role-based UI definitions (custom forms/layouts per role)
- ๐ฏ Plugin system (custom rules, hooks, adapters)
- ๐ฏ Extensive docs + SDKs (Node, Browser, CLI)
- ๐ฏ Real-world examples: CRM, Inventory, E-commerce, etc.
### **Experimental / Future Ideas**
- ๐ง AI-powered schema suggestions or generation
- ๐ Integration with existing low-code tools (Retool, BudiBase, etc.)
- ๐ผ Schema portability (exportSchema(), importSchema())
- ๐ฏ Real-time subscriptions
- ๐ฏ TypeORMAdapter (enterprise features)
## ๐ค Contributing
### ๐๏ธ Monorepo Structure
SchemaKit now uses a **monorepo architecture** for better organization and framework adapter development:
```
schemakit/ # Repository root
โโโ packages/
โ โโโ schemakit/ # ๐ฆ Core engine (this package)
โ โโโ schemakit-elysia/ # ๐ Elysia framework adapter
โ โโโ schemakit-api/ # ๐ง Shared API utilities
โ โโโ schemakit-express/ # ๐ง Express adapter (coming soon)
โโโ examples/
โ โโโ elysia-basic/ # ๐ก Working examples
โโโ pnpm-workspace.yaml # ๐ Workspace configuration
โโโ README.md # ๐ Monorepo overview
```
### ๐ ๏ธ Development Setup
```bash
# Clone the repository
git clone https://github.com/MobtakronIO/schemakit.git
cd schemakit
# Install dependencies (requires pnpm)
pnpm install
# Build all packages
pnpm build
# Work on core SchemaKit
cd packages/schemakit
pnpm dev
# Run tests
pnpm test
```
### ๐ฏ Contribution Areas
SchemaKit is designed with a clear separation of concerns. Contributors can focus on specific layers:
- **Meta Schema Layer**: Enhance the data model for entities/permissions
- **Engine Layer**: Improve business logic and authorization patterns
- **Adapter Layer**: Add support for new databases (MongoDB, CockroachDB, etc.)
- **Framework Adapters**: Build integrations for Express, Fastify, NestJS, etc.
- **Interface Layer**: Build tools and UIs for schema management
### ๐ฆ Package Dependencies
- **Core (`@mobtakronio/schemakit`)**: Framework-agnostic, zero HTTP dependencies
- **Framework Adapters**: Depend on core + specific framework (Elysia, Express, etc.)
- **Shared API**: Common utilities for all framework adapters
- **Examples**: Demonstrate real-world usage patterns
## ๐ Performance & Production
While in beta, SchemaKit prioritizes **developer experience** and **flexibility** over raw performance. For production applications requiring maximum performance:
1. **Use DrizzleAdapter** (planned v0.3) for query optimization
2. **Cache entity definitions** using the built-in caching system
3. **Consider hybrid approaches** - SchemaKit for dynamic entities, direct ORM for static high-traffic tables
## ๐ Learn More
- ๐ฎ **[Examples](../../examples/)** - See SchemaKit in action with framework adapters
- ๐ **[Elysia Adapter](../schemakit-elysia/)** - Auto-generated REST APIs with Swagger docs
- ๐๏ธ **[Monorepo Overview](../../README.md)** - Full project structure and roadmap
- ๐ฌ **[Discussions](https://github.com/MobtakronIO/schemakit/discussions)** - Community and support
- ๐ **[Issues](https://github.com/MobtakronIO/schemakit/issues)** - Bug reports and feature requests
## ๐ License
MIT ยฉ [MobtakronIO](https://github.com/MobtakronIO)
---
**SchemaKit: Where Business Logic Meets Runtime Flexibility**
*Code Less. Deploy Less. Build Smarter.*
## ๐๏ธ Database Adapters
SchemaKit uses a flexible adapter pattern to support multiple databases.
### Using Drizzle ORM (Recommended)
For production use, SchemaKit integrates with Drizzle ORM to provide robust database support. This approach gives you:
- ๐ **Better Performance** - Connection pooling, prepared statements, and query optimization
- ๐ **Type Safety** - Full TypeScript support with Drizzle
- ๐ก๏ธ **Security** - Automatic SQL injection protection
- ๐ฆ **Smaller Bundle** - Database drivers are peer dependencies
#### Installation
First, install Drizzle ORM and your database driver:
```bash
# For PostgreSQL
npm install drizzle-orm pg
# For MySQL
npm install drizzle-orm mysql2
# For SQLite
npm install drizzle-orm better-sqlite3
```
#### Configuration
```typescript
import { SchemaKit } from '@mobtakronio/schemakit';
// PostgreSQL
const kit = new SchemaKit({
adapter: 'postgres',
config: {
host: 'localhost',
port: 5432,
database: 'mydb',
user: 'user',
password: 'password'
}
});
// MySQL
const kit = new SchemaKit({
adapter: 'mysql',
config: {
host: 'localhost',
port: 3306,
database: 'mydb',
user: 'user',
password: 'password'
}
});
// SQLite
const kit = new SchemaKit({
adapter: 'sqlite',
config: {
filename: './database.sqlite'
}
});
// Initialize the adapter (optional; lazy by default)
await kit.init();
```
- The previous in-memory adapter was removed to reduce complexity.
- For testing, prefer SQLite with `better-sqlite3` or Postgres.
You can create custom adapters by extending the `DatabaseAdapter` class. See the adapter documentation for details.