36 KiB
MetaBuilder
A data-driven, multi-tenant platform where 95% of functionality lives in JSON/Lua, not TypeScript. Build enterprise applications declaratively with a 6-level permission system.
📋 Ready to populate the kanban? See KANBAN_READY.md for a quick guide to populate the GitHub project board with 775 TODO items.
Table of Contents
- Quick Start
- Quick Overview
- Refactor Plan
- Architecture
- 6-Level Permission System
- Package System
- Database
- Multi-Tenant System
- Lua Scripting
- API Reference
- Testing
- Development
- Security
- Deployment
- Contributing
- Troubleshooting
- Key Files Reference
- Roadmap
Quick Start
# Clone and install
git clone <repo>
cd metabuilder/frontends/nextjs
npm install
# Set up database
npm run db:generate
npm run db:push
# Start development
npm run dev
Visit http://localhost:3000
Prerequisites
- Node.js 18+
- npm or yarn
- Docker (optional)
15-Minute Sanity Check
cd frontends/nextjs
npm ci
npm run typecheck
npm run lint
npm run test:unit -- --run
npm run build
Quick Overview
MetaBuilder is a data-driven, multi-tenant platform with these core features:
- 6-Level Permission System: Public → User → Moderator → Admin → God → Supergod hierarchy
- Multi-Tenant Data: All queries filter by
tenantId; each tenant has isolated config - Declarative Packages: Ship UI/features via JSON/Lua in
packages/*/seed/ - Lua Sandbox: Safe runtime execution with blocked system access
- Type-Safe Workflow: TypeScript, Act local CI, comprehensive testing
Refactor Plan
🚀 Auto Code Extractor 3000™ - Automated File Splitting
NEW: One-command solution to split large files (>150 LOC) into modular structure!
We have 62 files exceeding 150 lines. The Auto Code Extractor 3000™ automatically extracts functions into individual files following the lambda-per-file pattern.
Quick Commands
# Preview what will be extracted
npm run extract:preview
# Extract 5 files
npm run extract:quick
# Extract all high-priority files (automated)
npm run extract:auto
📖 Quick Start Guide | 📚 Full Documentation
Next.js to Lua Conversion TODO
Table of Contents
- TODOs by Phase
- Prep Checklist
- Audit Results
- Quick File References
- Next Steps
- Phase Deliverables
- Support Notes
- Tracking & Templates
- Package Design Notes
- Metadata Design Notes
TODOs by Phase
Phase 0 – Foundation
- Audit all
frontends/nextjs/src/entry points (pages, components, hooks, lib). Determine what goes to Lua. - Define the Lua boundary. List metadata, static, and seed assets plus their API surface.
Phase 1 – Mapping
- Map reusable TypeScript helpers to single-function Lua targets (one file, one function) and describe their inputs/outputs for future porting.
- Categorize each file as “port to Lua”, “adapter only”, or “keep in TypeScript”.
Phase 2 – Framework Bridge
- Extend the core framework only where gaps remain (data loading, metadata resolution, routing) with tiny TypeScript adapters to Lua if needed.
- Align metadata/seed folder structure with the requirements (consider
lua/orpackages/static_content) and add placeholder files.
Phase 3 – Pilot Conversion
- Pilot a TypeScript → Lua helper conversion (choose one small helper, wrap it with an adapter, and keep the rest of the build intact).
- Ensure the pilot is wired into the Next.js app without breaking the current build or tests.
Phase 4 – Stabilize
- Update documentation/tests to reflect the new Lua metadata focus and ensure existing CI steps continue to pass with the new structure.
- Iterate with feedback—confirm the team agrees on the folder layout, metadata ownership, and which TypeScript files stay as adapters.
Prep Checklist
- Confirm tooling (Lua runtime,
luacheck, etc.) is installed if needed before creating helpers. - Backup critical TypeScript files via comments or notes before starting ports.
- Share the plan with the team and gather quick approvals for folder names (
lua/,packages/static_content). - Identify one “safe” helper to convert first, ideally small and well-tested.
Audit Results
App surface
frontends/nextjs/src/apphas 40+ routes.- Each route needs metadata.
- Key files:
page.tsxlayout.tsxlevelstree- auth/dashboards
providers.tsxand theme hookspackages/[...path]/route.ts
- API handlers touch auth, users, packages, levels, power-transfers, GitHub actions, screenshot, and health.
- They depend on helpers under
frontends/nextjs/src/lib/api,lib/packages/loader,db, anddbal.
UI components
frontends/nextjs/src/componentsholds ~60 React files.- Builders:
BuilderLevel1,Level2,Level3,Level4,Level5NerdModeIDE
- Editors:
LuaEditorLuaBlocksEditorCodeEditorJsonEditorSchemaEditors
- Management views:
PackageManagerDatabaseManagerComponentCatalogWorkflowEditor
- Integrations and tools:
GitHubActionsFetcherIRCWebchatvariantsDBALDemoUnifiedLogin
- Atoms, molecules, and organisms live in nested folders. We will tag each file in Phase 1.
Hooks & libraries
- Hooks:
useAuthuseAutoRefreshuseKVuseLevelRoutinguseDBALuseFileTreeuseCodeEditoruseResolvedUseruseGitHubFetcheruse-mobilehooks/authstorehooks/use-dbalhelpers (blob storage, kv store, cached data)
- Libraries cover:
- auth and security (
lib/auth,lib/security) - database and DBAL helpers
- package, seed, and metadata tooling (
lib/packages,lib/seed) - Lua engine and functions
- workflow and rendering helpers
- API helpers and schema utilities
- GitHub and general utilities (
lib/utils,lib/prisma)
- auth and security (
- Phase 1 will tag each file as “adapter” or “port”.
Supporting assets
frontends/nextjs/src/seed-datahas JSON seeds for packages and baseline data. These can move to metadata.- Tests live in
app/api/*/*.test.tsx,lib/**/*test.ts,components/get-component-icon.test.tsx, andhooks/*.test.ts. We will decide which tests follow Lua stubbed logic or stay with TypeScript.
Quick File References
frontends/nextjs/src/app: each route, page, provider, and API handler needs metadata or a Lua adapter.frontends/nextjs/src/components: move builders, editors, and managers to metadata-driven definitions.frontends/nextjs/src/hooks: turn each hook into a Lua micro-function.frontends/nextjs/src/lib: catalogue auth, security, db/DBAL, packages, Lua, workflow, API, schema, GitHub, and utility modules.- Supporting assets: seed JSONs, README docs, and tests must align with the Lua transition.
God Panel / Package Mapping Notes
- Level 4’s
Level4Tabsexposes a “Packages” tab that rendersPackageManager, so God-level users open that tab when they need to install, enable, or disable packages (frontends/nextjs/src/components/level4/Level4Tabs.tsx). PackageManagerloads the catalog fromPACKAGE_CATALOG, shows installed/available packages, and calls APIs (installPackage,togglePackageEnabled,uninstallPackage,listInstalledPackages) that persist package state (frontends/nextjs/src/components/PackageManager.tsx).PACKAGE_CATALOGlives infrontends/nextjs/src/lib/packages/package-catalog.tsand contains the manifest content (schemas, pages, workflows, Lua scripts, seed data) that the God panel presents when a package is selected.- The reusable packages under
packages/follow the structure described inpackages/README.md: each package hasseed/metadata.json,components.json, and optionalstatic_content/examples.json, so new package metadata can align with whatPackageManagerexpects. - Default packages are enumerated in
frontends/nextjs/src/lib/packages/package-glue/default-packages.ts(admin_dialog, dashboard, forum_forge, etc.), and God panel UI relies on those definitions to match catalog entries with metadata stored inpackages/.
Next Steps
- Create the companion metadata folder (e.g.,
lua/orpackages/static_content) with placeholder single-function files that mirror the above references. - Run the audit across the identified folders. Mark each file as “port to Lua”, “adapter only”, or “leave in TypeScript” before editing.
Phase Deliverables
- Phase 0: Audit spreadsheet/list with tags for each entry. Lua boundary doc with endpoints and metadata goals.
- Phase 1: Mapping sheet (spreadsheet or Markdown) documenting TypeScript helper → Lua micro-function mapping and file categorization.
- Phase 2: Adapter interface stubs plus placeholder Lua files under the new metadata folder.
- Phase 3: One working Lua helper wired through an adapter, with updated unit test coverage or manual verification notes.
- Phase 4: Documentation updates, test run results, and a summary of which files moved versus stayed.
Support Notes
-
Risks: The Next.js frontend is large; do not remove TypeScript pages until their Lua replacements exist. Keep unit/e2e tests running in TypeScript during transition.
-
Owner: Track who updates each phase and keep a note in this doc or comments for accountability.
-
Validation tips: After a Lua helper is added, run
npm run lintandnpm run test:unitfromfrontends/nextjs/. Keep logs of failing tests if you defer them. -
Documentation: Update READMEs in
components/,hooks/, andlib/with pointers to the new Lua package once core content moves. -
Checkpoint: Before Phase 3, ensure adapter interfaces exist for data access and that seed data has been migrated to the metadata folder.
-
Toolbelt
npm run lint(infrontends/nextjs/)npm run test:unitnpm run test:e2e(only after Lua helpers are wired)npm run buildto verify core app still compiles
-
Folder sketch
lua/metadata/– metadata + seed descriptors per packagelua/functions/– single-function files (one helper per file)lua/adapters/– TypeScript adapters that relay calls into Lua micro-functionspackages/static_content/– optional storage for JSON seeds already living in the frontend
Tracking & Templates
- Audit table:
- File path
- Current role (page, API, hook, lib)
- Port target (Lua, adapter, stay TS)
- Notes/risks
- Owner/ETA
- Mapping sheet:
- Helper name
- Inputs/outputs
- Proposed Lua file path
- Adapter needed (yes/no)
- Test expectations
Lua Conversion & God Panel Mapping
- God-level builders (Level 4 tabs) expose the
PackageManagerUI where admins install, enable, and disable packages (Level4Tabs→PackageManagerinfrontends/nextjs/src/components). PackageManagerloadsPACKAGE_CATALOG, drives the install/toggle APIs, and feeds catalog entries back into the God panel (frontends/nextjs/src/lib/packages/package-catalog.tsandfrontends/nextjs/src/components/PackageManager.tsx).- Catalog metadata mirrors the
packages/*/seed/metadata.jsonformat described inpackages/README.md; new packages must follow that structure (metadata, components, optional static content) so the God panel can surface them. - Default package metadata is pre-defined under
frontends/nextjs/src/lib/packages/package-glue/default-packages.ts(admin_dialog, dashboard, forum_forge, etc.) to keep UI, Lua loaders, and catalog definitions aligned.
Package Design Notes
- Keep packages lean: each folder under
packages/should containseed/, optionalstatic_content/, and light JSON/metadata entries. - Store metadata (name, version, packageId) in
seed/metadata.json; keeppackageIdsnake_case and version semver. - Avoid coupling packages to UI; they should expose data scripts for Lua/metadata consumers.
- Use
package/gluelogic infrontends/nextjs/src/lib/packagesas reference when designing new packages so metadata matches runtime expectations. - Document every package’s dependencies and optional scripts so Lua adapters can load/distribute them predictably.
Metadata Design Notes
- Define metadata per route/component via JSON tables describing inputs, outputs, Lua helper references, and UI states.
- Keep metadata separate from implementation; store static descriptors in
lua/metadata/*and reference them via adapters. - Version metadata files to make rollbacks easier and ensure seeds stay synchronized with database migrations.
- Use small, focused metadata files so the single-function Lua helpers can import only the data they need.
- Track metadata ownership (which team, file) inside each descriptor to simplify future audits.
Reference Resources
- AGENTS.md: follow repo guidelines and nested agent notes before touching
dbal/or other special folders. - UI_STANDARDS.md: reference for UI design rules while documenting Lua metadata that may affect styling.
- packages/: inspect existing JSON-driven package structure for inspiration (seed/metadata.json, static_content/).
- tools/: reuse scripts from this folder when building new metadata loaders or conversion helpers.
- frontends/nextjs/src/lib/packages/package-glue/: examine default packages and loaders to keep Lua metadata compatible.
Decision Log
- Document every key decision (phase changes, Lua structure choices, package additions) below with date/owner for easy onboarding.
- [date] - [owner] - [decision summary]
- ...
Collaboration Notes
- Post updates to this doc before merging any changes, especially new folder names or metadata formats.
- Tag @owner in relevant PR comments when handing off a phase or requesting review.
Architecture
MetaBuilder combines:
- Declarative Components: Render UIs from JSON using
RenderComponent - DBAL: TypeScript SDK + C++ daemon, language-agnostic via YAML contracts
- Package System: Self-contained modules in
/packages/{name}/seed/ - Multi-Tenancy: All queries filter by
tenantId
Project Structure
metabuilder/
├── frontends/nextjs/ # Next.js application
│ ├── src/
│ │ ├── app/ # App routes and pages
│ │ ├── components/ # React components (Atomic Design)
│ │ │ ├── atoms/ # Basic UI elements
│ │ │ ├── molecules/ # Simple composites (2-5 atoms)
│ │ │ ├── organisms/ # Complex features with business logic
│ │ │ └── level1-5/ # Page-level components
│ │ ├── lib/ # Core libraries
│ │ ├── hooks/ # Custom React hooks
│ │ ├── seed-data/ # Database seeds
│ │ ├── theme/ # MUI theme configuration
│ │ └── types/ # TypeScript type definitions
│ └── e2e/ # Playwright E2E tests
├── packages/ # Feature packages (JSON/Lua-driven)
├── dbal/ # Database Abstraction Layer
│ ├── ts/ # TypeScript implementation
│ ├── cpp/ # C++ daemon (production)
│ │ ├── src/ # Source code
│ │ ├── include/ # Header files
│ │ ├── build-config/ # CMake, Docker configs
│ │ ├── lint-config/ # Clang format/tidy configs
│ │ └── docs/ # Implementation docs
│ ├── api/ # YAML contracts
│ └── docs/ # DBAL documentation
├── prisma/ # Database schema & migrations
├── config/ # Shared configuration
│ ├── build/ # Next.js, TypeScript configs
│ ├── lint/ # ESLint config
│ ├── test/ # Vitest, Playwright configs
│ └── misc/ # Other configs (JSON, env)
├── tools/ # Repository utilities
│ ├── analysis/ # Code analysis scripts
│ ├── detection/ # Stub/pattern detection
│ ├── generation/ # Code generation
│ ├── quality/ # Quality metrics
│ ├── security/ # Security scanning
│ └── validation/ # Validation scripts
├── docs/ # Documentation
│ ├── architecture/ # System design docs
│ ├── guides/ # How-to guides
│ ├── security/ # Security documentation
│ ├── todo/ # Task tracking
│ └── navigation/ # Doc navigation files
├── deployment/ # Docker configs
└── .github/ # GitHub workflows & prompts
├── workflows/ # CI/CD pipelines
└── prompts/ # AI prompt templates
Component Architecture (Atomic Design)
| Layer | Examples | Rules |
|---|---|---|
| Atoms | Button, Input, Badge | No custom dependencies |
| Molecules | AppHeader, ProfileCard | Can use Atoms only |
| Organisms | SchemaEditor, PackageManager | Can use Atoms, Molecules, other Organisms |
| Pages | Level1-5 | Can use all |
6-Level Permission System
Hierarchical access control where each level inherits all permissions from lower levels:
| Level | Role | Access | Route |
|---|---|---|---|
| 1 | Public | Read-only, unauthenticated | / |
| 2 | User | Personal dashboard, content creation | /dashboard |
| 3 | Moderator | Moderation desk, flag review, report handling | /moderator |
| 4 | Admin | User management, system settings | /admin |
| 5 | God | Workflows, advanced scripting, packages | /builder |
| 6 | Supergod | Full system control, tenant management | /supergod |
The new Level 3 moderator desk (/moderator) is protected by AuthGate with requiredRole="moderator" and surfaces flagged discussions, incident reports, and quick actions before escalation to admin.
Permission Matrix
| Feature | L1 | L2 | L3 | L4 | L5 | L6 |
|---|---|---|---|---|---|---|
| View Public Data | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Authenticate | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Create Content | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Moderate Content | ✓ | ✓ | ✓ | ✓ | ||
| Manage Users | ✓ | ✓ | ✓ | |||
| Run Workflows | ✓ | ✓ | ||||
| System Configuration | ✓ |
Usage
import { canAccessLevel } from '@/lib/auth'
import { useAuth } from '@/hooks'
export const AdminPanel = () => {
const { user } = useAuth()
if (!canAccessLevel(user.level, 4)) {
return <AccessDenied />
}
return <AdminContent />
}
// Multiple conditional features
const features = {
basicDashboard: true,
contentEditor: user.level >= 2,
moderationDesk: user.level >= 3,
userManagement: user.level >= 4,
workflowEngine: user.level >= 5,
systemConfig: user.level === 6,
}
Backend Route Protection
import { validateRequest } from '@/lib/auth'
export async function POST(req: Request) {
const user = await validateRequest(req)
if (!canAccessLevel(user.level, 4)) {
return Response.json({ error: 'Forbidden' }, { status: 403 })
}
return handleAdminOperation(req)
}
Package System
Self-contained feature modules with seed data, components, and Lua scripts.
Structure
packages/{name}/
├── seed/
│ ├── metadata.json # Package info
│ ├── components.json # Component definitions
│ ├── workflows.ts # Workflow definitions
│ ├── schemas.ts # Data schemas
│ └── scripts/ # Lua scripts
│ ├── initialize.lua
│ └── helpers.lua
├── src/ # React components (optional)
│ ├── components/
│ ├── lib/
│ └── hooks/
├── styles/ # SCSS styles
└── static_content/ # Assets (images, templates)
Package Metadata
{
"name": "@metabuilder/my-feature",
"version": "1.0.0",
"metabuilder": {
"type": "feature",
"minVersion": "1.0.0",
"permissions": ["level3"],
"components": [
{ "name": "MyComponent", "path": "src/components/MyComponent.tsx", "type": "widget" }
]
}
}
Available Packages
| Package | Description |
|---|---|
admin_dialog |
Admin utilities |
arcade_lobby |
Games arcade |
codegen_studio |
Code generation tools |
dashboard |
Dashboard widgets |
data_table |
Data table component |
form_builder |
Form creation tools |
forum_forge |
Forum system |
nav_menu |
Navigation menus |
notification_center |
Notifications |
social_hub |
Social features |
spark-tools |
Development tools |
stream_cast |
Streaming features |
Creating a Package
mkdir -p packages/my-feature/seed/scripts
mkdir -p packages/my-feature/src/{components,lib,hooks}
// packages/my-feature/seed/index.ts
export const packageSeed = {
name: '@metabuilder/my-feature',
version: '1.0.0',
components: [],
workflows: [],
}
Database
Prisma ORM
Schema: prisma/schema.prisma
npm run db:generate # Generate Prisma client
npm run db:push # Apply schema changes
npm run db:migrate # Create migration
npm run db:studio # Open database UI
npm run db:reset # Reset database (destructive!)
Schema Example
model User {
id String @id @default(cuid())
email String @unique
password String
level Int // 1-5
tenant Tenant @relation(fields: [tenantId], references: [id])
tenantId String
workflows Workflow[]
@@unique([email, tenantId])
}
model Workflow {
id String @id @default(cuid())
name String
config String @db.Text
user User @relation(fields: [userId], references: [id])
userId String
tenantId String
}
CRUD Operations
// Create
const newUser = await prisma.user.create({
data: {
email: 'user@example.com',
password: hashPassword('password'),
level: 2,
tenant: { connect: { id: tenantId } },
},
})
// Read
const workflows = await prisma.workflow.findMany({
where: { tenantId: user.tenantId, status: 'active' },
orderBy: { createdAt: 'desc' },
take: 10,
})
// Update
const updated = await prisma.user.update({
where: { id: userId },
data: { level: 3 },
})
// Delete
await prisma.user.delete({ where: { id: userId } })
// Transaction
const result = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData })
const workflow = await tx.workflow.create({
data: { ...workflowData, userId: user.id }
})
return { user, workflow }
})
DBAL (Database Abstraction Layer)
For complex operations:
- TypeScript (
dbal/development/): Fast iteration, development - C++ Daemon (
dbal/production/): Production security, credential protection
import { dbalQuery } from '@/lib/database-dbal.server'
const result = await dbalQuery({
operation: 'transfer_workflow',
from: user1Id,
to: user2Id,
})
Multi-Tenant System
Complete isolation with access control, quotas, and namespace separation.
Initialize Tenant
import { InMemoryTenantManager, TenantAwareBlobStorage } from './dbal/development/src'
const tenantManager = new InMemoryTenantManager()
await tenantManager.createTenant('tenant-123', {
maxBlobStorageBytes: 1024 * 1024 * 1024, // 1GB
maxBlobCount: 10000,
maxRecords: 100000,
})
Tenant-Aware Storage
const tenantStorage = new TenantAwareBlobStorage(
baseStorage,
tenantManager,
'tenant-123',
'user-456'
)
// Automatically scoped to tenant namespace
await tenantStorage.upload('documents/report.pdf', pdfBuffer)
// Actual key: tenants/tenant-123/documents/report.pdf
Key-Value Store
const kvStore = new InMemoryKVStore()
const context = await tenantManager.getTenantContext('tenant-123', 'user-456')
await kvStore.set('config:theme', 'dark', context)
await kvStore.set('user:profile', { name: 'John' }, context)
// Lists
await kvStore.listAdd('tasks', ['Task 1', 'Task 2'], context)
const tasks = await kvStore.listGet('tasks', context)
Access Control
tenantManager.setUserRole('tenant-123', 'user-admin', 'admin')
tenantManager.setUserRole('tenant-123', 'user-viewer', 'viewer')
// Viewer can only read
const viewerContext = await tenantManager.getTenantContext('tenant-123', 'user-viewer')
await kvStore.get('data', viewerContext) // ✅ Success
await kvStore.set('data', 'new', viewerContext) // ❌ Permission denied
Quota Management
const usage = await tenantManager.getUsage('tenant-123')
console.log({
blobStorage: `${usage.currentBlobStorageBytes} / ${usage.maxBlobStorageBytes}`,
records: `${usage.currentRecords} / ${usage.maxRecords}`,
})
Lua Scripting
Business logic without code redeployment. Scripts run in isolated sandbox.
Sandbox Restrictions
- ❌ No
os,io,require,loadfile,dofile - ❌ No file system access
- ❌ 5-second execution timeout
- ✅ String manipulation, math, tables
Example Scripts
-- Validation
function validateEmail(email)
return string.match(email, "^[^@]+@[^@]+$") ~= nil
end
-- Data transformation
function formatCurrency(amount)
return string.format("$%.2f", amount)
end
-- Business rules
function calculateDiscount(total, memberLevel)
if memberLevel >= 3 then
return total * 0.15
elseif memberLevel >= 2 then
return total * 0.10
end
return 0
end
Executing Lua
import { executeLua } from '@/lib/lua-sandbox'
const result = await executeLua(luaCode, {
db: database,
user: currentUser,
config: packageConfig,
})
API Reference
Authentication
// POST /api/auth/login
{ email: string, password: string }
// Returns: { user: User, token: string }
// POST /api/auth/register
{ email: string, username: string }
// Returns: { user: User } (password emailed)
// POST /api/auth/reset-password
{ email: string }
// Returns: { success: boolean }
Users
// GET /api/users
// Returns: User[]
// GET /api/users/:id
// Returns: User
// PATCH /api/users/:id (Level 3+)
{ level?: number, email?: string }
// Returns: User
Packages
// GET /api/packages
// Returns: Package[]
// POST /api/packages/install (Level 4+)
{ packageId: string }
// Returns: { success: boolean }
// DELETE /api/packages/:id (Level 4+)
// Returns: { success: boolean }
Workflows
// GET /api/workflows
// Returns: Workflow[]
// POST /api/workflows (Level 4+)
{ name: string, config: object }
// Returns: Workflow
// POST /api/workflows/:id/execute (Level 4+)
{ input?: object }
// Returns: { result: any }
Testing
Commands
# From frontends/nextjs/
npm run test:unit # Vitest unit tests
npm run test:unit -- --run # Run once (no watch)
npm run test:unit -- --coverage # With coverage
npm run test:e2e # Playwright E2E tests
npm run lint # ESLint
npm run typecheck # TypeScript validation
Test File Structure
src/lib/utils.ts → src/lib/utils.test.ts
src/hooks/useKV.ts → src/hooks/useKV.test.ts
src/components/Button.tsx → src/components/Button.test.tsx
Parameterized Tests
import { describe, it, expect } from 'vitest'
describe('validateField', () => {
it.each([
{ field: { type: 'email' }, value: 'test@example.com', shouldError: false },
{ field: { type: 'email' }, value: 'invalid', shouldError: true },
{ field: { type: 'number', min: 0 }, value: -1, shouldError: true },
])('validates $field.type with $value', ({ field, value, shouldError }) => {
const result = validateField(field, value)
expect(!!result).toBe(shouldError)
})
})
React Hook Tests
import { renderHook, act } from '@testing-library/react'
describe('useIsMobile', () => {
it.each([
{ width: 400, expected: true },
{ width: 768, expected: false },
])('returns $expected for width $width', ({ width, expected }) => {
window.innerWidth = width
const { result } = renderHook(() => useIsMobile())
expect(result.current).toBe(expected)
})
})
Local CI Testing
npm run act # Full CI pipeline locally
npm run act:lint # Test linting only
npm run act:build # Test build only
npm run act:diagnose # Check setup (no Docker)
Act Modes
| Mode | Command | Description |
|---|---|---|
| Full CI | npm run act |
Complete workflow |
| Lint only | npm run act:lint |
Just linting |
| Build only | npm run act:build |
Just build |
| Diagnose | npm run act:diagnose |
Check setup |
Development
Scripts
# Development
npm run dev # Start dev server
npm run build # Production build
npm run preview # Preview production build
# Quality
npm run lint # Check code
npm run lint:fix # Auto-fix issues
npm run typecheck # TypeScript check
Code Conventions
| Rule | Details |
|---|---|
| UI Library | Material-UI (@mui/material) with sx prop |
| No Tailwind | Use MUI or .module.scss |
| No Radix UI | MUI equivalents only |
| One lambda per file | Classes only as containers |
| Imports | Absolute @/ paths |
| Components | Functional with hooks |
| Tests | 1:1 source-to-test naming |
Component Example
import { Box, Button } from '@mui/material'
interface MyComponentProps {
title: string
onAction: () => void
}
export const MyComponent = ({ title, onAction }: MyComponentProps) => {
return (
<Box sx={{ display: 'flex', gap: 2, p: 3 }}>
<h1>{title}</h1>
<Button variant="contained" onClick={onAction}>
Action
</Button>
</Box>
)
}
Generic Component Rendering
// ✅ Declarative
<RenderComponent component={{
type: 'form',
props: { schema: formSchema },
children: [/* field components */]
}} />
// ❌ Hardcoded
<UserForm user={user} onSave={handleSave} />
Security
Password Hashing
SHA-512 for all credentials:
import { hashPassword, verifyPassword } from '@/lib/password-utils'
const hash = hashPassword('mypassword')
const isValid = verifyPassword('mypassword', hash)
Lua Sandbox
Scripts cannot access system resources:
-- ❌ These are blocked
os.execute('rm -rf /')
io.open('/etc/passwd')
require('socket')
-- ✅ These work
local result = string.match(input, pattern)
local sum = a + b
Security Scanning
Code is automatically scanned for:
| Category | Patterns |
|---|---|
| JavaScript | eval(), innerHTML, XSS patterns, prototype pollution |
| Lua | os/io module usage, infinite loops, global manipulation |
| JSON | __proto__ injection, script tags |
Critical severity blocks execution. High severity requires acknowledgment.
Best Practices
- ✅ Always filter queries by
tenantId - ✅ Validate all user input
- ✅ Use transactions for related operations
- ✅ Hash passwords with SHA-512
- ❌ Never trust client-side permission checks
- ❌ Don't allow users to modify their own level
- ❌ Don't store secrets in database
Deployment
Docker
# Development
docker-compose -f deployment/docker-compose.development.yml up
# Production
docker-compose -f deployment/docker-compose.production.yml up
Environment Variables
# Development (SQLite)
DATABASE_URL="file:./dev.db"
# Production (PostgreSQL)
DATABASE_URL="postgresql://user:password@host:5432/metabuilder"
# Optional
NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api.example.com
Production Build
npm run build
npm run start
Contributing
Reporting Issues
MetaBuilder uses structured issue templates to ensure quality bug reports and feature requests:
- 🐛 Bug Report: Report bugs with environment details and reproduction steps
- ✨ Feature Request: Propose features aligned with data-driven architecture
- 📚 Documentation: Request documentation improvements
- 📦 Package Request: Propose new packages for the package system
- 🔧 DBAL Issue: Report Database Abstraction Layer issues
See .github/TEMPLATES.md for detailed guidance on using templates.
Workflow
- Follow
.github/copilot-instructions.mdand.github/prompts/0-kickstart.md - Run
npm run lint:fixbefore committing - Add parameterized tests for new functions
- Commit with descriptive messages on
main
Before Committing
npm run lint
npm run typecheck
npm run test:unit -- --run
Code Quality Targets
- 80%+ test coverage on critical paths
- All exported functions have tests
- JSDoc comments on public APIs
Pull Request Process
PRs are optional (trunk-based on main is default). When required:
- Use the comprehensive PR template (auto-populated)
- Complete all sections and checklists
- Include screenshots for UI changes
- Run linter and tests
- Update documentation
- Add test cases
- Use descriptive PR title
See .github/TEMPLATES.md for the complete PR checklist and MetaBuilder-specific guidelines.
Troubleshooting
Common Issues
| Problem | Solution |
|---|---|
| Port in use | npm run dev -- --port 5174 |
| Database connection failed | Check DATABASE_URL, run npm run db:push |
| TypeScript errors | Run npm run db:generate |
| Prisma client outdated | Run npm run db:generate |
| Build fails | Check npm run typecheck output |
Debug Commands
# View database
npm run db:studio
# Check migrations
ls prisma/migrations/
# Verbose logging
DEBUG=metabuilder:* npm run dev
If Something Fails
| Issue Type | Check |
|---|---|
| Build/config | Run sanity check above |
| Next.js app | Check terminal for errors |
| Prisma/DB | Run npm run db:generate && npm run db:push |
| Tests | Run npm run test:unit -- --run |
Key Files Reference
| Purpose | Location |
|---|---|
| App source | frontends/nextjs/src/ |
| Database schema | prisma/schema.prisma |
| Package seeds | packages/*/seed/ |
| DBAL TypeScript | dbal/development/src/ |
| DBAL C++ | dbal/production/src/ |
| E2E tests | frontends/nextjs/e2e/ |
| Shared config | config/ |
| Analysis tools | tools/analysis/ |
| Security tools | tools/security/ |
| Development prompts | .github/prompts/ |
| CI workflows | .github/workflows/ |
Roadmap
Current Phase: Foundation & Migration
| Status | Milestone | Target |
|---|---|---|
| ✅ | Multi-tenant architecture | Complete |
| ✅ | 6-level permission system | Complete |
| ✅ | Package system with JSON/Lua | Complete |
| ✅ | DBAL TypeScript SDK | Complete |
| 🔄 | Next.js to Lua conversion | In Progress |
| 🔄 | C++ DBAL daemon (production) | In Progress |
| ⏳ | Full Lua business logic | Q1 2025 |
| ⏳ | Package marketplace | Q2 2025 |
Future Goals
- Q1 2025: Complete Lua conversion for 95% of frontend logic
- Q2 2025: Launch package marketplace for community packages
- Q3 2025: Self-hosted deployment templates (Docker, K8s)
- Q4 2025: Enterprise features (SSO, audit logs, advanced analytics)
Contributing to Roadmap
See the Refactor Plan section for detailed phase breakdowns and how to contribute.
License
MIT License - See LICENSE file