mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
- Deleted all LuaScript CRUD operations from Client and entities. - Removed LuaScript validation functions and related files. - Updated InMemoryStore to remove LuaScript storage. - Cleaned up tests by removing LuaScript related test cases. - Adjusted documentation and quick start guide to reflect the removal of LuaScript functionality.
8.5 KiB
8.5 KiB
DBAL Quick Start Guide
What is Phase 2?
Phase 2 implements a complete, production-ready Database Abstraction Layer (DBAL) that:
- ✅ Works entirely in GitHub Spark (no external services needed)
- ✅ Provides ACL (access control) and audit logging
- ✅ Prepares for future C++ daemon integration
- ✅ Adds ~1ms overhead vs direct database access
- ✅ Type-safe, error-handled, fully documented
Quick Start (5 minutes)
1. Install Dependencies
The DBAL uses Prisma, which is already installed in MetaBuilder:
# Already done - Prisma is in package.json
2. Import the DBAL Client
import { getDBALClient } from '@/lib/dbal-client'
import type { User } from '@/lib/level-types'
// Get client (with or without user context)
const client = getDBALClient()
// Or with authentication (enables ACL)
const client = getDBALClient(currentUser, {
id: 'session_123',
token: 'abc'
})
3. Use CRUD Operations
// Create
const user = await client.users.create({
username: 'alice',
email: 'alice@example.com',
role: 'user'
})
// Read
const foundUser = await client.users.read(user.id)
// Update
await client.users.update(user.id, {
email: 'alice.new@example.com'
})
// List with filters
const admins = await client.users.list({
filter: { role: 'admin' },
sort: { createdAt: 'desc' },
limit: 20
})
// Delete
await client.users.delete(user.id)
4. Handle Errors
import { DBALError, DBALErrorCode } from '../../dbal/development/src'
try {
await client.users.read('nonexistent_id')
} catch (error) {
if (error instanceof DBALError) {
switch (error.code) {
case DBALErrorCode.NOT_FOUND:
toast.error('User not found')
break
case DBALErrorCode.FORBIDDEN:
toast.error('Access denied')
break
default:
toast.error('Database error')
}
}
}
Key Features
🔒 Security (ACL)
Automatic role-based access control:
// User with role 'user' can only read/update their own records
const client = getDBALClient(currentUser, session)
await client.users.update(currentUser.id, { email: 'new@example.com' }) // ✅ OK
await client.users.update(otherUser.id, { email: 'new@example.com' }) // ❌ Forbidden
// God/SuperGod can access all records
const client = getDBALClient(godUser, session)
await client.users.update(anyUser.id, { email: 'new@example.com' }) // ✅ OK
📝 Audit Logging
All operations are logged automatically:
{
"timestamp": "2024-01-15T10:30:00.000Z",
"user": "alice",
"role": "admin",
"entity": "User",
"operation": "create",
"success": true
}
Check browser console for [DBAL Audit] logs.
🎯 Type Safety
Full TypeScript support:
import type { User, PageConfig, ComponentNode, Workflow, InstalledPackage, Session } from '../../dbal/development/src'
// Type-safe entities
const user: User = await client.users.create({ ... })
const page: PageConfig = await client.pageConfigs.create({ ... })
const component: ComponentNode = await client.componentNodes.create({ ... })
const workflow: Workflow = await client.workflows.create({ ... })
const pkg: InstalledPackage = await client.installedPackages.create({ ... })
const session: Session = await client.sessions.create({ ... })
// Type-safe list results
const result = await client.users.list()
const users: User[] = result.data
const total: number = result.total
const hasMore: boolean = result.hasMore
Available Operations
Users
client.users.create(data)
client.users.read(id)
client.users.update(id, data)
client.users.delete(id)
client.users.list(options)
Pages
client.pageConfigs.create(data)
client.pageConfigs.read(id)
client.pageConfigs.readByPath(path) // Special: find by path
client.pageConfigs.update(id, data)
client.pageConfigs.delete(id)
client.pageConfigs.list(options)
Components
client.componentNodes.create(data)
client.componentNodes.read(id)
client.componentNodes.update(id, data)
client.componentNodes.delete(id)
client.componentNodes.getTree(pageId) // Special: get all components for a page
Workflows
client.workflows.create(data)
client.workflows.read(id)
client.workflows.update(id, data)
client.workflows.delete(id)
client.workflows.list(options)
Packages
client.installedPackages.create(data)
client.installedPackages.read(packageId)
client.installedPackages.update(packageId, data)
client.installedPackages.delete(packageId)
client.installedPackages.list(options)
Sessions (system-only)
client.sessions.create(data)
client.sessions.read(id)
client.sessions.update(id, data)
client.sessions.delete(id)
client.sessions.list(options)
Common Patterns
List with Pagination
const result = await client.users.list({
filter: { role: 'admin' },
sort: { createdAt: 'desc' },
page: 1,
limit: 20
})
console.log(`Showing ${result.data.length} of ${result.total} users`)
if (result.hasMore) {
console.log('More results available')
}
Conditional ACL
// Disable ACL for system operations
const systemClient = getDBALClient() // No user context
// Enable ACL for user operations
const userClient = getDBALClient(currentUser, session)
Check Capabilities
const capabilities = await client.capabilities()
if (capabilities.transactions) {
// Use transactions
}
if (capabilities.fullTextSearch) {
// Use full-text search
}
Migration from Current Code
Before (Direct Database)
import { Database } from '@/lib/database'
const users = await Database.getUsers()
const user = await Database.getUserById(id)
await Database.addUser(newUser)
await Database.updateUser(id, updates)
await Database.deleteUser(id)
After (DBAL)
import { getDBALClient } from '@/lib/dbal-client'
const client = getDBALClient()
const result = await client.users.list()
const users = result.data
const user = await client.users.read(id)
await client.users.create(newUser)
await client.users.update(id, updates)
await client.users.delete(id)
Configuration
Development Mode (default)
const client = new DBALClient({
mode: 'development', // Direct database access
adapter: 'prisma',
auth: { user, session },
security: {
sandbox: 'strict', // Enable ACL
enableAuditLog: true // Enable logging
}
})
Production Mode (future)
const client = new DBALClient({
mode: 'production', // Connect to C++ daemon
endpoint: 'wss://daemon.example.com:50051',
auth: { user, session },
security: {
sandbox: 'strict',
enableAuditLog: true
}
})
Performance
| Operation | Time | Notes |
|---|---|---|
| Create | ~3ms | +0.5ms ACL overhead |
| Read | ~2.5ms | +0.5ms ACL overhead |
| Update | ~3ms | +1ms (ACL check + audit) |
| Delete | ~2.5ms | +1ms (ACL check + audit) |
| List (20) | ~5ms | +0.5ms ACL overhead |
Total overhead: ~0.5-1ms per operation
Troubleshooting
"Entity not found" error
The entity name must match the Prisma model name:
// ✅ Correct
await client.users.create(...) // Maps to User model
// ❌ Wrong
await client.Users.create(...) // Capital U won't work
ACL denies operation
Check user role and entity permissions:
// User role 'user' cannot create other users
const client = getDBALClient(regularUser, session)
await client.users.create({ ... }) // ❌ Forbidden
// But can update their own record
await client.users.update(regularUser.id, { ... }) // ✅ OK
Timeout errors
Increase query timeout:
const client = new DBALClient({
mode: 'development',
adapter: 'prisma',
performance: {
queryTimeout: 60000 // 60 seconds
}
})
Next Steps
- Try it out: Use DBAL in a new component
- Migrate gradually: Replace Database calls one at a time
- Monitor logs: Check browser console for audit logs
- Test ACL: Try operations with different user roles
- Read docs: See
PHASE2_IMPLEMENTATION.mdfor details
Need Help?
- 📖 Full docs:
dbal/PHASE2_IMPLEMENTATION.md - 🏗️ Architecture:
dbal/README.md - 🚀 Future:
dbal/production/PHASE3_DAEMON.md - 🤖 AI Agent guide:
dbal/AGENTS.md
Summary
Phase 2 DBAL is ready to use right now in MetaBuilder:
- ✅ Complete TypeScript implementation
- ✅ ACL and audit logging
- ✅ Type-safe APIs
- ✅ Minimal overhead
- ✅ GitHub Spark compatible
- ✅ Prepares for Phase 3 C++ daemon
Just import, use, and enjoy! 🎉