diff --git a/content/docs/cn/index.mdx b/content/docs/cn/index.mdx index 7f984c2..c806fd6 100644 --- a/content/docs/cn/index.mdx +++ b/content/docs/cn/index.mdx @@ -1,16 +1,260 @@ --- -title: 欢迎 -description: 欢迎访问 ObjectStack 文档 +title: ObjectStack 规范 +description: 协议驱动、本地优先、数据库无关的全栈开发平台 --- -# 欢迎访问 ObjectStack +# ObjectStack 平台规范 -ObjectStack 是一个综合性平台,提供强大的工具和框架来构建现代应用程序。 +**ObjectStack** 是一个协议驱动的全栈开发平台,通过标准化的 JSON 协议将业务逻辑与技术实现分离。它使开发者能够构建可移植的、数据库无关的应用程序,并实现完全的数据主权。 -## 我们的产品 +## 核心架构原则 -我们提供三个核心产品,旨在简化您的开发工作流程: +ObjectStack 建立在三个不可动摇的支柱之上: -- **ObjectUI**:现代化的 UI 组件库,用于构建美观且响应式的用户界面 -- **ObjectQL**:强大的查询语言和数据访问层,用于高效的数据操作 -- **ObjectOS**:操作系统框架,为构建可扩展应用程序提供基础 +### 1. 协议驱动架构 +逻辑存在于**声明式协议**(JSON)中,而非命令式代码中。业务定义是数据,而非函数。这使得: +- **可移植性**:协议与语言和框架无关 +- **可组合性**:从简单的声明式块构建复杂系统 +- **AI 生成**:从协议规范生成 80% 的应用代码 +- **版本控制**:将业务逻辑作为结构化数据进行版本管理 + +### 2. 本地优先设计 +应用程序**默认离线工作**。云连接是可选的,而非强制的。这确保了: +- **数据主权**:用户拥有数据,而非平台 +- **零供应商锁定**:数据可导出为标准格式(.oos、.json) +- **默认隐私**:无需遥测或云依赖 +- **弹性**:应用程序在无网络连接时也能运行 + +### 3. 数据库无关 +一次编写,在**任何数据库**上运行。ObjectQL 完全抽象了数据层: +- **跨数据库协议**:MySQL、PostgreSQL、Oracle、SQLite、SQL Server 使用统一查询语法 +- **零迁移成本**:切换数据库无需更改应用代码 +- **方言抽象**:引擎处理特定数据库的 SQL 生成 +- **统一驱动接口**:无论底层存储如何,API 都保持一致 + +--- + +## 平台组件 + +ObjectStack 由三个解耦的引擎组成,它们通过标准化的 JSON 协议进行通信: + +```mermaid +graph TB + subgraph "应用层" + App[您的应用程序] + end + + subgraph "ObjectStack 平台" + OS[ObjectOS
运行时与编排] + UI[ObjectUI
声明式 UI 引擎] + QL[ObjectQL
数据协议引擎] + end + + subgraph "基础设施层" + DB[(数据库
MySQL/PG/Oracle/SQLite)] + Renderer[UI 渲染器
React/Vue/Flutter] + end + + App --> OS + OS --> UI + OS --> QL + UI --> Renderer + QL --> DB + + style OS fill:#e1f5ff + style UI fill:#fff3e0 + style QL fill:#f3e5f5 +``` + +### ObjectQL:数据协议引擎 + +**角色**:数据库无关的查询引擎和模式编译器 + +ObjectQL 定义了一种基于 JSON 的通用查询语言,可编译为任何支持数据库的原生 SQL。它通过完全抽象数据层来消除供应商锁定。 + +**核心能力**: +- **模式定义**:将数据模型声明为 JSON 规范 +- **查询协议**:所有 CRUD 操作的统一 JSON 语法 +- **AST 编译**:将协议转译为特定数据库的 SQL +- **虚拟城市**:多租户数据隔离机制 +- **驱动抽象**:可插拔数据库驱动(MySQL、PostgreSQL、Oracle、SQLite、SQL Server) + +[→ ObjectQL 规范](/docs/objectql) + +### ObjectUI:声明式 UI 引擎 + +**角色**:基于协议的界面渲染器 + +ObjectUI 将 UI 开发从命令式代码转变为声明式 JSON 规范。界面是数据,而非函数。 + +**核心能力**: +- **组件协议**:表单、表格、网格、仪表板的 JSON 定义 +- **数据绑定**:与 ObjectQL 数据层自动同步 +- **动作协议**:声明式事件处理(API 调用、导航、对话框) +- **渲染器无关**:React 实现可用,Vue/Flutter 已规划 +- **主题系统**:可自定义样式而不改变结构 + +[→ ObjectUI 规范](/docs/objectui) + +### ObjectOS:运行时平台 + +**角色**:应用编排和平台服务 + +ObjectOS 将 ObjectQL 和 ObjectUI 绑定到一个连贯的运行时环境中,提供身份管理、访问控制和部署能力。 + +**核心能力**: +- **QL-UI 绑定**:数据层和界面层的自动连接 +- **身份系统**:内置带 RBAC 的用户管理 +- **字段级安全**:细粒度数据访问控制 +- **插件架构**:可扩展的业务逻辑层 +- **部署模式**:独立(.oos 文件)、服务器(Docker)、多租户 SaaS + +[→ ObjectOS 规范](/docs/objectos) + +--- + +## 为什么选择 ObjectStack? + +### 对于个人开发者 +构建本地优先应用程序,**无需服务器基础设施**: +- 个人工具(笔记、CRM、项目管理) +- 使用 SQLite 的离线应用程序 +- 零部署复杂性——只需一个 .oos 文件 +- 完全的隐私和数据所有权 + +### 对于企业 IT +通过标准协议层**统一异构遗留系统**: +- 连接多个数据库(Oracle、SQL Server、MySQL) +- 在所有系统上提供统一的 ObjectQL API +- 使用一致的查询接口消除数据孤岛 +- 将集成复杂性降低 10 倍 + +### 对于 SaaS 初创公司 +专注于**核心业务逻辑**,而非基础设施: +- 跳过数月的 CRUD/认证/权限样板代码 +- 在协议级别内置多租户 +- 数据库无关允许客户选择 +- 从 SQLite 扩展到 PostgreSQL 无需更改代码 + +### 对于低代码平台供应商 +提供**真正的可移植性**,无供应商锁定: +- 客户选择自己的数据库 +- 将应用程序导出/导入为标准 .oos 文件 +- 基于协议的设计支持可视化编辑工具 +- 对 AI 友好的规范用于代码生成 + +--- + +## 设计理念 + +ObjectStack 遵循**[宣言](/docs/framework/manifesto)**中概述的原则: + +1. **协议中立性**:规范先于实现。协议层中没有数据库、语言或框架依赖。 + +2. **机制优于策略**:协议定义接口(机制),而非实现(策略)。用户系统和业务逻辑属于 ObjectOS,而非 ObjectQL/UI 规范。 + +3. **数据主权**:强制本地优先。所有核心功能必须离线工作。数据必须可导出为标准格式。 + +4. **稳定性承诺**:破坏性更改需要 2 个主要版本的迁移窗口。基础设施必须稳定。 + +这些原则是**不可动摇且不可协商的**。违反这些原则的功能不能添加到 ObjectStack。 + +--- + +## 快速开始 + +根据您的角色选择学习路径: + +### 快速开始(5 分钟) +立即运行一个可工作的应用程序: +- **[快速开始指南](/docs/framework/quickstart)**:构建您的第一个 ObjectStack 应用 + +### 概念基础(30 分钟) +了解理念和架构: +- **[欢迎使用 ObjectStack](/docs/framework/welcome)**:平台概述和价值主张 +- **[宣言](/docs/framework/manifesto)**:核心原则和设计决策 +- **[架构指南](/docs/framework/architecture)**:技术设计和组件关系 + +### 组件规范(每个 2-3 小时) +深入了解每个引擎的协议规范: +- **[ObjectQL 规范](/docs/objectql)**:模式定义、查询 DSL、聚合 +- **[ObjectUI 规范](/docs/objectui)**:组件协议、动作、渲染 +- **[ObjectOS 规范](/docs/objectos)**:身份管理、RBAC、部署 + +### AI 辅助开发 +了解如何利用 LLM 进行快速开发: +- **[AI 法典](/docs/framework/ai-codex)**:使用 AI 从协议规范生成 80% 的应用程序 + +--- + +## 示例:协议中的待办事项应用 + +一个完整的应用程序定义为声明式 JSON: + +**数据层(ObjectQL 模式)**: +```json +{ + "objects": { + "todos": { + "fields": { + "title": { "type": "text", "required": true }, + "completed": { "type": "boolean", "defaultValue": false }, + "priority": { "type": "select", "options": ["high", "medium", "low"] }, + "owner": { "type": "lookup", "reference_to": "_users" } + }, + "permission_set": { + "user": { + "allowRead": true, + "allowCreate": true, + "allowEdit": "owner eq $user.id", + "allowDelete": "owner eq $user.id" + } + } + } + } +} +``` + +**界面层(ObjectUI 协议)**: +```json +{ + "type": "page", + "title": "我的任务", + "body": { + "type": "table", + "object": "todos", + "filters": [["completed", "=", false]], + "columns": [ + { "field": "title", "label": "任务" }, + { "field": "priority", "label": "优先级" }, + { "field": "completed", "label": "完成", "type": "boolean" } + ], + "actions": [ + { "label": "标记完成", "type": "update", "data": { "completed": true } }, + { "label": "删除", "type": "delete", "confirm": true } + ] + } +} +``` + +**结果**:一个功能齐全、数据库无关、权限控制的任务管理应用程序——完全定义为数据。 + +--- + +## 社区和生态系统 + +- **GitHub**:[github.com/objectstack-ai](https://github.com/objectstack-ai) +- **协议规范**:本文档站点(objectstack.org) +- **参考实现**:开源引擎(MIT/Apache 2.0) +- **社区插件**:通过 ObjectOS 插件架构可扩展 + +--- + +## 下一步 + +1. **理解理念**:阅读**[宣言](/docs/framework/manifesto)**以了解 ObjectStack 的核心原则 +2. **构建您的第一个应用**:按照**[快速开始指南](/docs/framework/quickstart)**部署一个可工作的应用程序 +3. **学习协议**:研究**[ObjectQL](/docs/objectql)**、**[ObjectUI](/docs/objectui)** 和 **[ObjectOS](/docs/objectos)** 规范 +4. **探索用例**:查看**[架构](/docs/framework/architecture)**以了解企业模式 + +欢迎加入 ObjectStack 生态系统。让我们一起构建协议驱动开发的未来。 diff --git a/content/docs/cn/objectos/index.mdx b/content/docs/cn/objectos/index.mdx index ba6c19a..671aee6 100644 --- a/content/docs/cn/objectos/index.mdx +++ b/content/docs/cn/objectos/index.mdx @@ -1,227 +1,966 @@ --- -title: ObjectOS - 运行时与平台 -description: 将数据与界面绑定在一起的运行时平台,实现本地优先架构 +title: ObjectOS 平台规范 +description: 运行时编排平台 - 身份管理、RBAC、多租户和部署 --- -# ObjectOS - 运行时与平台 +# ObjectOS:运行时编排平台 -ObjectOS 是将 ObjectQL(数据)和 ObjectUI(界面)整合在一起的运行时平台,提供完整的应用环境,包括身份管理、访问控制和灵活的部署选项。 +ObjectOS 是将 ObjectQL(数据)和 ObjectUI(界面)绑定成统一应用环境的**运行时平台**。它提供核心平台服务:身份管理、访问控制、插件架构和灵活的部署模式。 -## 什么是 ObjectOS? +## 规范概览 -ObjectOS 是**运行时平台**,它编排整个 ObjectStack。它将数据层(ObjectQL)与展示层(ObjectUI)绑定,同时提供用户管理、安全和部署等关键平台服务。 +ObjectOS **不是应用服务器**——它是一个**平台规范**,包含参考实现。该平台定义: -### 核心能力 +1. **QL-UI 绑定协议**:ObjectQL 和 ObjectUI 如何通信 +2. **身份与访问系统**:用户管理、RBAC、字段级安全 +3. **插件架构**:业务逻辑的扩展契约 +4. **部署模式**:独立模式、服务器模式和多租户配置 -- 🔗 **QL-UI 绑定** - 无缝连接数据引擎与 UI 框架 -- 🏠 **本地优先架构** - 应用完全在本地设备上运行 -- 👥 **身份与访问管理** - 内置用户系统和 RBAC -- 🔒 **字段级安全** - 细粒度的数据访问控制 -- 🚀 **灵活部署** - 独立 .oos 文件或 Docker 容器 -- 🏢 **多租户就绪** - 支持 SaaS 场景的租户隔离 +### 核心设计原则 -## 工作原理 +**本地优先设计**:ObjectOS 应用**默认离线运行**。独立模式(.oos 文件)完全在本地设备上运行,无需任何网络依赖。 -ObjectOS 作为运行时环境提供以下能力: +**数据库无关**:ObjectOS 从不假设特定数据库。配置决定数据是存储在 SQLite(本地)、PostgreSQL(云端)还是 Oracle(企业)中。 -### 1. 绑定数据与界面 +**机制而非策略**:ObjectOS 提供身份和权限**机制**(RBAC 接口),而非**策略**(硬编码的用户系统)。应用定义自己的用户模型。 +--- + +## 平台架构 + +```mermaid +graph TB + subgraph "应用层" + App[您的应用] + end + + subgraph "ObjectOS 平台" + Auth[身份与访问层
用户、角色、权限] + Binding[QL-UI 绑定层
数据 ↔ 界面桥接] + Plugin[插件架构
自定义业务逻辑] + Deploy[部署层
独立 / 服务器 / 多租户] + end + + subgraph "核心引擎" + UI[ObjectUI
界面协议] + QL[ObjectQL
数据协议] + end + + subgraph "基础设施" + DB[(数据库)] + Storage[文件存储] + Cache[缓存层] + end + + App --> Auth + Auth --> Binding + Binding --> UI + Binding --> QL + Binding --> Plugin + Deploy --> DB + Deploy --> Storage + Deploy --> Cache + + style Auth fill:#e1f5ff + style Binding fill:#fff3e0 + style Plugin fill:#f3e5f5 + style Deploy fill:#e8f5e9 +``` + +### 平台职责 -ObjectOS 在 ObjectQL 和 ObjectUI 之间创建双向桥接: +1. **身份与访问**:在协议层管理用户、角色和权限 +2. **QL-UI 绑定**:自动连接 ObjectQL 数据源到 ObjectUI 组件 +3. **插件系统**:为自定义业务逻辑(触发器、验证器、工作流)提供钩子 +4. **部署**:处理应用打包和运行时配置 + +--- + +## 核心平台组件 + +### 1. QL-UI 绑定协议 + +ObjectOS 自动连接 ObjectQL 数据源到 ObjectUI 组件: ```typescript -// ObjectOS 自动连接数据和界面 +interface BindingConfiguration { + dataSource: ObjectQLConfig // ObjectQL 连接 + uiSource: ObjectUIConfig // UI 协议定义 + autoSync?: boolean // 数据变化时自动刷新 + caching?: CacheStrategy // 客户端缓存 +} + +interface ObjectQLConfig { + driver: DatabaseDriver + url: string + schema: SchemaRegistry +} + +interface ObjectUIConfig { + pages: Record + components: Record + theme?: ThemeConfig +} +``` + +**绑定示例**: +```typescript +import { ObjectOS } from '@objectstack/os' + const app = new ObjectOS({ - schema: './schema', // ObjectQL schemas - pages: './pages', // ObjectUI 组件 - storage: './data' // 本地优先存储 + // 数据层 + data: { + driver: 'sqlite', + url: './myapp.db', + schema: { + objects: { + customers: { + fields: { + name: { type: 'text', required: true }, + email: { type: 'email', unique: true }, + status: { type: 'select', options: ['active', 'inactive'] } + } + } + } + } + }, + + // UI 层 + ui: { + pages: { + customers: { + type: 'page', + title: 'Customer Management', + body: { + type: 'table', + object: 'customers', // 自动绑定到 ObjectQL 对象 + columns: [ + { field: 'name', sortable: true }, + { field: 'email' }, + { field: 'status', type: 'badge' } + ] + } + } + } + } }) await app.start() ``` -### 2. 管理平台服务 +ObjectOS 处理: +- ✅ UI 组件挂载时获取数据 +- ✅ 数据操作前进行权限检查(RBAC) +- ✅ 变更前进行验证 +- ✅ 错误处理和用户反馈 +- ✅ 缓存管理 -提供核心平台能力: +### 2. 身份与访问管理 -- **用户系统** - `_users` 对象中的认证和用户资料 -- **角色管理** - `_roles` 对象中的灵活角色定义 -- **权限控制** - 支持字段级安全的 RBAC -- **数据隔离** - 多租户数据隔离 +ObjectOS 提供**协议级身份系统**,包含 RBAC 和字段级安全: -### 3. 支持灵活部署 +```typescript +interface IdentitySystem { + objects: { + _users: SystemObject // 内置用户对象 + _roles: SystemObject // 内置角色对象 + _permissions: SystemObject // 内置权限对象 + } + + authentication: AuthConfig // 认证提供者 + authorization: AuthzConfig // 权限规则 +} + +interface SystemObject { + _users: { + fields: { + username: { type: 'text', unique: true } + email: { type: 'email', unique: true } + password_hash: { type: 'text' } // 永不通过 API 暴露 + role: { type: 'lookup', reference_to: '_roles' } + is_active: { type: 'boolean', defaultValue: true } + created_at: { type: 'datetime', auto: 'onCreate' } + } + } + + _roles: { + fields: { + name: { type: 'text', unique: true } + description: { type: 'text' } + permissions: { type: 'master_detail', reference_to: '_permissions' } + } + } + + _permissions: { + fields: { + object: { type: 'text' } // 目标对象名称 + allow_read: { type: 'boolean' } + allow_create: { type: 'boolean' } + allow_edit: { type: 'boolean' } + allow_delete: { type: 'boolean' } + field_level_security: { type: 'json' } // 字段级规则 + } + } +} +``` -以多种模式部署应用: +**示例:权限配置**: +```typescript +const app = new ObjectOS({ + // ... 数据和 UI 配置 ... + + identity: { + authentication: { + providers: ['email', 'oauth'], + jwt: { + secret: process.env.JWT_SECRET, + expiresIn: '7d' + } + }, + + authorization: { + defaultRole: 'user', + roles: { + admin: { + permissions: { + customers: { read: true, create: true, edit: true, delete: true }, + orders: { read: true, create: true, edit: true, delete: true } + } + }, + user: { + permissions: { + customers: { + read: true, + create: false, + edit: false, + delete: false + }, + orders: { + read: 'owner eq $user.id', // 基于公式的权限 + create: true, + edit: 'owner eq $user.id', + delete: false + } + } + }, + guest: { + permissions: { + customers: { read: false, create: false, edit: false, delete: false }, + orders: { read: false, create: false, edit: false, delete: false } + } + } + } + } + } +}) +``` -```bash -# 独立模式 - 单个 .oos 文件 -./myapp.oos +### 3. 字段级安全(FLS) -# 服务器模式 - Docker 容器 -docker run -p 3000:3000 myapp:latest +字段级别的细粒度访问控制: -# 多租户 SaaS 模式 -docker run -e MULTI_TENANT=true myapp:latest +```typescript +interface FieldLevelSecurity { + object: string + field: string + read?: boolean | Expression // 可以读取字段吗? + edit?: boolean | Expression // 可以修改字段吗? +} ``` -## 平台架构 +**示例:FLS 配置**: +```json +{ + "objects": { + "employees": { + "fields": { + "name": { "type": "text" }, + "email": { "type": "email" }, + "salary": { + "type": "currency", + "field_level_security": { + "read": "$user.role === 'hr' || $user.role === 'admin'", + "edit": "$user.role === 'hr'" + } + }, + "ssn": { + "type": "text", + "field_level_security": { + "read": "$user.role === 'admin'", + "edit": false + } + } + } + } + } +} +``` +当普通用户查询员工时: +```json +// 查询 +{ "object": "employees" } + +// 响应(salary 和 ssn 字段自动过滤) +[ + { "name": "John Doe", "email": "john@company.com" } +] ``` -┌─────────────────────────────────────────────────────┐ -│ 应用层 │ -│ (您的业务逻辑) │ -└──────────────────────┬──────────────────────────────┘ - │ -┌──────────────────────▼──────────────────────────────┐ -│ ObjectOS 平台 │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ 身份与访问层 │ │ -│ │ ┌────────┬────────┬──────────────────┐ │ │ -│ │ │ 用户 │ 角色 │ 权限(FLS) │ │ │ -│ │ └────────┴────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ QL-UI 绑定层 │ │ -│ │ ┌──────────────────┬──────────────────┐ │ │ -│ │ │ ObjectUI │ ObjectQL │ │ │ -│ │ │ (展示层) │ (数据引擎) │ │ │ -│ │ └──────────────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ 存储抽象层 │ │ -│ │ ┌─────────┬──────────┬──────────────────┐ │ │ -│ │ │ SQLite │ MySQL │ PostgreSQL │ │ │ -│ │ │ (本地) │ (服务器) │ (服务器) │ │ │ -│ │ └─────────┴──────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────┘ + +### 4. 插件架构 + +使用自定义业务逻辑扩展 ObjectOS: + +```typescript +interface ObjectOSPlugin { + name: string + version: string + + // 生命周期钩子 + onInstall?(): Promise + onUninstall?(): Promise + onStart?(app: ObjectOSApp): Promise + onStop?(): Promise + + // 数据钩子 + beforeQuery?(query: QueryProtocol): Promise + afterQuery?(result: QueryResult): Promise + beforeMutation?(mutation: MutationProtocol): Promise + afterMutation?(result: MutationResult): Promise + + // UI 钩子 + beforeRender?(protocol: ComponentProtocol): Promise + + // 自定义路由 + routes?: RouteDefinition[] + + // 自定义组件 + components?: Record +} ``` -## 使用场景 +**示例:审计日志插件**: +```typescript +const auditLogPlugin: ObjectOSPlugin = { + name: 'audit-log', + version: '1.0.0', + + async afterMutation(result: MutationResult) { + // 记录所有数据变更 + await this.db.insert({ + object: '_audit_logs', + action: 'insert', + data: { + user_id: this.context.user.id, + object: result.object, + action: result.action, + record_id: result.id, + timestamp: new Date(), + changes: result.changes + } + }) + + return result + } +} -### 个人生产力应用 +// 安装插件 +app.use(auditLogPlugin) +``` -构建完全离线运行的本地优先应用: +**示例:邮件通知插件**: +```typescript +const emailPlugin: ObjectOSPlugin = { + name: 'email-notifications', + version: '1.0.0', + + async afterMutation(result: MutationResult) { + if (result.object === 'orders' && result.action === 'insert') { + // 发送订单确认邮件 + await this.sendEmail({ + to: result.data.customer_email, + subject: 'Order Confirmation', + template: 'order-confirmation', + data: result.data + }) + } + + return result + }, + + routes: [ + { + path: '/api/emails/preview/:template', + method: 'GET', + handler: async (req, res) => { + const template = await this.renderTemplate(req.params.template) + res.send(template) + } + } + ] +} +``` + +--- + +## 部署模式 + +ObjectOS 支持三种部署策略: +### 1. 独立模式(本地优先) + +**使用场景**:个人应用、离线优先工具、边缘计算 + +**配置**: ```typescript const app = new ObjectOS({ mode: 'standalone', - storage: '~/.myapp/data.db' + storage: './myapp.oos', // 单文件 SQLite 数据库 + ui: { + pages: { ... } + } }) + +await app.start() ``` -### 团队协作工具 +**特性**: +- ✅ 无需服务器基础设施 +- ✅ 完全离线能力 +- ✅ 数据存储在本地 .oos 文件(SQLite) +- ✅ 可作为单个可执行文件分发 +- ✅ 无需网络连接 -部署带用户管理的服务器应用: +**分发**: +```bash +# 打包为独立可执行文件 +objectstack build --mode standalone --output myapp.oos +# 可在任何地方运行 +./myapp.oos +# 或 +objectstack run myapp.oos +``` + +### 2. 服务器模式(云/企业) + +**使用场景**:团队协作、Web 应用、云部署 + +**配置**: ```typescript const app = new ObjectOS({ mode: 'server', - database: 'mysql://localhost/myapp', - auth: { - providers: ['email', 'oauth'] + port: 3000, + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + identity: { + authentication: { + providers: ['email', 'oauth'], + oauth: { + google: { + clientId: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET + } + } + } + }, + ui: { + pages: { ... } } }) + +await app.listen() +``` + +**特性**: +- ✅ 支持多用户认证 +- ✅ 自动生成 RESTful API +- ✅ 适用于任何数据库(MySQL、PostgreSQL、Oracle) +- ✅ 通过负载均衡器水平扩展 +- ✅ 可与现有系统集成 + +**部署**: +```dockerfile +# Dockerfile +FROM node:18 +WORKDIR /app +COPY package.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["npm", "start"] +``` + +```bash +# 部署到云端 +docker build -t myapp . +docker push myapp:latest +kubectl apply -f deployment.yaml ``` -### 多租户 SaaS 平台 +### 3. 多租户 SaaS 模式 -构建具有完整租户隔离的 SaaS 应用: +**使用场景**:SaaS 平台、多租户应用 +**配置**: ```typescript const app = new ObjectOS({ mode: 'multi-tenant', - tenantStrategy: 'virtualCity', - database: 'postgresql://localhost/saas' + tenantStrategy: 'virtualCity', // 或 'schema' 或 'database' + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + multiTenant: { + identification: { + strategy: 'subdomain', // customer1.myapp.com, customer2.myapp.com + // 或: 'header' // X-Tenant-ID header + // 或: 'jwt' // 从 JWT token 提取 + }, + isolation: { + strategy: 'virtualCity', // 所有租户在一个数据库中,通过上下文过滤 + // 或: 'schema' // 每个租户获得一个 PostgreSQL schema + // 或: 'database' // 每个租户获得单独数据库 + }, + provisioning: { + autoCreate: true, // 注册时自动创建租户 + defaultPlan: 'trial' + } + } }) -``` -## 您将学到什么 +// 中间件提取租户上下文 +app.use((req, res, next) => { + const tenantId = req.hostname.split('.')[0] // 从子域名提取 + req.tenant = app.getTenant(tenantId) + next() +}) -在本章节中,您将了解: +// 所有查询自动限定到租户范围 +app.get('/api/customers', async (req, res) => { + const customers = await req.tenant.query('customers', {}) + res.json(customers) // 仅返回该租户的客户 +}) +``` -- ✅ **平台架构** - ObjectOS 如何绑定 QL 和 UI -- ✅ **身份与访问** - 用户系统、RBAC 和字段级安全 -- ✅ **部署与运维** - 独立模式、服务器模式和多租户模式 -- ✅ **最佳实践** - 安全配置和优化技巧 +**租户隔离策略**: -## 开始学习 +| 策略 | 描述 | 优点 | 缺点 | 使用场景 | +|----------|-------------|------|------|----------| +| **虚拟城市** | 所有租户共享数据库,通过上下文过滤 | ✅ 资源利用率高
✅ 管理简单 | ❌ 需要仔细过滤
❌ 单点故障 | 多租户、中等数据量 | +| **Schema 隔离** | 每个租户获得 PostgreSQL schema | ✅ 数据隔离
✅ 备份简单 | ❌ Schema 限制(PostgreSQL:约100个)
❌ 迁移复杂 | 数百个租户 | +| **Database 隔离** | 每个租户获得独立数据库 | ✅ 完全隔离
✅ 独立扩展
✅ 迁移简单 | ❌ 资源使用高
❌ 管理开销大 | 企业客户、高价值租户 | -准备好深入了解了吗?从这里开始: +--- -1. **[平台架构](/docs/objectos/platform-architecture)** - 理解 ObjectOS 的工作原理 -2. **[身份与访问](/docs/objectos/identity-access)** - 设置用户和权限 -3. **[部署与运维](/docs/objectos/deployment)** - 部署您的应用 +## 高级特性 -## 快速示例 +### 1. 混合同步(本地优先 + 云端) -这里有一个完整的示例帮您入门: +结合独立模式与可选云同步: ```typescript -import { ObjectOS } from '@objectstack/os' - -// 1. 使用 schema 和 UI 初始化 ObjectOS const app = new ObjectOS({ mode: 'standalone', - storage: './myapp.db', - schema: { - objects: { - tasks: { - fields: { - name: { type: 'text', required: true }, - owner: { type: 'lookup', reference_to: '_users' } + storage: './myapp.oos', + + sync: { + enabled: true, + remote: 'https://sync.myapp.com', + strategy: 'manual', // 或 'automatic', 'scheduled' + conflict: 'last-write-wins', // 或 'manual-resolution' + encryption: { + enabled: true, + algorithm: 'AES-256-GCM', + key: process.env.ENCRYPTION_KEY + } + } +}) + +// 手动触发同步 +await app.sync.push() // 上传本地变更 +await app.sync.pull() // 下载远程变更 +await app.sync.bidirectional() // 双向同步并解决冲突 +``` + +### 2. 工作流引擎 + +内置工作流自动化: + +```typescript +const app = new ObjectOS({ + // ... 配置 ... + + workflows: { + order_approval: { + trigger: { + object: 'orders', + action: 'insert', + condition: 'total_amount > 10000' + }, + steps: [ + { + action: 'update', + object: 'orders', + data: { status: 'pending_approval' } }, - permission_set: { - user_permission: { - allowCreate: true, - allowRead: true, - allowEdit: "owner eq $user.id", - allowDelete: "owner eq $user.id" - } + { + action: 'notification', + type: 'email', + to: '{{approver.email}}', + template: 'order-approval-request' + } + ] + }, + + lead_nurturing: { + trigger: { + object: 'leads', + action: 'insert' + }, + steps: [ + { action: 'wait', duration: '1 day' }, + { + action: 'notification', + type: 'email', + template: 'welcome-email' + }, + { action: 'wait', duration: '3 days' }, + { + action: 'notification', + type: 'email', + template: 'follow-up-email', + condition: 'status == "new"' } + ] + } + } +}) +``` + +### 3. API 生成 + +ObjectOS 从 ObjectQL schemas 自动生成 RESTful API: + +```typescript +// Schema 定义 +{ + objects: { + products: { + fields: { + name: { type: 'text', required: true }, + price: { type: 'currency' }, + category: { type: 'select', options: ['electronics', 'clothing'] } + } + } + } +} + +// 自动生成的 REST API: +// GET /api/products - 列出所有产品 +// GET /api/products/:id - 获取单个产品 +// POST /api/products - 创建产品 +// PATCH /api/products/:id - 更新产品 +// DELETE /api/products/:id - 删除产品 +// GET /api/products/count - 统计产品数量 +// POST /api/products/aggregate - 聚合产品数据 +``` + +通过插件自定义 API 端点: + +```typescript +const customAPIPlugin: ObjectOSPlugin = { + name: 'custom-api', + routes: [ + { + path: '/api/products/featured', + method: 'GET', + handler: async (req, res) => { + const products = await req.db.query({ + object: 'products', + filters: [{ field: 'featured', operator: 'eq', value: true }], + top: 10 + }) + res.json(products) } } + ] +} +``` + +### 4. 实时更新 + +支持实时数据的 WebSocket: + +```typescript +const app = new ObjectOS({ + // ... 配置 ... + + realtime: { + enabled: true, + transport: 'websocket', + port: 3001 + } +}) + +// 客户端(通过 ObjectUI 自动) +{ + type: 'table', + object: 'orders', + realtime: true // 数据变化时表格自动更新 +} +``` + +--- + +## 使用场景 + +### 1. 个人生产力工具 + +**场景**:笔记应用、本地 CRM、项目管理 + +**配置**: +```typescript +const app = new ObjectOS({ + mode: 'standalone', + storage: '~/.mynotes/data.oos' +}) +``` + +**优势**: +- 零配置——下载即可运行 +- 完全隐私——数据永不离开设备 +- 天然离线工作 +- 可选择性同步到云端 + +### 2. 企业系统集成 + +**场景**:跨多个遗留数据库的统一仪表板 + +**配置**: +```typescript +// 连接多个数据源 +const erpDB = new ObjectQL({ driver: 'oracle', url: 'oracle://...' }) +const crmDB = new ObjectQL({ driver: 'sqlserver', url: 'sqlserver://...' }) + +const app = new ObjectOS({ + mode: 'server', + dataSources: { + erp: erpDB, + crm: crmDB }, - pages: { - home: { - type: 'list', - object: 'tasks' + ui: { + pages: { + dashboard: { + type: 'grid', + items: [ + { type: 'table', object: 'erp.customers' }, + { type: 'table', object: 'crm.leads' } + ] + } } } }) +``` -// 2. 启动应用 -await app.start() +**优势**: +- 多系统统一 UI +- 一致的查询语言 +- 无需自定义集成代码 +- 易于维护和扩展 + +### 3. 多租户 SaaS 平台 -console.log('ObjectOS 运行在 http://localhost:3000') +**场景**:项目管理 SaaS + +**配置**: +```typescript +const app = new ObjectOS({ + mode: 'multi-tenant', + tenantStrategy: 'schema', + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + identity: { + authentication: { + providers: ['email', 'oauth'] + } + } +}) ``` -## 本地优先架构 +**优势**: +- 完全租户隔离 +- 开箱即用的 RBAC +- 可扩展架构 +- 可在策略间迁移租户 + +--- + +## 学习内容 -ObjectOS 采用本地优先原则设计: +本规范文档涵盖: -- **离线优先** - 应用无需网络连接即可工作 -- **用户拥有数据** - 独立模式下数据保存在用户设备上 -- **按需同步** - 可选的云服务同步 -- **快速性能** - SQLite 驱动的本地存储 +- ✅ **[平台架构](/cn/docs/objectos/architecture)** - QL-UI 绑定、身份系统、插件架构 +- ✅ **[身份与访问](/cn/docs/objectos/identity-access)** - 用户管理、RBAC、字段级安全 +- ✅ **[插件开发](/cn/docs/objectos/plugins)** - 创建自定义业务逻辑扩展 +- ✅ **[部署指南](/cn/docs/objectos/deployment)** - 独立、服务器和多租户模式 +- ✅ **[API 参考](/cn/docs/objectos/api-reference)** - 完整的 ObjectOS SDK 文档 +- ✅ **[最佳实践](/cn/docs/objectos/best-practices)** - 安全、性能和可扩展性模式 + +--- + +## 快速开始示例 + +这是一个完整的端到端示例: ```typescript -// 本地优先配置 +import { ObjectOS } from '@objectstack/os' + +// 1. 初始化 ObjectOS const app = new ObjectOS({ - mode: 'standalone', - storage: './local-data.db', - sync: { - enabled: false, // 完全离线 - // 或启用同步: - // remote: 'https://sync.example.com', - // strategy: 'manual' + mode: 'server', + port: 3000, + + // 数据层(ObjectQL) + data: { + driver: 'sqlite', + url: './myapp.db', + schema: { + objects: { + tasks: { + fields: { + title: { type: 'text', required: true }, + status: { type: 'select', options: ['todo', 'in_progress', 'done'] }, + owner: { type: 'lookup', reference_to: '_users' } + }, + permission_set: { + user: { + allowRead: true, + allowCreate: true, + allowEdit: 'owner eq $user.id', + allowDelete: 'owner eq $user.id' + } + } + } + } + } + }, + + // UI 层(ObjectUI) + ui: { + pages: { + home: { + type: 'page', + title: 'My Tasks', + body: { + type: 'table', + object: 'tasks', + filters: [{ field: 'status', operator: 'ne', value: 'done' }], + columns: [ + { field: 'title', sortable: true }, + { field: 'status', type: 'badge' } + ], + actions: [ + { + label: 'Complete', + type: 'api_request', + api: '/api/tasks/{{row.id}}', + method: 'PATCH', + data: { status: 'done' } + } + ] + } + } + } + }, + + // 身份层 + identity: { + authentication: { + providers: ['email'] + }, + authorization: { + defaultRole: 'user' + } } }) + +// 2. 启动应用 +await app.listen() +console.log('ObjectOS running at http://localhost:3000') ``` +这创建了一个完整的任务管理应用,包含: +- SQLite 数据库 +- 用户认证 +- 权限控制的任务 CRUD +- 自动 REST API +- Web 界面 +- 仅用约 50 行代码 + +--- + +## 设计原理 + +### 为什么需要 QL-UI 绑定? + +**手动 API 开发很繁琐**。自动绑定提供: + +- **零样板代码**:无需编写 REST 控制器 +- **类型安全**:ObjectQL schema 强制数据契约 +- **权限强制执行**:自动应用 RBAC +- **一致性**:所有组件遵循相同模式 + +### 为什么内置身份系统? + +**大多数应用都需要用户管理**。内置系统提供: + +- **标准对象**:`_users`、`_roles`、`_permissions` 对象 +- **开箱即用的 RBAC**:无需自定义权限代码 +- **字段级安全**:细粒度访问控制 +- **集成就绪**:可插拔的认证提供者(OAuth、LDAP、SAML) + +### 为什么需要插件架构? + +**每个应用都有独特需求**。插件系统提供: + +- **可扩展性**:无需分叉即可添加自定义业务逻辑 +- **可组合性**:组合插件实现复杂工作流 +- **可维护性**:插件与核心平台隔离 +- **社区**:跨项目共享和重用插件 + +--- + +## 规范合规性 + +ObjectOS 实现必须通过 **ObjectOS 合规性测试套件**: + +- ✅ 具有自动数据获取的 QL-UI 绑定 +- ✅ 用户认证和会话管理 +- ✅ RBAC 权限强制执行 +- ✅ 字段级安全过滤 +- ✅ 具有生命周期钩子的插件系统 +- ✅ 独立模式(.oos 文件执行) +- ✅ 服务器模式(HTTP API 服务器) +- ✅ 多租户模式(虚拟城市隔离) + +参考实现: +- **Node.js**: [@objectstack/os](https://github.com/objectstack-ai/objectos) (JavaScript/TypeScript) +- **Python**: [objectos-py](https://github.com/objectstack-ai/objectos-py) (计划中) +- **Go**: [objectos-go](https://github.com/objectstack-ai/objectos-go) (计划中) + +--- + ## 下一步 -开始您的 ObjectOS 之旅: +1. **理解平台架构**:阅读[架构](/cn/docs/objectos/architecture)以了解 ObjectOS 如何编排 QL 和 UI +2. **设置身份系统**:查看[身份与访问](/cn/docs/objectos/identity-access)了解用户管理和 RBAC +3. **部署应用**:遵循[部署指南](/cn/docs/objectos/deployment)了解独立、服务器或多租户模式 +4. **使用插件扩展**:学习[插件开发](/cn/docs/objectos/plugins)以添加自定义业务逻辑 -- **初次接触 ObjectOS?** 从[平台架构](/docs/objectos/platform-architecture)开始 -- **设置安全?** 跳转到[身份与访问](/docs/objectos/identity-access) -- **准备部署?** 查看[部署与运维](/docs/objectos/deployment) +关于哲学背景,请参阅: +- **[宣言](/cn/docs/framework/manifesto)** - 为什么 ObjectOS 是本地优先和基于插件的 +- **[架构](/cn/docs/framework/architecture)** - ObjectOS 如何完善 ObjectStack 生态系统 diff --git a/content/docs/cn/objectql/index.mdx b/content/docs/cn/objectql/index.mdx index 6a765d7..05f3c49 100644 --- a/content/docs/cn/objectql/index.mdx +++ b/content/docs/cn/objectql/index.mdx @@ -1,191 +1,642 @@ --- -title: ObjectQL - 数据引擎 -description: 强大的数据引擎,提供 Schema 驱动架构和跨数据库支持 +title: ObjectQL 协议规范 +description: 数据库无关的数据协议引擎 - 模式定义、查询 DSL 和驱动抽象 --- -# ObjectQL - 数据引擎 +# ObjectQL:数据协议引擎 -ObjectQL 是 ObjectStack 的核心数据引擎,提供统一的数据访问层,具有 Schema 驱动架构、强大的查询能力和跨数据库支持。 +ObjectQL 是 ObjectStack 核心的**数据库无关查询引擎**。它定义了一种基于 JSON 的通用协议,用于模式定义、数据查询和变更,可编译为任何支持数据库的原生 SQL。 -## 什么是 ObjectQL? +## 规范概述 -ObjectQL 是一个**声明式数据引擎**,允许您只定义一次数据结构,就能在不同数据库系统中一致地访问数据。它抽象了数据库的复杂性,同时保留了 SQL 的强大功能和性能。 +ObjectQL **不是数据库**——它是一个**协议规范**及其参考实现。该协议定义: -### 核心能力 +1. **模式定义语言**:基于 JSON 的数据模型声明 +2. **查询 DSL(领域特定语言)**:CRUD 操作的统一语法 +3. **AST 编译**:数据库无关查询的抽象语法树 +4. **驱动接口**:数据库引擎的标准适配器契约 -- 🗂️ **Schema 驱动架构** - 声明式定义数据结构 -- 🔍 **统一查询 DSL** - 使用一致的语法查询任何数据库 -- ⚡ **性能优化** - SQLite 虚拟列索引,优化的数据库驱动 -- 🔄 **跨数据库支持** - SQLite、MySQL、PostgreSQL、Oracle、SQL Server -- 🏗️ **Virtual City 机制** - 多租户数据隔离 -- 🛡️ **类型安全** - 查询和结果的强类型支持 +### 核心设计原则 -## 工作原理 +**协议中立性**:ObjectQL 规范与实现无关。同一协议可由以下引擎执行: +- JavaScript 引擎(Node.js) +- Python 引擎(计划中) +- Java 引擎(计划中) +- Go 引擎(计划中) -ObjectQL 基于三个核心原则运作: +**数据库无关**:协议从不假定特定数据库。像"JSONB"(PostgreSQL)或"ROWNUM"(Oracle)这样的概念不存在于协议层——它们由特定方言的转译器处理。 -### 1. Schema 定义 +**机制,而非策略**:ObjectQL 定义*如何描述数据操作*,而非*如何实现*它们。用户认证、验证逻辑和业务规则属于 ObjectOS。 -使用简单的 JavaScript 对象定义数据结构: +--- + +## 协议架构 + +```mermaid +sequenceDiagram + participant App as 应用程序 + participant Engine as ObjectQL 引擎 + participant AST as AST 编译器 + participant Transpiler as 方言转译器 + participant Driver as 数据库驱动 + participant DB as 数据库 + + App->>Engine: 查询协议 (JSON) + Engine->>AST: 解析为 AST + AST->>Transpiler: 编译 AST + Transpiler->>Driver: 数据库特定 SQL + Driver->>DB: 执行查询 + DB-->>Driver: 结果集 + Driver-->>Engine: 标准化响应 + Engine-->>App: 标准 JSON 响应 +``` + +### 协议流程 + +1. **协议输入**:应用程序发送 JSON 查询协议 +2. **AST 解析**:引擎将协议解析为抽象语法树 +3. **方言编译**:AST 编译为特定数据库的 SQL +4. **驱动执行**:驱动执行原生 SQL +5. **响应标准化**:结果标准化为协议格式 +6. **协议输出**:应用程序接收一致的 JSON 响应 + +这种架构确保**完全的数据库独立性**——从 MySQL 切换到 PostgreSQL 无需更改任何应用代码。 + +--- + +## 核心协议组件 + +### 1. 模式定义协议 + +将数据结构定义为声明式 JSON 规范: ```typescript -const schema = { - objects: { - todos: { - fields: { - title: { type: 'text', required: true }, - completed: { type: 'boolean', defaultValue: false }, - due_date: { type: 'datetime' } - } +interface ObjectSchema { + name: string // 对象标识符 + label?: string // 人类可读名称 + fields: Record // 字段定义 + indexes?: Index[] // 性能索引 + triggers?: Trigger[] // 生命周期钩子 + permission_set?: PermissionSet // 访问控制规则 +} + +interface Field { + type: FieldType // 数据类型 + label?: string // 显示名称 + required?: boolean // 验证规则 + unique?: boolean // 唯一性约束 + defaultValue?: any // 默认值 + reference_to?: string // 关系目标(用于查找/主从关系) + formula?: string // 计算字段表达式 +} + +type FieldType = + | 'text' | 'textarea' | 'number' | 'currency' | 'percent' + | 'date' | 'datetime' | 'time' + | 'boolean' | 'select' | 'multiselect' + | 'lookup' | 'master_detail' + | 'url' | 'email' | 'phone' + | 'autonumber' | 'formula' +``` + +**示例模式**: +```json +{ + "objects": { + "orders": { + "label": "销售订单", + "fields": { + "order_number": { + "type": "autonumber", + "format": "ORD-{0000}" + }, + "customer": { + "type": "lookup", + "reference_to": "customers", + "required": true + }, + "order_date": { + "type": "date", + "defaultValue": "{{$now}}" + }, + "total_amount": { + "type": "currency", + "precision": 2 + }, + "status": { + "type": "select", + "options": ["draft", "confirmed", "shipped", "delivered"] + } + }, + "indexes": [ + { "fields": ["customer", "order_date"] }, + { "fields": ["status", "order_date"] } + ] } } } ``` -### 2. 查询执行 +此模式是**数据库无关的**。ObjectQL 将生成: +- **MySQL**:带有 `INT AUTO_INCREMENT`、`VARCHAR`、`DECIMAL`、`ENUM` 的 `CREATE TABLE` +- **PostgreSQL**:带有 `SERIAL`、`VARCHAR`、`NUMERIC`、`TEXT`(带检查约束)的 `CREATE TABLE` +- **Oracle**:带有 `NUMBER` 序列触发器、`VARCHAR2`、`NUMBER`、`VARCHAR2`(带检查约束)的 `CREATE TABLE` +- **SQLite**:带有 `INTEGER PRIMARY KEY`、`TEXT`、`REAL`、`TEXT`(带检查约束)的 `CREATE TABLE` + +### 2. 查询协议(DSL) -使用直观的 DSL 查询数据: +所有数据操作的统一 JSON 语法: ```typescript -const activeTodos = await db.query('todos', { - filters: [['completed', '=', false]], - sort: 'due_date asc' -}) +interface QueryProtocol { + object: string // 目标对象名称 + fields?: string[] // 要返回的字段(默认:全部) + filters?: FilterExpression // WHERE 子句 + sort?: string | SortExpression // ORDER BY 子句 + top?: number // LIMIT 子句 + skip?: number // OFFSET 子句 + related?: RelatedQuery[] // JOIN/子查询展开 +} + +type FilterExpression = Filter | CompoundFilter + +interface Filter { + field: string + operator: Operator + value: any +} + +type Operator = + | 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte' + | 'startswith' | 'endswith' | 'contains' | 'notcontains' + | 'in' | 'notin' | 'between' + | 'isnull' | 'isnotnull' + +interface CompoundFilter { + and?: FilterExpression[] + or?: FilterExpression[] +} +``` + +**示例查询**: + +```json +// 简单查询 +{ + "object": "orders", + "fields": ["order_number", "customer", "total_amount"], + "filters": { + "and": [ + { "field": "status", "operator": "eq", "value": "confirmed" }, + { "field": "order_date", "operator": "gte", "value": "2024-01-01" } + ] + }, + "sort": "order_date desc", + "top": 50 +} + +// 带关系的查询 +{ + "object": "orders", + "fields": ["order_number", "total_amount"], + "filters": { + "field": "customer.country", + "operator": "eq", + "value": "USA" + }, + "related": [ + { + "object": "order_items", + "foreign_key": "order_id", + "fields": ["product", "quantity", "unit_price"] + } + ] +} +``` + +### 3. 变更协议 + +数据修改的标准化操作: + +```typescript +interface MutationProtocol { + object: string + action: 'insert' | 'update' | 'delete' + data?: Record // 用于 insert/update + filters?: FilterExpression // 用于 update/delete +} ``` -### 3. 数据库抽象 - -ObjectQL 自动将查询转换为目标数据库的优化 SQL,自动处理方言差异。 - -## 架构概览 - -``` -┌─────────────────────────────────────────┐ -│ 应用层 │ -│ (您的业务逻辑) │ -└────────────────┬────────────────────────┘ - │ - │ ObjectQL API - │ -┌────────────────▼────────────────────────┐ -│ ObjectQL 引擎 │ -│ ┌────────────┬──────────────────────┐ │ -│ │ Schema │ 查询处理器 │ │ -│ │ 注册表 │ 和优化器 │ │ -│ └────────────┴──────────────────────┘ │ -│ ┌──────────────────────────────────┐ │ -│ │ Virtual City 管理器 │ │ -│ │ (多租户隔离) │ │ -│ └──────────────────────────────────┘ │ -└────────────────┬────────────────────────┘ - │ - │ 驱动抽象层 - │ -┌────────────────▼────────────────────────┐ -│ 数据库驱动 │ -│ ┌──────┬──────┬──────┬──────┬──────┐ │ -│ │SQLite│MySQL │Postgres│Oracle│SQL │ │ -│ │ │ │ │ │Server│ │ -│ └──────┴──────┴──────┴──────┴──────┘ │ -└─────────────────────────────────────────┘ +**示例变更**: + +```json +// 插入 +{ + "object": "orders", + "action": "insert", + "data": { + "customer": "CUST-001", + "order_date": "2024-03-15", + "total_amount": 1250.00, + "status": "confirmed" + } +} + +// 批量更新 +{ + "object": "orders", + "action": "update", + "filters": { + "and": [ + { "field": "status", "operator": "eq", "value": "confirmed" }, + { "field": "order_date", "operator": "lt", "value": "2024-01-01" } + ] + }, + "data": { + "status": "archived" + } +} + +// 条件删除 +{ + "object": "orders", + "action": "delete", + "filters": { + "field": "status", + "operator": "eq", + "value": "cancelled" + } +} ``` +--- + +## 数据库驱动接口 + +ObjectQL 定义了所有数据库适配器必须实现的**标准化驱动契约**: + +```typescript +interface ObjectQLDriver { + // 连接管理 + connect(config: ConnectionConfig): Promise + disconnect(): Promise + + // 模式操作 + createTable(schema: ObjectSchema): Promise + alterTable(schema: ObjectSchema, changes: SchemaChange[]): Promise + dropTable(objectName: string): Promise + + // 查询操作 + query(protocol: QueryProtocol): Promise + + // 变更操作 + insert(protocol: MutationProtocol): Promise + update(protocol: MutationProtocol): Promise + delete(protocol: MutationProtocol): Promise + + // 事务管理 + beginTransaction(): Promise + commit(transaction: Transaction): Promise + rollback(transaction: Transaction): Promise + + // 方言特定编译 + compileAST(ast: ASTNode): string // 返回原生 SQL +} +``` + +### 支持的驱动 + +官方参考实现: + +| 驱动 | 状态 | 用例 | +|------|------|------| +| **@objectql/driver-sqlite** | ✅ 稳定 | 本地优先应用、开发、边缘计算 | +| **@objectql/driver-mysql** | ✅ 稳定 | Web 应用、云部署 | +| **@objectql/driver-postgres** | ✅ 稳定 | 企业系统、分析工作负载 | +| **@objectql/driver-oracle** | 🚧 测试版 | 遗留系统集成 | +| **@objectql/driver-sqlserver** | 🚧 测试版 | Microsoft 技术栈集成 | + +欢迎社区驱动——实现 `ObjectQLDriver` 接口并作为 npm 包发布。 + +--- + +## 高级功能 + +### 虚拟城市(多租户) + +ObjectQL 通过虚拟城市机制提供**协议级多租户**: + +```typescript +// 每个租户获得隔离的数据上下文 +const tenant1DB = engine.virtualCity('tenant_001') +const tenant2DB = engine.virtualCity('tenant_002') + +// 相同的查询,隔离的数据 +await tenant1DB.query('customers', {}) // 返回 tenant_001 的客户 +await tenant2DB.query('customers', {}) // 返回 tenant_002 的客户 +``` + +**实现**:虚拟城市是驱动级功能。MySQL/PostgreSQL 实现使用模式分离,SQLite 使用单独的数据库文件。 + +### 虚拟列索引(性能) + +对于缺少原生 JSON 索引的数据库(例如 SQLite),ObjectQL 提供虚拟列索引: + +```json +{ + "objects": { + "products": { + "fields": { + "metadata": { "type": "text" } // 存储 JSON + }, + "virtual_indexes": [ + { + "name": "idx_price", + "expression": "JSON_EXTRACT(metadata, '$.price')", + "type": "number" + } + ] + } + } +} +``` + +ObjectQL 自动创建索引虚拟列以实现高性能查询。 + +### 公式字段 + +在模式中定义的计算字段: + +```json +{ + "fields": { + "quantity": { "type": "number" }, + "unit_price": { "type": "currency" }, + "line_total": { + "type": "formula", + "formula": "quantity * unit_price", + "return_type": "currency" + } + } +} +``` + +公式字段是**数据库无关的表达式**,编译为 SQL `GENERATED` 列(PostgreSQL/MySQL)或在内存中计算(SQLite)。 + +### 聚合协议 + +带分组的统计查询: + +```json +{ + "object": "orders", + "aggregations": [ + { "field": "total_amount", "function": "sum", "alias": "revenue" }, + { "field": "order_number", "function": "count", "alias": "order_count" } + ], + "groupBy": ["customer", "status"], + "filters": { + "field": "order_date", + "operator": "gte", + "value": "2024-01-01" + } +} +``` + +编译为跨所有数据库的 `GROUP BY` 查询和适当的聚合函数。 + +--- + ## 使用场景 -### 本地优先应用 +### 1. 本地优先应用 -使用 SQLite 构建个人应用: +**场景**:个人生产力工具(笔记、CRM、项目管理) +**配置**: ```typescript -const db = new ObjectQL({ - driver: 'sqlite', - url: './data/myapp.db' +import { ObjectQL } from '@objectql/core' +import { SQLiteDriver } from '@objectql/driver-sqlite' + +const engine = new ObjectQL({ + driver: new SQLiteDriver({ + database: './myapp.db' + }) }) ``` -### 企业系统 +**优势**: +- 零服务器基础设施 +- 完全离线能力 +- 数据存储在本地 .db 文件中 +- 以后可升级到云数据库而无需更改代码 + +### 2. 企业系统集成 -连接到现有数据库: +**场景**:异构遗留数据库上的统一 API +**配置**: ```typescript -const db = new ObjectQL({ - driver: 'mysql', - url: 'mysql://user:pass@localhost:3306/mydb' +// 连接到现有的 Oracle ERP 数据库 +const erpDB = new ObjectQL({ + driver: new OracleDriver({ + host: 'oracle.company.com', + database: 'ERP_PROD' + }) +}) + +// 连接到 SQL Server CRM 数据库 +const crmDB = new ObjectQL({ + driver: new SQLServerDriver({ + host: 'sqlserver.company.com', + database: 'CRM_PROD' + }) }) + +// 两者统一的 ObjectQL API +const erpCustomers = await erpDB.query('customers', {}) +const crmLeads = await crmDB.query('leads', {}) ``` -### 多租户 SaaS +**优势**: +- 所有系统的单一查询语言 +- 每个数据库无需自定义集成代码 +- 一致的错误处理和验证 +- 更易于维护和测试 + +### 3. 多租户 SaaS 平台 -利用 Virtual City 实现租户隔离: +**场景**:具有租户隔离的 SaaS 应用 +**配置**: ```typescript -const tenantDb = db.virtualCity('tenant_123') -const data = await tenantDb.query('customers', {}) +const engine = new ObjectQL({ + driver: new PostgreSQLDriver({ + host: 'postgres.cloud.com', + database: 'saas_platform' + }), + multiTenant: true +}) + +// 每个租户获得隔离的上下文 +app.use(async (req, res, next) => { + const tenantId = req.headers['x-tenant-id'] + req.db = engine.virtualCity(tenantId) + next() +}) + +// 自动数据隔离 +router.get('/api/orders', async (req, res) => { + const orders = await req.db.query('orders', {}) + res.json(orders) // 仅返回租户的订单 +}) ``` -## 您将学到什么 +**优势**: +- 协议级租户隔离 +- 数据隔离无需业务逻辑 +- 可扩展到每租户模式或每租户数据库 +- ObjectQL 自动处理路由 -在本章节中,您将了解: +--- -- ✅ **核心概念** - 理解 Schema 和 Virtual City 机制 -- ✅ **协议规范** - Schema 定义、查询 DSL 和聚合操作 -- ✅ **核心功能** - 虚拟列索引、驱动适配和性能优化 -- ✅ **服务端 SDK** - 完整的 API 参考和实践示例 +## 您将学到什么 -## 开始学习 +本规范文档涵盖: -准备好深入了解了吗?从这里开始: +- ✅ **[核心概念](/docs/objectql/core-concepts)** - 模式、虚拟城市、数据类型、关系 +- ✅ **[协议规范](/docs/objectql/protocol-spec)** - 查询、变更、聚合的完整 JSON 模式参考 +- ✅ **[驱动开发](/docs/objectql/driver-dev)** - 实现自定义数据库适配器 +- ✅ **[服务端 SDK](/docs/objectql/server-sdk)** - 参考实现 API(JavaScript/Node.js) +- ✅ **[性能指南](/docs/objectql/performance)** - 优化策略、索引、查询分析 -1. **[核心概念](/docs/objectql/core-concepts)** - 理解基础概念 -2. **[协议规范](/docs/objectql/protocol-spec)** - 学习 Schema 和查询语言 -3. **[核心功能](/docs/objectql/core-features)** - 探索高级功能 -4. **[服务端 SDK](/docs/objectql/server-sdk)** - 掌握 API +--- -## 快速示例 +## 快速开始示例 -这里有一个完整的示例帮您入门: +这是一个完整的端到端示例: ```typescript import { ObjectQL } from '@objectql/core' +import { SQLiteDriver } from '@objectql/driver-sqlite' -// 1. 初始化 ObjectQL -const db = new ObjectQL({ - driver: 'sqlite', - url: './myapp.db' +// 1. 初始化引擎 +const engine = new ObjectQL({ + driver: new SQLiteDriver({ database: './todo.db' }) }) -// 2. 定义 Schema -await db.registerSchema({ +// 2. 注册模式 +await engine.registerSchema({ objects: { tasks: { fields: { - name: { type: 'text', required: true }, - status: { type: 'select', options: ['todo', 'done'] }, - priority: { type: 'number' } + title: { type: 'text', required: true }, + completed: { type: 'boolean', defaultValue: false }, + priority: { type: 'select', options: ['high', 'medium', 'low'] }, + due_date: { type: 'date' } } } } }) // 3. 插入数据 -await db.mutation('tasks', { +await engine.insert({ + object: 'tasks', action: 'insert', - data: { name: '学习 ObjectQL', status: 'todo', priority: 1 } + data: { + title: '学习 ObjectQL', + priority: 'high', + due_date: '2024-12-31' + } }) // 4. 查询数据 -const tasks = await db.query('tasks', { - filters: [['status', '=', 'todo']], - sort: 'priority desc' +const urgentTasks = await engine.query({ + object: 'tasks', + filters: { + and: [ + { field: 'completed', operator: 'eq', value: false }, + { field: 'priority', operator: 'eq', value: 'high' } + ] + }, + sort: 'due_date asc' +}) + +console.log(urgentTasks) +// [{ title: '学习 ObjectQL', priority: 'high', completed: false, due_date: '2024-12-31' }] + +// 5. 切换到 PostgreSQL(零代码更改) +const prodEngine = new ObjectQL({ + driver: new PostgreSQLDriver({ + url: 'postgresql://localhost/production' + }) }) -console.log(tasks) // [{ name: '学习 ObjectQL', status: 'todo', priority: 1 }] +// 相同的模式,相同的查询,不同的数据库 +await prodEngine.registerSchema(schema) +const sameTasks = await prodEngine.query(queryProtocol) ``` +--- + +## 设计理由 + +### 为什么使用 JSON 协议? + +**TypeScript/JavaScript SDK 是实现细节**。真正的 API 是 JSON 协议: + +- **语言无关**:Python、Java、Go 都可以实现 ObjectQL +- **网络透明**:协议可通过 HTTP、WebSockets、gRPC 发送 +- **可版本化**:协议是结构化数据,可进行差异比较和版本控制 +- **AI 友好**:LLM 可以轻松生成和修改 JSON 协议 + +### 为什么使用 AST 编译? + +**直接 SQL 模板化既脆弱又不安全**。AST 编译提供: + +- **SQL 注入保护**:AST 级别的参数化查询 +- **方言抽象**:单一 AST 编译为任何 SQL 方言 +- **查询优化**:AST 可在执行前进行分析和优化 +- **一致的语义**:跨所有数据库的相同查询行为 + +### 为什么使用驱动抽象? + +**数据库 API 不一致**。驱动接口提供: + +- **统一错误处理**:跨数据库的一致错误类型 +- **连接池**:无论驱动如何,标准的池管理 +- **事务语义**:一致 API 的 ACID 保证 +- **测试**:无需数据库的单元测试 mock 驱动 + +--- + +## 规范合规性 + +ObjectQL 实现必须通过 **ObjectQL 合规性测试套件**: + +- ✅ 模式定义解析和验证 +- ✅ 所有运算符的查询协议执行 +- ✅ insert/update/delete 的变更协议 +- ✅ 关系查询(查找、主从关系) +- ✅ 带分组的聚合查询 +- ✅ 事务管理(ACID) +- ✅ 虚拟城市多租户隔离 +- ✅ 错误处理和响应格式 + +参考实现: +- **JavaScript**:[@objectql/core](https://github.com/objectstack-ai/objectql)(Node.js) +- **Python**:[objectql-py](https://github.com/objectstack-ai/objectql-py)(计划中) +- **Go**:[objectql-go](https://github.com/objectstack-ai/objectql-go)(计划中) + +--- + ## 下一步 -开始您的 ObjectQL 之旅: +1. **理解核心概念**:阅读[核心概念](/docs/objectql/core-concepts)了解模式、关系和虚拟城市 +2. **学习协议**:查看[协议规范](/docs/objectql/protocol-spec)获取完整的 JSON 模式参考 +3. **使用 SDK 构建**:使用[服务端 SDK](/docs/objectql/server-sdk)在应用中集成 ObjectQL +4. **优化性能**:探索[性能指南](/docs/objectql/performance)获取生产最佳实践 -- **初次接触 ObjectQL?** 从[核心概念](/docs/objectql/core-concepts)开始 -- **想查看完整 API?** 跳转到[服务端 SDK](/docs/objectql/server-sdk) -- **需要特定功能?** 查看[核心功能](/docs/objectql/core-features) +有关哲学背景,请参见: +- **[宣言](/docs/framework/manifesto)** - 为什么 ObjectQL 是协议驱动和数据库无关的 +- **[架构](/docs/framework/architecture)** - ObjectQL 如何融入 ObjectStack 生态系统 diff --git a/content/docs/cn/objectui/index.mdx b/content/docs/cn/objectui/index.mdx index bf04fd8..45be856 100644 --- a/content/docs/cn/objectui/index.mdx +++ b/content/docs/cn/objectui/index.mdx @@ -1,216 +1,731 @@ --- -title: ObjectUI - 界面引擎 -description: 声明式 UI 引擎,提供数据驱动渲染和基于协议的组件 +title: ObjectUI 协议规范 +description: 声明式界面引擎 - 组件协议、操作与渲染器抽象 --- -# ObjectUI - 界面引擎 +# ObjectUI: 声明式界面引擎 -ObjectUI 是 ObjectStack 的表现层,提供声明式 UI 引擎,通过 JSON 协议渲染界面。它将 UI 开发从命令式代码转变为数据驱动的声明。 +ObjectUI 是 ObjectStack 的**表现层协议**。它定义了一套基于 JSON 的规范,用于声明式地描述用户界面,将 UI 作为数据而非代码。 -## 什么是 ObjectUI? +## 规范概述 -ObjectUI 是一个**声明式 UI 引擎**,允许您使用 JSON 协议定义用户界面,而不是编写组件代码。它提供了一套完整的预构建组件,可以根据数据规范自动渲染。 +ObjectUI **不是一个组件库**——它是一个**协议规范**及其渲染器实现。该协议定义了: -### 核心能力 +1. **组件协议**: UI 元素的 JSON 模式 (表单、表格、网格、页面) +2. **操作协议**: 声明式事件处理器 (API 调用、导航、对话框) +3. **数据绑定协议**: 与 ObjectQL 数据层的自动同步 +4. **渲染器接口**: 框架实现的标准化契约 -- 🎨 **声明式 UI** - 使用 JSON 而非 JSX/代码定义界面 -- 🔄 **数据驱动渲染** - UI 自动反映数据变化 -- 📦 **组件协议** - 丰富的预构建组件集 -- 🎭 **主题支持** - 可自定义的样式和主题 -- ⚡ **性能优化** - 智能渲染和更新 -- 🔌 **框架无关** - React 渲染器,其他框架即将支持 +### 核心设计原则 -## 工作原理 +**协议中立性**: ObjectUI 规范与渲染器无关。同一协议可以被以下渲染器渲染: +- React 渲染器 (参考实现) +- Vue 渲染器 (计划中) +- Flutter 渲染器 (计划中) +- 原生移动端渲染器 (计划中) -ObjectUI 基于一个简单的原则:**UI 即数据**。 +**声明式而非命令式**: ObjectUI 描述*要渲染什么*,而非*如何渲染*。协议中没有 `onClick` 回调或 `useState` 钩子——只有数据结构。 -### 1. 定义 UI 协议 +**数据驱动**: UI 组件绑定到 ObjectQL 数据源。状态管理、验证和更新由渲染器自动处理。 -使用 JSON 描述您的界面: +**框架无关**: 协议从不假设 React、Vue 或任何特定框架。渲染器将协议转换为框架特定的实现。 +--- + +## 协议架构 + +```mermaid +sequenceDiagram + participant App as 应用程序 + participant Renderer as ObjectUI 渲染器 + participant Parser as 协议解析器 + participant Component as 组件注册表 + participant DataLayer as ObjectQL 数据层 + + App->>Renderer: UI 协议 (JSON) + Renderer->>Parser: 解析协议 + Parser->>Component: 解析组件 + Component->>DataLayer: 绑定数据源 + DataLayer-->>Component: 数据响应 + Component-->>Renderer: 渲染的 UI + Renderer-->>App: 交互式界面 + + Note over App,DataLayer: 用户交互 + App->>Renderer: 用户操作 + Renderer->>DataLayer: 执行操作 (API 调用) + DataLayer-->>Renderer: 更新的数据 + Renderer-->>App: 重新渲染 UI +``` + +### 协议流程 + +1. **协议输入**: 应用程序提供 JSON UI 协议 +2. **协议解析**: 渲染器解析并验证协议结构 +3. **组件解析**: 将协议类型映射到框架组件 +4. **数据绑定**: 将组件连接到 ObjectQL 数据源 +5. **渲染**: 渲染框架特定的组件 +6. **操作处理**: 用户交互触发协议定义的操作 +7. **状态更新**: 数据变化触发自动重新渲染 + +这种架构确保了**完全的框架独立性**——从 React 切换到 Vue 无需任何协议更改。 + +--- + +## 核心协议组件 + +### 1. 组件协议 + +将 UI 元素定义为声明式 JSON 规范: + +```typescript +interface ComponentProtocol { + type: ComponentType // 组件标识符 + id?: string // 唯一组件 ID + name?: string // 字段名称 (用于表单输入) + label?: string // 显示标签 + visible?: boolean | Expression // 条件可见性 + disabled?: boolean | Expression // 条件禁用状态 + style?: StyleProperties // 自定义样式 + children?: ComponentProtocol[] // 嵌套组件 +} + +type ComponentType = + // 容器组件 + | 'page' | 'card' | 'grid' | 'form' | 'table' | 'list' + // 输入组件 + | 'input' | 'textarea' | 'select' | 'multiselect' | 'checkbox' | 'switch' + | 'datepicker' | 'timepicker' | 'datetimepicker' + | 'number' | 'currency' | 'percent' + // 显示组件 + | 'text' | 'heading' | 'image' | 'icon' | 'badge' | 'avatar' + // 操作组件 + | 'button' | 'link' | 'dropdown' +``` +**示例: 页面组件**: ```json { "type": "page", - "title": "待办事项列表", + "title": "客户管理", + "description": "管理客户记录", "body": { - "type": "form", - "fields": [ + "type": "grid", + "columns": 2, + "gap": 4, + "items": [ { - "name": "title", - "type": "input", - "label": "任务名称", - "required": true + "type": "card", + "title": "客户列表", + "body": { + "type": "table", + "object": "customers", + "columns": [ + { "field": "name", "label": "姓名", "sortable": true }, + { "field": "email", "label": "邮箱" }, + { "field": "status", "label": "状态", "type": "badge" } + ] + } }, { - "name": "priority", - "type": "select", - "label": "优先级", - "options": ["高", "中", "低"] + "type": "card", + "title": "添加客户", + "body": { + "type": "form", + "object": "customers", + "action": "insert", + "fields": [ + { "name": "name", "type": "input", "required": true }, + { "name": "email", "type": "input", "inputType": "email" }, + { "name": "status", "type": "select", "options": ["active", "inactive"] } + ] + } } ] } } ``` -### 2. 使用 ObjectUI 渲染 +### 2. 表单协议 -将协议传递给渲染器: +具有验证和数据绑定的丰富表单定义: -```tsx -import { ObjectUIRenderer } from '@objectstack/react-renderer' +```typescript +interface FormProtocol extends ComponentProtocol { + type: 'form' + object?: string // ObjectQL 对象名称 + api?: string // 自定义 API 端点 + method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' + action?: 'insert' | 'update' | 'delete' // ObjectQL 操作 + fields: FieldProtocol[] // 表单字段 + initialValues?: Record // 默认值 + submitText?: string // 提交按钮标签 + resetText?: string // 重置按钮标签 + onSuccess?: ActionProtocol // 成功处理器 + onError?: ActionProtocol // 错误处理器 +} -function App() { - return +interface FieldProtocol extends ComponentProtocol { + name: string // 字段标识符 + type: ComponentType // 输入类型 + label?: string // 显示标签 + placeholder?: string // 占位符文本 + required?: boolean // 验证规则 + validation?: ValidationRule[] // 自定义验证 + dependsOn?: string // 依赖字段 + visible?: Expression // 条件可见性 + disabled?: Expression // 条件禁用状态 +} + +interface ValidationRule { + type: 'required' | 'email' | 'url' | 'min' | 'max' | 'pattern' | 'custom' + value?: any // 规则参数 + message: string // 错误消息 } ``` -### 3. 自动生成 UI +**示例: 复杂表单**: +```json +{ + "type": "form", + "object": "orders", + "action": "insert", + "fields": [ + { + "name": "customer", + "type": "select", + "label": "客户", + "required": true, + "api": "/api/customers", + "displayField": "name", + "valueField": "id" + }, + { + "name": "order_date", + "type": "datepicker", + "label": "订单日期", + "defaultValue": "{{$now}}", + "required": true + }, + { + "name": "items", + "type": "table", + "label": "订单项", + "columns": [ + { + "field": "product", + "type": "select", + "api": "/api/products", + "required": true + }, + { "field": "quantity", "type": "number", "min": 1 }, + { + "field": "unit_price", + "type": "currency", + "disabled": true, + "formula": "{{product.price}}" + }, + { + "field": "total", + "type": "currency", + "disabled": true, + "formula": "{{quantity * unit_price}}" + } + ] + }, + { + "name": "grand_total", + "type": "currency", + "label": "总计", + "disabled": true, + "formula": "{{SUM(items, 'total')}}" + } + ], + "submitText": "创建订单", + "onSuccess": { + "type": "navigate", + "path": "/orders/{{response.id}}" + } +} +``` -ObjectUI 渲染出一个功能完整的界面,包含表单、验证、操作和状态管理——全部来自 JSON 协议。 +### 3. 表格协议 -## 架构概览 +具有排序、过滤、分页的数据网格: + +```typescript +interface TableProtocol extends ComponentProtocol { + type: 'table' + object?: string // ObjectQL 对象名称 + api?: string // 自定义 API 端点 + columns: ColumnProtocol[] // 列定义 + filters?: FilterProtocol[] // 预定义过滤器 + searchable?: boolean // 启用搜索栏 + sortable?: boolean // 启用列排序 + paginated?: boolean // 启用分页 + pageSize?: number // 每页行数 + selectable?: boolean // 启用行选择 + actions?: ActionProtocol[] // 行操作 + bulkActions?: ActionProtocol[] // 批量操作 +} +interface ColumnProtocol { + field: string // 数据字段名称 + label: string // 列标题 + type?: 'text' | 'number' | 'date' | 'boolean' | 'badge' | 'avatar' | 'custom' + sortable?: boolean // 启用排序 + filterable?: boolean // 启用过滤 + width?: string // 列宽度 + align?: 'left' | 'center' | 'right' + formatter?: Expression // 自定义格式化 + visible?: boolean | Expression // 条件可见性 +} ``` -┌─────────────────────────────────────────┐ -│ 应用层 │ -│ (业务逻辑) │ -└────────────────┬────────────────────────┘ - │ - │ UI 协议 (JSON) - │ -┌────────────────▼────────────────────────┐ -│ ObjectUI 引擎 │ -│ ┌────────────┬──────────────────────┐ │ -│ │ 协议 │ 组件 │ │ -│ │ 解析器 │ 注册表 │ │ -│ └────────────┴──────────────────────┘ │ -│ ┌──────────────────────────────────┐ │ -│ │ 渲染协调器 │ │ -│ │ (状态与操作) │ │ -│ └──────────────────────────────────┘ │ -└────────────────┬────────────────────────┘ - │ - │ 组件实例 - │ -┌────────────────▼────────────────────────┐ -│ React 渲染器 │ -│ ┌──────┬──────┬──────┬──────┬──────┐ │ -│ │Input │Select│Table │Form │Page │ │ -│ │ │ │ │ │ │ │ -│ └──────┴──────┴──────┴──────┴──────┘ │ -└─────────────────────────────────────────┘ + +**示例: 高级表格**: +```json +{ + "type": "table", + "object": "products", + "columns": [ + { + "field": "image", + "label": "图片", + "type": "avatar", + "width": "60px" + }, + { + "field": "name", + "label": "产品名称", + "sortable": true, + "filterable": true + }, + { + "field": "category", + "label": "类别", + "type": "badge", + "sortable": true + }, + { + "field": "price", + "label": "价格", + "type": "currency", + "sortable": true, + "align": "right" + }, + { + "field": "stock", + "label": "库存", + "type": "number", + "sortable": true, + "align": "right", + "formatter": "{{value > 10 ? '有货' : '库存不足'}}" + }, + { + "field": "status", + "label": "状态", + "type": "badge", + "filterable": true + } + ], + "filters": [ + { "field": "status", "operator": "eq", "value": "active" } + ], + "searchable": true, + "sortable": true, + "paginated": true, + "pageSize": 50, + "selectable": true, + "actions": [ + { + "label": "编辑", + "type": "navigate", + "path": "/products/{{row.id}}/edit" + }, + { + "label": "删除", + "type": "api_request", + "api": "/api/products/{{row.id}}", + "method": "DELETE", + "confirm": { + "title": "删除产品", + "message": "确定要删除 {{row.name}} 吗?" + } + } + ], + "bulkActions": [ + { + "label": "激活", + "type": "api_request", + "api": "/api/products/bulk-update", + "method": "PATCH", + "data": { "status": "active" } + }, + { + "label": "停用", + "type": "api_request", + "api": "/api/products/bulk-update", + "method": "PATCH", + "data": { "status": "inactive" } + } + ] +} ``` -## 核心概念 +### 4. 操作协议 -### 声明式 vs 命令式 +无需命令式代码的声明式事件处理: -**命令式 UI (传统方式):** -```tsx -// 编写代码描述如何构建 UI -function TodoForm() { - const [title, setTitle] = useState('') - const [priority, setPriority] = useState('') - - const handleSubmit = (e) => { - e.preventDefault() - // 提交逻辑... +```typescript +interface ActionProtocol { + type: ActionType + label?: string // 按钮/链接文本 + icon?: string // 图标名称 + confirm?: ConfirmDialog // 确认对话框 + condition?: Expression // 条件执行 +} + +type ActionType = + | APIRequestAction + | NavigateAction + | DialogAction + | ToastAction + | RefreshAction + | CustomAction + +interface APIRequestAction extends ActionProtocol { + type: 'api_request' + api: string // API 端点 + method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' + data?: Record // 请求主体 + params?: Record // 查询参数 + onSuccess?: ActionProtocol // 成功处理器 + onError?: ActionProtocol // 错误处理器 +} + +interface NavigateAction extends ActionProtocol { + type: 'navigate' + path: string // 导航路径 + target?: '_self' | '_blank' // 目标窗口 +} + +interface DialogAction extends ActionProtocol { + type: 'dialog' + title: string // 对话框标题 + content: ComponentProtocol // 对话框主体 + width?: string // 对话框宽度 + actions?: ActionProtocol[] // 对话框操作 +} + +interface ToastAction extends ActionProtocol { + type: 'toast' + message: string // 提示消息 + variant?: 'success' | 'error' | 'warning' | 'info' + duration?: number // 显示持续时间 (ms) +} +``` + +**示例: 操作链**: +```json +{ + "type": "button", + "label": "批准订单", + "action": { + "type": "api_request", + "api": "/api/orders/{{order.id}}/approve", + "method": "POST", + "confirm": { + "title": "批准订单", + "message": "确定要批准订单 #{{order.order_number}} 吗?" + }, + "onSuccess": { + "type": "toast", + "message": "订单已成功批准", + "variant": "success", + "next": { + "type": "navigate", + "path": "/orders" + } + }, + "onError": { + "type": "toast", + "message": "批准订单失败: {{error.message}}", + "variant": "error" + } } - - return ( -
- setTitle(e.target.value)} - /> - - -
- ) } ``` -**声明式 UI (ObjectUI):** +### 5. 表达式语言 + +动态值和条件逻辑: + +```typescript +type Expression = string // 格式: {{expression}} + +// 变量引用 +"{{field_name}}" // 当前表单字段 +"{{row.field_name}}" // 表格行数据 +"{{$user.id}}" // 当前用户 +"{{$now}}" // 当前时间戳 +"{{$env.API_URL}}" // 环境变量 + +// 运算符 +"{{value > 10}}" // 比较 +"{{status === 'active'}}" // 相等 +"{{price * quantity}}" // 算术 +"{{firstname + ' ' + lastname}}" // 连接 + +// 函数 +"{{SUM(items, 'total')}}" // 数组聚合 +"{{FILTER(items, 'status eq active')}}" // 数组过滤 +"{{FORMAT(date, 'YYYY-MM-DD')}}" // 格式化 +"{{LOOKUP('products', product_id, 'name')}}" // 数据查找 + +// 条件 +"{{status === 'active' ? '活跃' : '不活跃'}}" // 三元运算符 +``` + +**示例: 动态表单**: ```json { "type": "form", - "api": "/api/todos", "fields": [ - { "name": "title", "type": "input", "required": true }, - { "name": "priority", "type": "select", "options": ["高", "中", "低"] } + { + "name": "customer_type", + "type": "select", + "options": ["individual", "business"] + }, + { + "name": "first_name", + "type": "input", + "label": "名", + "visible": "{{customer_type === 'individual'}}", + "required": "{{customer_type === 'individual'}}" + }, + { + "name": "last_name", + "type": "input", + "label": "姓", + "visible": "{{customer_type === 'individual'}}", + "required": "{{customer_type === 'individual'}}" + }, + { + "name": "company_name", + "type": "input", + "label": "公司名称", + "visible": "{{customer_type === 'business'}}", + "required": "{{customer_type === 'business'}}" + }, + { + "name": "tax_id", + "type": "input", + "label": "税号", + "visible": "{{customer_type === 'business'}}", + "validation": [ + { + "type": "pattern", + "value": "^[0-9]{9}$", + "message": "税号必须是9位数字" + } + ] + } ] } ``` -声明式方法的优势: -- ✅ 更少的代码编写和维护 -- ✅ 更容易理解和修改 -- ✅ 可以作为数据生成、存储和版本控制 -- ✅ 支持动态 UI 生成 +--- + +## 渲染器接口 + +ObjectUI 定义了一个**标准化的渲染器契约**,所有框架实现都必须支持: + +```typescript +interface ObjectUIRenderer { + // 核心渲染 + render(protocol: ComponentProtocol, container: HTMLElement): RenderedComponent + unmount(component: RenderedComponent): void + + // 组件注册 + registerComponent(type: ComponentType, implementation: ComponentImplementation): void + + // 操作处理 + registerActionHandler(type: ActionType, handler: ActionHandler): void + + // 数据绑定 + bindDataSource(component: RenderedComponent, source: DataSource): void + + // 主题管理 + setTheme(theme: ThemeConfig): void + + // 生命周期钩子 + onMount?(component: RenderedComponent): void + onUpdate?(component: RenderedComponent, changes: PropertyChanges): void + onUnmount?(component: RenderedComponent): void +} +``` + +### 支持的渲染器 + +官方参考实现: + +| 渲染器 | 状态 | 框架 | +|----------|--------|-----------| +| **@objectui/react-renderer** | ✅ 稳定 | React 18+ | +| **@objectui/vue-renderer** | 🚧 计划中 | Vue 3+ | +| **@objectui/flutter-renderer** | 🚧 计划中 | Flutter | +| **@objectui/native-renderer** | 🚧 计划中 | React Native | -### 数据驱动渲染 +欢迎社区渲染器——实现 `ObjectUIRenderer` 接口并发布为 npm 包。 -ObjectUI 组件是**数据驱动**的: +--- + +## 高级功能 + +### 组件组合 -1. **协议定义结构** - JSON 描述要渲染什么 -2. **数据定义内容** - 组件获取或接收数据 -3. **状态触发更新** - 变化自动重新渲染 +从简单组件构建复杂 UI: ```json { - "type": "table", - "api": "/api/users", - "columns": [ - { "name": "name", "label": "姓名" }, - { "name": "email", "label": "邮箱" }, - { "name": "status", "label": "状态" } - ] + "type": "page", + "title": "仪表板", + "body": { + "type": "grid", + "columns": 3, + "items": [ + { + "type": "card", + "title": "总收入", + "body": { + "type": "text", + "value": "{{SUM(orders, 'total_amount')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + }, + { + "type": "card", + "title": "活跃用户", + "body": { + "type": "text", + "value": "{{COUNT(users, 'status eq active')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + }, + { + "type": "card", + "title": "待处理订单", + "body": { + "type": "text", + "value": "{{COUNT(orders, 'status eq pending')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + } + ] + } +} +``` + +### 响应式布局 + +自动适配屏幕尺寸: + +```json +{ + "type": "grid", + "columns": { "mobile": 1, "tablet": 2, "desktop": 4 }, + "gap": { "mobile": 2, "tablet": 3, "desktop": 4 }, + "items": [...] } ``` -这个表格: -- 自动从 `/api/users` 获取数据 -- 按指定列渲染 -- 处理分页、排序、筛选 -- 数据变化时自动更新 +### 自定义组件 + +扩展组件库: + +```typescript +// 在渲染器中注册自定义组件 +renderer.registerComponent('chart', ChartComponent) + +// 在协议中使用 +{ + "type": "chart", + "chartType": "line", + "data": "{{monthly_revenue}}", + "xAxis": "month", + "yAxis": "revenue" +} +``` + +### 主题系统 + +无需更改结构即可自定义外观: + +```typescript +renderer.setTheme({ + colors: { + primary: '#007bff', + secondary: '#6c757d', + success: '#28a745', + error: '#dc3545' + }, + fonts: { + body: 'Inter, sans-serif', + heading: 'Poppins, sans-serif' + }, + spacing: { + unit: 8 // 8px 基本单位 + } +}) +``` + +--- ## 使用场景 -### 管理后台 +### 1. 管理面板和仪表板 -无需编写 UI 代码即可构建完整的管理界面: +**场景**: 无需编写 UI 代码即可构建完整的管理界面 +**协议**: ```json { "type": "page", "title": "用户管理", "body": { - "type": "crud", - "api": "/api/users", - "columns": [...], - "filters": [...], - "actions": [...] + "type": "table", + "object": "users", + "columns": [ + { "field": "avatar", "type": "avatar" }, + { "field": "name", "sortable": true }, + { "field": "email", "sortable": true }, + { "field": "role", "type": "badge" }, + { "field": "created_at", "type": "date", "sortable": true } + ], + "actions": [ + { "label": "编辑", "type": "navigate", "path": "/users/{{row.id}}/edit" }, + { "label": "删除", "type": "api_request", "api": "/api/users/{{row.id}}", "method": "DELETE" } + ] } } ``` -### 动态表单 +**优势**: +- 不需要 React/Vue 代码 +- 自动 CRUD 操作 +- 内置分页、排序、过滤 +- 可以存储在数据库中并进行版本控制 + +### 2. 动态表单 -创建基于配置自适应的表单: +**场景**: 根据配置或用户权限自适应的表单 +**协议**: ```json { "type": "form", - "api": "/api/submit", + "object": "leads", "fields": [ { "name": "name", "type": "input", "required": true }, + { "name": "email", "type": "input", "inputType": "email" }, { "name": "country", "type": "select", @@ -219,96 +734,192 @@ ObjectUI 组件是**数据驱动**的: { "name": "state", "type": "select", - "api": "/api/states", + "api": "/api/states?country={{country}}", + "visible": "{{country !== null}}", "dependsOn": "country" + }, + { + "name": "budget", + "type": "currency", + "visible": "{{$user.role === 'sales' || $user.role === 'admin'}}" } ] } ``` -### 低代码平台 +**优势**: +- 表单结构作为数据存储 +- 无需代码部署即可轻松修改 +- 基于权限的字段可见性 +- 依赖字段逻辑 + +### 3. 低代码 / 无代码平台 -让用户通过配置构建界面: +**场景**: 使非开发人员能够构建界面 +**实现**: ```typescript -// 将 UI 协议存储到数据库 -await db.mutation('pages', { +// 在数据库中存储 UI 协议 +await db.insert({ + object: 'pages', action: 'insert', data: { - name: 'dashboard', - protocol: { type: 'page', ... } + name: 'customer_dashboard', + protocol: { + type: 'page', + title: '客户仪表板', + body: { ... } + } } }) -// 从数据库渲染 -const page = await db.query('pages', { filters: [['name', '=', 'dashboard']] }) -return +// 获取并渲染 +const page = await db.query({ + object: 'pages', + filters: [{ field: 'name', operator: 'eq', value: 'customer_dashboard' }] +}) + +return +``` + +**优势**: +- UI 定义像数据一样可版本控制 +- 可以构建可视化 UI 构建器 +- AI 可以生成协议 +- 易于进行 A/B 测试 UI 变体 + +### 4. 移动应用 + +**场景**: 相同协议,不同渲染器 + +**React Native**: +```tsx +import { ObjectUIRenderer } from '@objectui/native-renderer' + +function App() { + return +} ``` -## 您将学到什么 +**Flutter**: +```dart +import 'package:objectui_flutter/objectui_flutter.dart'; -在本章节中,您将了解: +Widget build(BuildContext context) { + return ObjectUIRenderer(protocol: uiProtocol); +} +``` -- ✅ **核心概念** - 理解声明式 UI 和数据驱动渲染 -- ✅ **组件规范** - 所有组件的完整协议参考 -- ✅ **渲染器使用** - 如何在 React 应用中集成 ObjectUI -- ✅ **自定义** - 主题、样式和扩展组件 +**优势**: +- 编写一次 UI 协议 +- 在 Web、iOS、Android 上渲染 +- 跨平台行为一致 +- 共享业务逻辑 -## 开始学习 +--- -准备好深入了解了吗?从这里开始: +## 学习内容 -1. **[核心概念](/docs/objectui/core-concepts)** - 理解声明式 UI 原则 -2. **[组件规范](/docs/objectui/component-spec)** - 学习组件协议 -3. **[渲染器使用](/docs/objectui/renderer-usage)** - 在应用中集成 +本规范文档涵盖: -## 快速示例 +- ✅ **[核心概念](/cn/docs/objectui/core-concepts)** - 声明式 UI、数据绑定、组件组合 +- ✅ **[组件规范](/cn/docs/objectui/component-spec)** - 所有组件的完整 JSON 模式参考 +- ✅ **[操作](/cn/docs/objectui/actions)** - 操作协议规范 (API、导航、对话框) +- ✅ **[渲染器使用](/cn/docs/objectui/renderer-usage)** - 在 React/Vue/Flutter 应用中集成 ObjectUI +- ✅ **[主题](/cn/docs/objectui/theming)** - 自定义外观和样式 +- ✅ **[最佳实践](/cn/docs/objectui/best-practices)** - 设计模式和优化策略 -这里有一个完整的示例帮您入门: +--- + +## 快速入门示例 + +这是一个完整的端到端示例: ```tsx -import { ObjectUIRenderer } from '@objectstack/react-renderer' +import { ObjectUIRenderer } from '@objectui/react-renderer' +import '@objectui/react-renderer/styles.css' // 1. 定义 UI 协议 const todoApp = { type: 'page', - title: '我的待办事项', + title: '待办事项应用', body: { type: 'grid', columns: 2, + gap: 4, items: [ + // 添加待办事项表单 { - type: 'form', - title: '添加待办', - api: '/api/todos', - method: 'POST', - fields: [ - { - name: 'title', - type: 'input', - label: '任务', - required: true - }, - { - name: 'completed', - type: 'switch', - label: '已完成', - defaultValue: false + type: 'card', + title: '添加任务', + body: { + type: 'form', + object: 'todos', + action: 'insert', + fields: [ + { + name: 'title', + type: 'input', + label: '任务名称', + required: true + }, + { + name: 'priority', + type: 'select', + label: '优先级', + options: ['high', 'medium', 'low'], + defaultValue: 'medium' + }, + { + name: 'due_date', + type: 'datepicker', + label: '截止日期' + } + ], + submitText: '添加任务', + onSuccess: { + type: 'toast', + message: '任务创建成功', + variant: 'success' } - ], - submitText: '添加任务' + } }, + // 待办事项列表表格 { - type: 'table', - title: '待办列表', - api: '/api/todos', - columns: [ - { name: 'title', label: '任务' }, - { name: 'completed', label: '完成', type: 'boolean' } - ], - actions: [ - { label: '删除', api: '/api/todos/${id}', method: 'DELETE' } - ] + type: 'card', + title: '我的任务', + body: { + type: 'table', + object: 'todos', + filters: [ + { field: 'completed', operator: 'eq', value: false } + ], + columns: [ + { field: 'title', label: '任务', sortable: true }, + { field: 'priority', label: '优先级', type: 'badge' }, + { field: 'due_date', label: '截止日期', type: 'date', sortable: true }, + { field: 'completed', label: '完成', type: 'boolean' } + ], + actions: [ + { + label: '完成', + type: 'api_request', + api: '/api/todos/{{row.id}}', + method: 'PATCH', + data: { completed: true } + }, + { + label: '删除', + type: 'api_request', + api: '/api/todos/{{row.id}}', + method: 'DELETE', + confirm: { + title: '删除任务', + message: '确定吗?' + } + } + ] + } } ] } @@ -316,20 +927,80 @@ const todoApp = { // 2. 渲染 function App() { - return + return } + +export default App ``` -这创建了一个功能完整的待办应用,包含: -- 添加待办的表单 -- 显示所有待办的表格 -- 每个待办的删除操作 -- 自动数据获取和更新 +这创建了一个功能齐全的待办事项应用,具有: +- 添加任务的表单 +- 显示活动任务的表格 +- 完成和删除操作 +- 从 ObjectQL 自动获取数据 +- 不需要命令式 React 代码 + +--- + +## 设计原理 + +### 为什么使用 JSON 协议? + +**React/Vue 组件是实现细节**。真正的 UI 是 JSON 协议: + +- **框架无关**: 相同协议可在 React、Vue、Flutter 中渲染 +- **可版本控制**: UI 作为结构化数据存储在数据库中 +- **AI 友好**: LLM 擅长生成 JSON 结构 +- **可移植**: 在项目间导出/导入 UI 定义 + +### 为什么是声明式? + +**命令式 UI 代码脆弱且冗长**。声明式协议提供: + +- **可维护性**: 更改结构,而非代码 +- **一致性**: 所有表单/表格遵循相同模式 +- **可测试性**: 协议是数据,易于验证 +- **组合性**: 从简单构建块构建复杂 UI + +### 为什么是数据驱动? + +**手动状态管理容易出错**。自动数据绑定提供: + +- **一致性**: UI 始终反映数据状态 +- **更少代码**: 无需 useState、useEffect 或状态管理库 +- **性能**: 由渲染器处理智能差异和更新 +- **简单性**: 开发人员专注于结构,而非同步 + +--- + +## 规范合规性 + +ObjectUI 渲染器必须通过 **ObjectUI 合规性测试套件**: + +- ✅ 协议解析和验证 +- ✅ 所有组件类型正确渲染 +- ✅ 操作执行和错误处理 +- ✅ 数据绑定和更新 +- ✅ 表达式求值 +- ✅ 条件可见性和禁用状态 +- ✅ 表单验证和提交 +- ✅ 表格排序、过滤、分页 +- ✅ 响应式布局 + +参考实现: +- **React**: [@objectui/react-renderer](https://github.com/objectstack-ai/objectui) (React 18+) +- **Vue**: [@objectui/vue-renderer](https://github.com/objectstack-ai/objectui-vue) (计划中) +- **Flutter**: [objectui_flutter](https://github.com/objectstack-ai/objectui-flutter) (计划中) + +--- ## 下一步 -开始您的 ObjectUI 之旅: +1. **理解核心概念**: 阅读[核心概念](/cn/docs/objectui/core-concepts)以学习声明式 UI 原则 +2. **学习组件协议**: 查看[组件规范](/cn/docs/objectui/component-spec)获取完整参考 +3. **使用渲染器构建**: 使用[渲染器使用](/cn/docs/objectui/renderer-usage)在应用中集成 ObjectUI +4. **自定义外观**: 探索[主题](/cn/docs/objectui/theming)了解样式和自定义 -- **初次接触声明式 UI?** 从[核心概念](/docs/objectui/core-concepts)开始 -- **需要组件参考?** 跳转到[组件规范](/docs/objectui/component-spec) -- **准备开始构建?** 查看[渲染器使用](/docs/objectui/renderer-usage) +有关理念背景,请参阅: +- **[宣言](/cn/docs/framework/manifesto)** - 为什么 ObjectUI 是协议驱动和框架无关的 +- **[架构](/cn/docs/framework/architecture)** - ObjectUI 如何融入 ObjectStack 生态系统 diff --git a/content/docs/en/objectos/index.mdx b/content/docs/en/objectos/index.mdx index 2657341..a861860 100644 --- a/content/docs/en/objectos/index.mdx +++ b/content/docs/en/objectos/index.mdx @@ -1,227 +1,966 @@ --- -title: ObjectOS - The Platform -description: Runtime platform that binds data and UI together with Local-First architecture +title: ObjectOS Platform Specification +description: Runtime Orchestration Platform - Identity Management, RBAC, Multi-Tenancy, and Deployment --- -# ObjectOS - The Platform +# ObjectOS: The Runtime Orchestration Platform -ObjectOS is the runtime platform that brings ObjectQL (data) and ObjectUI (interface) together, providing a complete application environment with identity management, access control, and flexible deployment options. +ObjectOS is the **runtime platform** that binds ObjectQL (data) and ObjectUI (interface) into a cohesive application environment. It provides essential platform services: identity management, access control, plugin architecture, and flexible deployment modes. -## What is ObjectOS? +## Specification Overview -ObjectOS is the **runtime platform** that orchestrates the entire ObjectStack. It binds the data layer (ObjectQL) with the presentation layer (ObjectUI) while providing essential platform services like user management, security, and deployment capabilities. +ObjectOS is **not an application server**—it is a **platform specification** with reference implementations. The platform defines: -### Key Capabilities +1. **QL-UI Binding Protocol**: How ObjectQL and ObjectUI communicate +2. **Identity & Access System**: User management, RBAC, field-level security +3. **Plugin Architecture**: Extensibility contracts for business logic +4. **Deployment Modes**: Standalone, server, and multi-tenant configurations -- 🔗 **QL-UI Binding** - Seamlessly connects data engine with UI framework -- 🏠 **Local-First Architecture** - Run applications entirely on local devices -- 👥 **Identity & Access Management** - Built-in user system with RBAC -- 🔒 **Field-Level Security** - Fine-grained data access control -- 🚀 **Flexible Deployment** - Standalone .oos files or Docker containers -- 🏢 **Multi-Tenant Ready** - SaaS-ready with tenant isolation +### Core Design Principles -## How It Works +**Local-First by Design**: ObjectOS applications run **offline by default**. Standalone mode (.oos files) operates entirely on local devices with zero network dependency. -ObjectOS operates as the runtime environment that: +**Database Agnostic**: ObjectOS never assumes a specific database. Configuration determines whether data lives in SQLite (local), PostgreSQL (cloud), or Oracle (enterprise). -### 1. Binds Data and UI +**Mechanism over Policy**: ObjectOS provides identity and permission **mechanisms** (RBAC interfaces), not **policies** (hardcoded user systems). Applications define their own user models. +--- + +## Platform Architecture + +```mermaid +graph TB + subgraph "Application Layer" + App[Your Application] + end + + subgraph "ObjectOS Platform" + Auth[Identity & Access Layer
Users, Roles, Permissions] + Binding[QL-UI Binding Layer
Data ↔ Interface Bridge] + Plugin[Plugin Architecture
Custom Business Logic] + Deploy[Deployment Layer
Standalone / Server / Multi-Tenant] + end + + subgraph "Core Engines" + UI[ObjectUI
Interface Protocol] + QL[ObjectQL
Data Protocol] + end + + subgraph "Infrastructure" + DB[(Database)] + Storage[File Storage] + Cache[Cache Layer] + end + + App --> Auth + Auth --> Binding + Binding --> UI + Binding --> QL + Binding --> Plugin + Deploy --> DB + Deploy --> Storage + Deploy --> Cache + + style Auth fill:#e1f5ff + style Binding fill:#fff3e0 + style Plugin fill:#f3e5f5 + style Deploy fill:#e8f5e9 +``` + +### Platform Responsibilities -ObjectOS creates a bidirectional bridge between ObjectQL and ObjectUI: +1. **Identity & Access**: Manages users, roles, and permissions at protocol level +2. **QL-UI Binding**: Automatically connects ObjectQL data sources to ObjectUI components +3. **Plugin System**: Provides hooks for custom business logic (triggers, validators, workflows) +4. **Deployment**: Handles application packaging and runtime configuration + +--- + +## Core Platform Components + +### 1. QL-UI Binding Protocol + +ObjectOS automatically wires ObjectQL data sources to ObjectUI components: ```typescript -// ObjectOS automatically wires up data and UI +interface BindingConfiguration { + dataSource: ObjectQLConfig // ObjectQL connection + uiSource: ObjectUIConfig // UI protocol definitions + autoSync?: boolean // Auto-refresh on data changes + caching?: CacheStrategy // Client-side caching +} + +interface ObjectQLConfig { + driver: DatabaseDriver + url: string + schema: SchemaRegistry +} + +interface ObjectUIConfig { + pages: Record + components: Record + theme?: ThemeConfig +} +``` + +**Example Binding**: +```typescript +import { ObjectOS } from '@objectstack/os' + const app = new ObjectOS({ - schema: './schema', // ObjectQL schemas - pages: './pages', // ObjectUI components - storage: './data' // Local-First storage + // Data Layer + data: { + driver: 'sqlite', + url: './myapp.db', + schema: { + objects: { + customers: { + fields: { + name: { type: 'text', required: true }, + email: { type: 'email', unique: true }, + status: { type: 'select', options: ['active', 'inactive'] } + } + } + } + } + }, + + // UI Layer + ui: { + pages: { + customers: { + type: 'page', + title: 'Customer Management', + body: { + type: 'table', + object: 'customers', // Auto-binds to ObjectQL object + columns: [ + { field: 'name', sortable: true }, + { field: 'email' }, + { field: 'status', type: 'badge' } + ] + } + } + } + } }) await app.start() ``` -### 2. Manages Platform Services +ObjectOS handles: +- ✅ Data fetching when UI component mounts +- ✅ Permission checks (RBAC) before data operations +- ✅ Validation before mutations +- ✅ Error handling and user feedback +- ✅ Cache management + +### 2. Identity & Access Management + +ObjectOS provides **protocol-level identity system** with RBAC and field-level security: + +```typescript +interface IdentitySystem { + objects: { + _users: SystemObject // Built-in user object + _roles: SystemObject // Built-in role object + _permissions: SystemObject // Built-in permission object + } + + authentication: AuthConfig // Auth providers + authorization: AuthzConfig // Permission rules +} + +interface SystemObject { + _users: { + fields: { + username: { type: 'text', unique: true } + email: { type: 'email', unique: true } + password_hash: { type: 'text' } // Never exposed via API + role: { type: 'lookup', reference_to: '_roles' } + is_active: { type: 'boolean', defaultValue: true } + created_at: { type: 'datetime', auto: 'onCreate' } + } + } + + _roles: { + fields: { + name: { type: 'text', unique: true } + description: { type: 'text' } + permissions: { type: 'master_detail', reference_to: '_permissions' } + } + } + + _permissions: { + fields: { + object: { type: 'text' } // Target object name + allow_read: { type: 'boolean' } + allow_create: { type: 'boolean' } + allow_edit: { type: 'boolean' } + allow_delete: { type: 'boolean' } + field_level_security: { type: 'json' } // Field-level rules + } + } +} +``` + +**Example: Permission Configuration**: +```typescript +const app = new ObjectOS({ + // ... data and UI config ... + + identity: { + authentication: { + providers: ['email', 'oauth'], + jwt: { + secret: process.env.JWT_SECRET, + expiresIn: '7d' + } + }, + + authorization: { + defaultRole: 'user', + roles: { + admin: { + permissions: { + customers: { read: true, create: true, edit: true, delete: true }, + orders: { read: true, create: true, edit: true, delete: true } + } + }, + user: { + permissions: { + customers: { + read: true, + create: false, + edit: false, + delete: false + }, + orders: { + read: 'owner eq $user.id', // Formula-based permission + create: true, + edit: 'owner eq $user.id', + delete: false + } + } + }, + guest: { + permissions: { + customers: { read: false, create: false, edit: false, delete: false }, + orders: { read: false, create: false, edit: false, delete: false } + } + } + } + } + } +}) +``` + +### 3. Field-Level Security (FLS) + +Fine-grained access control at the field level: + +```typescript +interface FieldLevelSecurity { + object: string + field: string + read?: boolean | Expression // Can read field? + edit?: boolean | Expression // Can modify field? +} +``` + +**Example: FLS Configuration**: +```json +{ + "objects": { + "employees": { + "fields": { + "name": { "type": "text" }, + "email": { "type": "email" }, + "salary": { + "type": "currency", + "field_level_security": { + "read": "$user.role === 'hr' || $user.role === 'admin'", + "edit": "$user.role === 'hr'" + } + }, + "ssn": { + "type": "text", + "field_level_security": { + "read": "$user.role === 'admin'", + "edit": false + } + } + } + } + } +} +``` + +When a regular user queries employees: +```json +// Query +{ "object": "employees" } + +// Response (salary and ssn fields automatically filtered) +[ + { "name": "John Doe", "email": "john@company.com" } +] +``` + +### 4. Plugin Architecture + +Extend ObjectOS with custom business logic: + +```typescript +interface ObjectOSPlugin { + name: string + version: string + + // Lifecycle hooks + onInstall?(): Promise + onUninstall?(): Promise + onStart?(app: ObjectOSApp): Promise + onStop?(): Promise + + // Data hooks + beforeQuery?(query: QueryProtocol): Promise + afterQuery?(result: QueryResult): Promise + beforeMutation?(mutation: MutationProtocol): Promise + afterMutation?(result: MutationResult): Promise + + // UI hooks + beforeRender?(protocol: ComponentProtocol): Promise + + // Custom routes + routes?: RouteDefinition[] + + // Custom components + components?: Record +} +``` + +**Example: Audit Log Plugin**: +```typescript +const auditLogPlugin: ObjectOSPlugin = { + name: 'audit-log', + version: '1.0.0', + + async afterMutation(result: MutationResult) { + // Log all data changes + await this.db.insert({ + object: '_audit_logs', + action: 'insert', + data: { + user_id: this.context.user.id, + object: result.object, + action: result.action, + record_id: result.id, + timestamp: new Date(), + changes: result.changes + } + }) + + return result + } +} + +// Install plugin +app.use(auditLogPlugin) +``` + +**Example: Email Notification Plugin**: +```typescript +const emailPlugin: ObjectOSPlugin = { + name: 'email-notifications', + version: '1.0.0', + + async afterMutation(result: MutationResult) { + if (result.object === 'orders' && result.action === 'insert') { + // Send order confirmation email + await this.sendEmail({ + to: result.data.customer_email, + subject: 'Order Confirmation', + template: 'order-confirmation', + data: result.data + }) + } + + return result + }, + + routes: [ + { + path: '/api/emails/preview/:template', + method: 'GET', + handler: async (req, res) => { + const template = await this.renderTemplate(req.params.template) + res.send(template) + } + } + ] +} +``` -Provides essential platform capabilities: +--- + +## Deployment Modes -- **User System** - Authentication and user profiles in `_users` object -- **Role Management** - Flexible role definitions in `_roles` object -- **Permission Control** - RBAC with field-level security -- **Data Isolation** - Multi-tenant data segregation +ObjectOS supports three deployment strategies: -### 3. Enables Flexible Deployment +### 1. Standalone Mode (Local-First) -Deploy applications in multiple modes: +**Use Case**: Personal applications, offline-first tools, edge computing + +**Configuration**: +```typescript +const app = new ObjectOS({ + mode: 'standalone', + storage: './myapp.oos', // Single-file SQLite database + ui: { + pages: { ... } + } +}) +await app.start() +``` + +**Characteristics**: +- ✅ Zero server infrastructure required +- ✅ Complete offline capability +- ✅ Data stored in local .oos file (SQLite) +- ✅ Can be distributed as single executable +- ✅ No network connectivity needed + +**Distribution**: ```bash -# Standalone mode - single .oos file +# Package as standalone executable +objectstack build --mode standalone --output myapp.oos + +# Run anywhere ./myapp.oos +# or +objectstack run myapp.oos +``` + +### 2. Server Mode (Cloud/Enterprise) -# Server mode - Docker container -docker run -p 3000:3000 myapp:latest +**Use Case**: Team collaboration, web applications, cloud deployments -# Multi-tenant SaaS mode -docker run -e MULTI_TENANT=true myapp:latest +**Configuration**: +```typescript +const app = new ObjectOS({ + mode: 'server', + port: 3000, + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + identity: { + authentication: { + providers: ['email', 'oauth'], + oauth: { + google: { + clientId: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET + } + } + } + }, + ui: { + pages: { ... } + } +}) + +await app.listen() ``` -## Platform Architecture +**Characteristics**: +- ✅ Multi-user support with authentication +- ✅ RESTful API automatically generated +- ✅ Works with any database (MySQL, PostgreSQL, Oracle) +- ✅ Horizontal scalability with load balancers +- ✅ Can integrate with existing systems + +**Deployment**: +```dockerfile +# Dockerfile +FROM node:18 +WORKDIR /app +COPY package.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["npm", "start"] +``` +```bash +# Deploy to cloud +docker build -t myapp . +docker push myapp:latest +kubectl apply -f deployment.yaml ``` -┌─────────────────────────────────────────────────────┐ -│ Application Layer │ -│ (Your Business Logic) │ -└──────────────────────┬──────────────────────────────┘ - │ -┌──────────────────────▼──────────────────────────────┐ -│ ObjectOS Platform │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ Identity & Access Layer │ │ -│ │ ┌────────┬────────┬──────────────────┐ │ │ -│ │ │ Users │ Roles │ Permissions (FLS)│ │ │ -│ │ └────────┴────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ QL-UI Binding Layer │ │ -│ │ ┌──────────────────┬──────────────────┐ │ │ -│ │ │ ObjectUI │ ObjectQL │ │ │ -│ │ │ (Presentation) │ (Data Engine) │ │ │ -│ │ └──────────────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ Storage Abstraction │ │ -│ │ ┌─────────┬──────────┬──────────────────┐ │ │ -│ │ │ SQLite │ MySQL │ PostgreSQL │ │ │ -│ │ │ (Local) │ (Server) │ (Server) │ │ │ -│ │ └─────────┴──────────┴──────────────────┘ │ │ -│ └──────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────┘ + +### 3. Multi-Tenant SaaS Mode + +**Use Case**: SaaS platforms, multi-tenant applications + +**Configuration**: +```typescript +const app = new ObjectOS({ + mode: 'multi-tenant', + tenantStrategy: 'virtualCity', // or 'schema' or 'database' + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + multiTenant: { + identification: { + strategy: 'subdomain', // customer1.myapp.com, customer2.myapp.com + // or: 'header' // X-Tenant-ID header + // or: 'jwt' // Extract from JWT token + }, + isolation: { + strategy: 'virtualCity', // All tenants in one database, filtered by context + // or: 'schema' // Each tenant gets a PostgreSQL schema + // or: 'database' // Each tenant gets separate database + }, + provisioning: { + autoCreate: true, // Auto-create tenant on signup + defaultPlan: 'trial' + } + } +}) + +// Middleware extracts tenant context +app.use((req, res, next) => { + const tenantId = req.hostname.split('.')[0] // From subdomain + req.tenant = app.getTenant(tenantId) + next() +}) + +// All queries automatically scoped to tenant +app.get('/api/customers', async (req, res) => { + const customers = await req.tenant.query('customers', {}) + res.json(customers) // Only returns tenant's customers +}) +``` + +**Tenant Isolation Strategies**: + +| Strategy | Description | Pros | Cons | Use Case | +|----------|-------------|------|------|----------| +| **Virtual City** | All tenants share database, filtered by context | ✅ High resource efficiency
✅ Easy management | ❌ Requires careful filtering
❌ Single point of failure | Many tenants, moderate data volume | +| **Schema-per-Tenant** | Each tenant gets PostgreSQL schema | ✅ Data isolation
✅ Easy backups | ❌ Schema limits (PostgreSQL: ~100s)
❌ Migration complexity | Hundreds of tenants | +| **Database-per-Tenant** | Each tenant gets own database | ✅ Complete isolation
✅ Independent scaling
✅ Easy migration | ❌ High resource usage
❌ Management overhead | Enterprise customers, high-value tenants | + +--- + +## Advanced Features + +### 1. Hybrid Sync (Local-First + Cloud) + +Combine standalone mode with optional cloud sync: + +```typescript +const app = new ObjectOS({ + mode: 'standalone', + storage: './myapp.oos', + + sync: { + enabled: true, + remote: 'https://sync.myapp.com', + strategy: 'manual', // or 'automatic', 'scheduled' + conflict: 'last-write-wins', // or 'manual-resolution' + encryption: { + enabled: true, + algorithm: 'AES-256-GCM', + key: process.env.ENCRYPTION_KEY + } + } +}) + +// Trigger sync manually +await app.sync.push() // Upload local changes +await app.sync.pull() // Download remote changes +await app.sync.bidirectional() // Both directions with conflict resolution +``` + +### 2. Workflow Engine + +Built-in workflow automation: + +```typescript +const app = new ObjectOS({ + // ... config ... + + workflows: { + order_approval: { + trigger: { + object: 'orders', + action: 'insert', + condition: 'total_amount > 10000' + }, + steps: [ + { + action: 'update', + object: 'orders', + data: { status: 'pending_approval' } + }, + { + action: 'notification', + type: 'email', + to: '{{approver.email}}', + template: 'order-approval-request' + } + ] + }, + + lead_nurturing: { + trigger: { + object: 'leads', + action: 'insert' + }, + steps: [ + { action: 'wait', duration: '1 day' }, + { + action: 'notification', + type: 'email', + template: 'welcome-email' + }, + { action: 'wait', duration: '3 days' }, + { + action: 'notification', + type: 'email', + template: 'follow-up-email', + condition: 'status == "new"' + } + ] + } + } +}) +``` + +### 3. API Generation + +ObjectOS automatically generates RESTful APIs from ObjectQL schemas: + +```typescript +// Schema definition +{ + objects: { + products: { + fields: { + name: { type: 'text', required: true }, + price: { type: 'currency' }, + category: { type: 'select', options: ['electronics', 'clothing'] } + } + } + } +} + +// Auto-generated REST API: +// GET /api/products - List all products +// GET /api/products/:id - Get single product +// POST /api/products - Create product +// PATCH /api/products/:id - Update product +// DELETE /api/products/:id - Delete product +// GET /api/products/count - Count products +// POST /api/products/aggregate - Aggregate products +``` + +Custom API endpoints via plugins: + +```typescript +const customAPIPlugin: ObjectOSPlugin = { + name: 'custom-api', + routes: [ + { + path: '/api/products/featured', + method: 'GET', + handler: async (req, res) => { + const products = await req.db.query({ + object: 'products', + filters: [{ field: 'featured', operator: 'eq', value: true }], + top: 10 + }) + res.json(products) + } + } + ] +} ``` +### 4. Real-Time Updates + +WebSocket support for live data: + +```typescript +const app = new ObjectOS({ + // ... config ... + + realtime: { + enabled: true, + transport: 'websocket', + port: 3001 + } +}) + +// Client-side (automatic via ObjectUI) +{ + type: 'table', + object: 'orders', + realtime: true // Table updates automatically when data changes +} +``` + +--- + ## Use Cases -### Personal Productivity Apps +### 1. Personal Productivity Tools -Build Local-First applications that run entirely offline: +**Scenario**: Note-taking app, local CRM, project management +**Configuration**: ```typescript const app = new ObjectOS({ mode: 'standalone', - storage: '~/.myapp/data.db' + storage: '~/.mynotes/data.oos' }) ``` -### Team Collaboration Tools +**Benefits**: +- Zero setup—just download and run +- Complete privacy—data never leaves device +- Works offline by design +- Can sync to cloud optionally + +### 2. Enterprise System Integration -Deploy server-based applications with user management: +**Scenario**: Unified dashboard over multiple legacy databases +**Configuration**: ```typescript +// Connect to multiple data sources +const erpDB = new ObjectQL({ driver: 'oracle', url: 'oracle://...' }) +const crmDB = new ObjectQL({ driver: 'sqlserver', url: 'sqlserver://...' }) + const app = new ObjectOS({ mode: 'server', - database: 'mysql://localhost/myapp', - auth: { - providers: ['email', 'oauth'] + dataSources: { + erp: erpDB, + crm: crmDB + }, + ui: { + pages: { + dashboard: { + type: 'grid', + items: [ + { type: 'table', object: 'erp.customers' }, + { type: 'table', object: 'crm.leads' } + ] + } + } } }) ``` -### Multi-Tenant SaaS Platforms +**Benefits**: +- Single UI for multiple systems +- Consistent query language +- No custom integration code +- Easy to maintain and extend + +### 3. Multi-Tenant SaaS Platform -Build SaaS applications with complete tenant isolation: +**Scenario**: Project management SaaS +**Configuration**: ```typescript const app = new ObjectOS({ mode: 'multi-tenant', - tenantStrategy: 'virtualCity', - database: 'postgresql://localhost/saas' + tenantStrategy: 'schema', + data: { + driver: 'postgres', + url: process.env.DATABASE_URL + }, + identity: { + authentication: { + providers: ['email', 'oauth'] + } + } }) ``` -## What You'll Learn +**Benefits**: +- Complete tenant isolation +- RBAC out of the box +- Scalable architecture +- Can migrate tenants between strategies -In this section, you will discover: +--- -- ✅ **Platform Architecture** - How ObjectOS binds QL and UI together -- ✅ **Identity & Access** - User system, RBAC, and field-level security -- ✅ **Deployment & Operations** - Standalone, server, and multi-tenant modes -- ✅ **Best Practices** - Security configurations and optimization techniques +## What You'll Learn -## Getting Started +This specification documentation covers: -Ready to dive in? Start with: +- ✅ **[Platform Architecture](/docs/objectos/architecture)** - QL-UI binding, identity system, plugin architecture +- ✅ **[Identity & Access](/docs/objectos/identity-access)** - User management, RBAC, field-level security +- ✅ **[Plugin Development](/docs/objectos/plugins)** - Creating custom business logic extensions +- ✅ **[Deployment Guide](/docs/objectos/deployment)** - Standalone, server, and multi-tenant modes +- ✅ **[API Reference](/docs/objectos/api-reference)** - Complete ObjectOS SDK documentation +- ✅ **[Best Practices](/docs/objectos/best-practices)** - Security, performance, and scalability patterns -1. **[Platform Architecture](/docs/objectos/platform-architecture)** - Understand how ObjectOS works -2. **[Identity & Access](/docs/objectos/identity-access)** - Set up users and permissions -3. **[Deployment](/docs/objectos/deployment)** - Deploy your application +--- -## Quick Example +## Quick Start Example -Here's a complete example to get you started: +Here's a complete end-to-end example: ```typescript import { ObjectOS } from '@objectstack/os' -// 1. Initialize ObjectOS with schema and UI +// 1. Initialize ObjectOS const app = new ObjectOS({ - mode: 'standalone', - storage: './myapp.db', - schema: { - objects: { - tasks: { - fields: { - name: { type: 'text', required: true }, - owner: { type: 'lookup', reference_to: '_users' } - }, - permission_set: { - user_permission: { - allowCreate: true, - allowRead: true, - allowEdit: "owner eq $user.id", - allowDelete: "owner eq $user.id" + mode: 'server', + port: 3000, + + // Data Layer (ObjectQL) + data: { + driver: 'sqlite', + url: './myapp.db', + schema: { + objects: { + tasks: { + fields: { + title: { type: 'text', required: true }, + status: { type: 'select', options: ['todo', 'in_progress', 'done'] }, + owner: { type: 'lookup', reference_to: '_users' } + }, + permission_set: { + user: { + allowRead: true, + allowCreate: true, + allowEdit: 'owner eq $user.id', + allowDelete: 'owner eq $user.id' + } } } } } }, - pages: { - home: { - type: 'list', - object: 'tasks' + + // UI Layer (ObjectUI) + ui: { + pages: { + home: { + type: 'page', + title: 'My Tasks', + body: { + type: 'table', + object: 'tasks', + filters: [{ field: 'status', operator: 'ne', value: 'done' }], + columns: [ + { field: 'title', sortable: true }, + { field: 'status', type: 'badge' } + ], + actions: [ + { + label: 'Complete', + type: 'api_request', + api: '/api/tasks/{{row.id}}', + method: 'PATCH', + data: { status: 'done' } + } + ] + } + } + } + }, + + // Identity Layer + identity: { + authentication: { + providers: ['email'] + }, + authorization: { + defaultRole: 'user' } } }) // 2. Start the application -await app.start() - +await app.listen() console.log('ObjectOS running at http://localhost:3000') ``` -## Local-First Architecture +This creates a complete task management application with: +- SQLite database +- User authentication +- Permission-controlled task CRUD +- Automatic REST API +- Web interface +- All in ~50 lines of code -ObjectOS is designed with Local-First principles: +--- -- **Offline-First** - Applications work without network connectivity -- **User Ownership** - Data stays on user's device in standalone mode -- **Sync When Ready** - Optional synchronization with cloud services -- **Fast Performance** - SQLite-powered local storage +## Design Rationale -```typescript -// Local-First configuration -const app = new ObjectOS({ - mode: 'standalone', - storage: './local-data.db', - sync: { - enabled: false, // Fully offline - // Or enable sync: - // remote: 'https://sync.example.com', - // strategy: 'manual' - } -}) -``` +### Why QL-UI Binding? + +**Manual API development is tedious**. Automatic binding provides: + +- **Zero Boilerplate**: No need to write REST controllers +- **Type Safety**: ObjectQL schema enforces data contracts +- **Permission Enforcement**: RBAC applied automatically +- **Consistency**: All components follow same patterns + +### Why Built-in Identity? + +**Most applications need user management**. Built-in system provides: + +- **Standard Objects**: `_users`, `_roles`, `_permissions` objects +- **RBAC Out of Box**: No custom permission code +- **Field-Level Security**: Fine-grained access control +- **Integration Ready**: Pluggable auth providers (OAuth, LDAP, SAML) + +### Why Plugin Architecture? + +**Every application has unique needs**. Plugin system provides: + +- **Extensibility**: Add custom business logic without forking +- **Composability**: Combine plugins for complex workflows +- **Maintainability**: Plugins isolated from core platform +- **Community**: Share and reuse plugins across projects + +--- + +## Specification Compliance + +ObjectOS implementations must pass the **ObjectOS Compliance Test Suite**: + +- ✅ QL-UI binding with automatic data fetching +- ✅ User authentication and session management +- ✅ RBAC permission enforcement +- ✅ Field-level security filtering +- ✅ Plugin system with lifecycle hooks +- ✅ Standalone mode (.oos file execution) +- ✅ Server mode (HTTP API server) +- ✅ Multi-tenant mode (Virtual City isolation) + +Reference implementations: +- **Node.js**: [@objectstack/os](https://github.com/objectstack-ai/objectos) (JavaScript/TypeScript) +- **Python**: [objectos-py](https://github.com/objectstack-ai/objectos-py) (planned) +- **Go**: [objectos-go](https://github.com/objectstack-ai/objectos-go) (planned) + +--- ## Next Steps -Begin your ObjectOS journey: +1. **Understand Platform Architecture**: Read [Architecture](/docs/objectos/architecture) to learn how ObjectOS orchestrates QL and UI +2. **Setup Identity System**: Review [Identity & Access](/docs/objectos/identity-access) for user management and RBAC +3. **Deploy Your App**: Follow [Deployment Guide](/docs/objectos/deployment) for standalone, server, or multi-tenant modes +4. **Extend with Plugins**: Study [Plugin Development](/docs/objectos/plugins) to add custom business logic -- **New to ObjectOS?** Start with [Platform Architecture](/docs/objectos/platform-architecture) -- **Setting up security?** Jump to [Identity & Access](/docs/objectos/identity-access) -- **Ready to deploy?** Check [Deployment & Operations](/docs/objectos/deployment) +For philosophical context, see: +- **[The Manifesto](/docs/framework/manifesto)** - Why ObjectOS is local-first and plugin-based +- **[Architecture](/docs/framework/architecture)** - How ObjectOS completes the ObjectStack ecosystem diff --git a/content/docs/en/objectql/index.mdx b/content/docs/en/objectql/index.mdx index a051bfa..ea74a50 100644 --- a/content/docs/en/objectql/index.mdx +++ b/content/docs/en/objectql/index.mdx @@ -1,191 +1,642 @@ --- -title: ObjectQL - The Data Engine -description: Powerful data engine with schema-driven architecture and cross-database support +title: ObjectQL Protocol Specification +description: Database-Agnostic Data Protocol Engine - Schema Definition, Query DSL, and Driver Abstraction --- -# ObjectQL - The Data Engine +# ObjectQL: The Data Protocol Engine -ObjectQL is the core data engine of ObjectStack, providing a unified data access layer with schema-driven architecture, powerful query capabilities, and cross-database support. +ObjectQL is the **database-agnostic query engine** at the core of ObjectStack. It defines a universal JSON-based protocol for schema definition, data queries, and mutations that compiles to native SQL for any supported database. -## What is ObjectQL? +## Specification Overview -ObjectQL is a **declarative data engine** that allows you to define your data structure once and access it consistently across different database systems. It abstracts database complexity while preserving SQL power and performance. +ObjectQL is **not a database**—it is a **protocol specification** with reference implementations. The protocol defines: -### Key Capabilities +1. **Schema Definition Language**: JSON-based data model declarations +2. **Query DSL (Domain-Specific Language)**: Unified syntax for CRUD operations +3. **AST Compilation**: Abstract Syntax Tree for database-agnostic queries +4. **Driver Interface**: Standardized adapter contract for database engines -- 🗂️ **Schema-Driven Architecture** - Define data structures declaratively -- 🔍 **Unified Query DSL** - Query any database with consistent syntax -- ⚡ **Performance Optimized** - Virtual Column Index for SQLite, optimized drivers -- 🔄 **Cross-Database Support** - SQLite, MySQL, PostgreSQL, Oracle, SQL Server -- 🏗️ **Virtual City Mechanism** - Multi-tenant data isolation -- 🛡️ **Type Safety** - Strong typing for queries and results +### Core Design Principles -## How It Works +**Protocol Neutrality**: ObjectQL specifications are implementation-agnostic. The same protocol can be executed by: +- JavaScript engine (Node.js) +- Python engine (planned) +- Java engine (planned) +- Go engine (planned) -ObjectQL operates on three core principles: +**Database Agnostic**: The protocol never assumes a specific database. Concepts like "JSONB" (PostgreSQL) or "ROWNUM" (Oracle) do not exist in the protocol layer—they are handled by dialect-specific transpilers. -### 1. Schema Definition +**Mechanism, Not Policy**: ObjectQL defines *how to describe data operations*, not *how to implement* them. User authentication, validation logic, and business rules belong in ObjectOS. -Define your data structure using simple JavaScript objects: +--- + +## Protocol Architecture + +```mermaid +sequenceDiagram + participant App as Application + participant Engine as ObjectQL Engine + participant AST as AST Compiler + participant Transpiler as Dialect Transpiler + participant Driver as Database Driver + participant DB as Database + + App->>Engine: Query Protocol (JSON) + Engine->>AST: Parse to AST + AST->>Transpiler: Compile AST + Transpiler->>Driver: Database-Specific SQL + Driver->>DB: Execute Query + DB-->>Driver: Result Set + Driver-->>Engine: Normalized Response + Engine-->>App: Standard JSON Response +``` + +### Protocol Flow + +1. **Protocol Input**: Application sends JSON query protocol +2. **AST Parsing**: Engine parses protocol into Abstract Syntax Tree +3. **Dialect Compilation**: AST compiled to database-specific SQL +4. **Driver Execution**: Driver executes native SQL +5. **Response Normalization**: Results standardized to protocol format +6. **Protocol Output**: Application receives consistent JSON response + +This architecture ensures **complete database independence**—changing from MySQL to PostgreSQL requires zero application code changes. + +--- + +## Core Protocol Components + +### 1. Schema Definition Protocol + +Define data structures as declarative JSON specifications: ```typescript -const schema = { - objects: { - todos: { - fields: { - title: { type: 'text', required: true }, - completed: { type: 'boolean', defaultValue: false }, - due_date: { type: 'datetime' } - } +interface ObjectSchema { + name: string // Object identifier + label?: string // Human-readable name + fields: Record // Field definitions + indexes?: Index[] // Performance indexes + triggers?: Trigger[] // Lifecycle hooks + permission_set?: PermissionSet // Access control rules +} + +interface Field { + type: FieldType // Data type + label?: string // Display name + required?: boolean // Validation rule + unique?: boolean // Uniqueness constraint + defaultValue?: any // Default value + reference_to?: string // Relationship target (for lookup/master-detail) + formula?: string // Computed field expression +} + +type FieldType = + | 'text' | 'textarea' | 'number' | 'currency' | 'percent' + | 'date' | 'datetime' | 'time' + | 'boolean' | 'select' | 'multiselect' + | 'lookup' | 'master_detail' + | 'url' | 'email' | 'phone' + | 'autonumber' | 'formula' +``` + +**Example Schema**: +```json +{ + "objects": { + "orders": { + "label": "Sales Orders", + "fields": { + "order_number": { + "type": "autonumber", + "format": "ORD-{0000}" + }, + "customer": { + "type": "lookup", + "reference_to": "customers", + "required": true + }, + "order_date": { + "type": "date", + "defaultValue": "{{$now}}" + }, + "total_amount": { + "type": "currency", + "precision": 2 + }, + "status": { + "type": "select", + "options": ["draft", "confirmed", "shipped", "delivered"] + } + }, + "indexes": [ + { "fields": ["customer", "order_date"] }, + { "fields": ["status", "order_date"] } + ] } } } ``` -### 2. Query Execution +This schema is **database-agnostic**. ObjectQL will generate: +- **MySQL**: `CREATE TABLE` with `INT AUTO_INCREMENT`, `VARCHAR`, `DECIMAL`, `ENUM` +- **PostgreSQL**: `CREATE TABLE` with `SERIAL`, `VARCHAR`, `NUMERIC`, `TEXT` (with check constraint) +- **Oracle**: `CREATE TABLE` with `NUMBER` sequence trigger, `VARCHAR2`, `NUMBER`, `VARCHAR2` (with check constraint) +- **SQLite**: `CREATE TABLE` with `INTEGER PRIMARY KEY`, `TEXT`, `REAL`, `TEXT` (with check constraint) + +### 2. Query Protocol (DSL) -Query your data using an intuitive DSL: +Unified JSON syntax for all data operations: ```typescript -const activeTodos = await db.query('todos', { - filters: [['completed', '=', false]], - sort: 'due_date asc' -}) +interface QueryProtocol { + object: string // Target object name + fields?: string[] // Fields to return (default: all) + filters?: FilterExpression // WHERE clause + sort?: string | SortExpression // ORDER BY clause + top?: number // LIMIT clause + skip?: number // OFFSET clause + related?: RelatedQuery[] // JOIN/subquery expansion +} + +type FilterExpression = Filter | CompoundFilter + +interface Filter { + field: string + operator: Operator + value: any +} + +type Operator = + | 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte' + | 'startswith' | 'endswith' | 'contains' | 'notcontains' + | 'in' | 'notin' | 'between' + | 'isnull' | 'isnotnull' + +interface CompoundFilter { + and?: FilterExpression[] + or?: FilterExpression[] +} +``` + +**Example Queries**: + +```json +// Simple query +{ + "object": "orders", + "fields": ["order_number", "customer", "total_amount"], + "filters": { + "and": [ + { "field": "status", "operator": "eq", "value": "confirmed" }, + { "field": "order_date", "operator": "gte", "value": "2024-01-01" } + ] + }, + "sort": "order_date desc", + "top": 50 +} + +// Query with relationships +{ + "object": "orders", + "fields": ["order_number", "total_amount"], + "filters": { + "field": "customer.country", + "operator": "eq", + "value": "USA" + }, + "related": [ + { + "object": "order_items", + "foreign_key": "order_id", + "fields": ["product", "quantity", "unit_price"] + } + ] +} +``` + +### 3. Mutation Protocol + +Standardized operations for data modification: + +```typescript +interface MutationProtocol { + object: string + action: 'insert' | 'update' | 'delete' + data?: Record // For insert/update + filters?: FilterExpression // For update/delete +} ``` -### 3. Database Abstraction - -ObjectQL translates your queries to optimized SQL for the target database, handling dialect differences automatically. - -## Architecture Overview - -``` -┌─────────────────────────────────────────┐ -│ Application Layer │ -│ (Your Business Logic) │ -└────────────────┬────────────────────────┘ - │ - │ ObjectQL API - │ -┌────────────────▼────────────────────────┐ -│ ObjectQL Engine │ -│ ┌────────────┬──────────────────────┐ │ -│ │ Schema │ Query Processor │ │ -│ │ Registry │ & Optimizer │ │ -│ └────────────┴──────────────────────┘ │ -│ ┌──────────────────────────────────┐ │ -│ │ Virtual City Manager │ │ -│ │ (Multi-tenant Isolation) │ │ -│ └──────────────────────────────────┘ │ -└────────────────┬────────────────────────┘ - │ - │ Driver Abstraction - │ -┌────────────────▼────────────────────────┐ -│ Database Drivers │ -│ ┌──────┬──────┬──────┬──────┬──────┐ │ -│ │SQLite│MySQL │Postgres│Oracle│SQL │ │ -│ │ │ │ │ │Server│ │ -│ └──────┴──────┴──────┴──────┴──────┘ │ -└─────────────────────────────────────────┘ +**Example Mutations**: + +```json +// Insert +{ + "object": "orders", + "action": "insert", + "data": { + "customer": "CUST-001", + "order_date": "2024-03-15", + "total_amount": 1250.00, + "status": "confirmed" + } +} + +// Bulk update +{ + "object": "orders", + "action": "update", + "filters": { + "and": [ + { "field": "status", "operator": "eq", "value": "confirmed" }, + { "field": "order_date", "operator": "lt", "value": "2024-01-01" } + ] + }, + "data": { + "status": "archived" + } +} + +// Conditional delete +{ + "object": "orders", + "action": "delete", + "filters": { + "field": "status", + "operator": "eq", + "value": "cancelled" + } +} ``` +--- + +## Database Driver Interface + +ObjectQL defines a **standardized driver contract** that all database adapters must implement: + +```typescript +interface ObjectQLDriver { + // Connection management + connect(config: ConnectionConfig): Promise + disconnect(): Promise + + // Schema operations + createTable(schema: ObjectSchema): Promise + alterTable(schema: ObjectSchema, changes: SchemaChange[]): Promise + dropTable(objectName: string): Promise + + // Query operations + query(protocol: QueryProtocol): Promise + + // Mutation operations + insert(protocol: MutationProtocol): Promise + update(protocol: MutationProtocol): Promise + delete(protocol: MutationProtocol): Promise + + // Transaction management + beginTransaction(): Promise + commit(transaction: Transaction): Promise + rollback(transaction: Transaction): Promise + + // Dialect-specific compilation + compileAST(ast: ASTNode): string // Returns native SQL +} +``` + +### Supported Drivers + +Official reference implementations: + +| Driver | Status | Use Case | +|--------|--------|----------| +| **@objectql/driver-sqlite** | ✅ Stable | Local-first apps, development, edge computing | +| **@objectql/driver-mysql** | ✅ Stable | Web applications, cloud deployments | +| **@objectql/driver-postgres** | ✅ Stable | Enterprise systems, analytics workloads | +| **@objectql/driver-oracle** | 🚧 Beta | Legacy system integration | +| **@objectql/driver-sqlserver** | 🚧 Beta | Microsoft stack integration | + +Community drivers welcome—implement the `ObjectQLDriver` interface and publish as npm package. + +--- + +## Advanced Features + +### Virtual City (Multi-Tenancy) + +ObjectQL provides **protocol-level multi-tenancy** through the Virtual City mechanism: + +```typescript +// Each tenant gets isolated data context +const tenant1DB = engine.virtualCity('tenant_001') +const tenant2DB = engine.virtualCity('tenant_002') + +// Identical queries, isolated data +await tenant1DB.query('customers', {}) // Returns tenant_001's customers +await tenant2DB.query('customers', {}) // Returns tenant_002's customers +``` + +**Implementation**: Virtual City is a driver-level feature. MySQL/PostgreSQL implementations use schema separation, SQLite uses separate database files. + +### Virtual Column Index (Performance) + +For databases lacking native JSON indexing (e.g., SQLite), ObjectQL provides virtual column indexes: + +```json +{ + "objects": { + "products": { + "fields": { + "metadata": { "type": "text" } // Stores JSON + }, + "virtual_indexes": [ + { + "name": "idx_price", + "expression": "JSON_EXTRACT(metadata, '$.price')", + "type": "number" + } + ] + } + } +} +``` + +ObjectQL automatically creates indexed virtual columns for high-performance queries. + +### Formula Fields + +Computed fields defined in schema: + +```json +{ + "fields": { + "quantity": { "type": "number" }, + "unit_price": { "type": "currency" }, + "line_total": { + "type": "formula", + "formula": "quantity * unit_price", + "return_type": "currency" + } + } +} +``` + +Formula fields are **database-agnostic expressions** compiled to SQL `GENERATED` columns (PostgreSQL/MySQL) or computed in-memory (SQLite). + +### Aggregation Protocol + +Statistical queries with grouping: + +```json +{ + "object": "orders", + "aggregations": [ + { "field": "total_amount", "function": "sum", "alias": "revenue" }, + { "field": "order_number", "function": "count", "alias": "order_count" } + ], + "groupBy": ["customer", "status"], + "filters": { + "field": "order_date", + "operator": "gte", + "value": "2024-01-01" + } +} +``` + +Compiles to `GROUP BY` queries with appropriate aggregate functions across all databases. + +--- + ## Use Cases -### Local-First Applications +### 1. Local-First Applications -Use SQLite for personal applications: +**Scenario**: Personal productivity tools (notes, CRM, project management) +**Configuration**: ```typescript -const db = new ObjectQL({ - driver: 'sqlite', - url: './data/myapp.db' +import { ObjectQL } from '@objectql/core' +import { SQLiteDriver } from '@objectql/driver-sqlite' + +const engine = new ObjectQL({ + driver: new SQLiteDriver({ + database: './myapp.db' + }) }) ``` -### Enterprise Systems +**Benefits**: +- Zero server infrastructure +- Complete offline capability +- Data stored in local .db file +- Can upgrade to cloud database later without code changes + +### 2. Enterprise System Integration -Connect to existing databases: +**Scenario**: Unified API over heterogeneous legacy databases +**Configuration**: ```typescript -const db = new ObjectQL({ - driver: 'mysql', - url: 'mysql://user:pass@localhost:3306/mydb' +// Connect to existing Oracle ERP database +const erpDB = new ObjectQL({ + driver: new OracleDriver({ + host: 'oracle.company.com', + database: 'ERP_PROD' + }) +}) + +// Connect to SQL Server CRM database +const crmDB = new ObjectQL({ + driver: new SQLServerDriver({ + host: 'sqlserver.company.com', + database: 'CRM_PROD' + }) }) + +// Unified ObjectQL API for both +const erpCustomers = await erpDB.query('customers', {}) +const crmLeads = await crmDB.query('leads', {}) ``` -### Multi-Tenant SaaS +**Benefits**: +- Single query language for all systems +- No custom integration code per database +- Consistent error handling and validation +- Easier to maintain and test + +### 3. Multi-Tenant SaaS Platform -Leverage Virtual City for tenant isolation: +**Scenario**: SaaS application with tenant isolation +**Configuration**: ```typescript -const tenantDb = db.virtualCity('tenant_123') -const data = await tenantDb.query('customers', {}) +const engine = new ObjectQL({ + driver: new PostgreSQLDriver({ + host: 'postgres.cloud.com', + database: 'saas_platform' + }), + multiTenant: true +}) + +// Each tenant gets isolated context +app.use(async (req, res, next) => { + const tenantId = req.headers['x-tenant-id'] + req.db = engine.virtualCity(tenantId) + next() +}) + +// Automatic data isolation +router.get('/api/orders', async (req, res) => { + const orders = await req.db.query('orders', {}) + res.json(orders) // Only returns tenant's orders +}) ``` -## What You'll Learn +**Benefits**: +- Protocol-level tenant isolation +- No business logic needed for data segregation +- Can scale to schema-per-tenant or database-per-tenant +- ObjectQL handles routing automatically -In this section, you will discover: +--- -- ✅ **Core Concepts** - Understanding Schema and Virtual City mechanism -- ✅ **Protocol Specification** - Schema definition, Query DSL, and Aggregations -- ✅ **Core Features** - Virtual Column Index, driver adaptation, and optimizations -- ✅ **Server SDK** - Complete API reference with practical examples +## What You'll Learn -## Getting Started +This specification documentation covers: -Ready to dive in? Start with: +- ✅ **[Core Concepts](/docs/objectql/core-concepts)** - Schema, Virtual City, data types, relationships +- ✅ **[Protocol Specification](/docs/objectql/protocol-spec)** - Complete JSON schema reference for queries, mutations, aggregations +- ✅ **[Driver Development](/docs/objectql/driver-dev)** - Implementing custom database adapters +- ✅ **[Server SDK](/docs/objectql/server-sdk)** - Reference implementation API (JavaScript/Node.js) +- ✅ **[Performance Guide](/docs/objectql/performance)** - Optimization strategies, indexing, query analysis -1. **[Core Concepts](/docs/objectql/core-concepts)** - Understand the fundamental concepts -2. **[Protocol Spec](/docs/objectql/protocol-spec)** - Learn the schema and query language -3. **[Core Features](/docs/objectql/core-features)** - Explore advanced features -4. **[Server SDK](/docs/objectql/server-sdk)** - Master the API +--- -## Quick Example +## Quick Start Example -Here's a complete example to get you started: +Here's a complete end-to-end example: ```typescript import { ObjectQL } from '@objectql/core' +import { SQLiteDriver } from '@objectql/driver-sqlite' -// 1. Initialize ObjectQL -const db = new ObjectQL({ - driver: 'sqlite', - url: './myapp.db' +// 1. Initialize Engine +const engine = new ObjectQL({ + driver: new SQLiteDriver({ database: './todo.db' }) }) -// 2. Define Schema -await db.registerSchema({ +// 2. Register Schema +await engine.registerSchema({ objects: { tasks: { fields: { - name: { type: 'text', required: true }, - status: { type: 'select', options: ['todo', 'done'] }, - priority: { type: 'number' } + title: { type: 'text', required: true }, + completed: { type: 'boolean', defaultValue: false }, + priority: { type: 'select', options: ['high', 'medium', 'low'] }, + due_date: { type: 'date' } } } } }) // 3. Insert Data -await db.mutation('tasks', { +await engine.insert({ + object: 'tasks', action: 'insert', - data: { name: 'Learn ObjectQL', status: 'todo', priority: 1 } + data: { + title: 'Learn ObjectQL', + priority: 'high', + due_date: '2024-12-31' + } }) // 4. Query Data -const tasks = await db.query('tasks', { - filters: [['status', '=', 'todo']], - sort: 'priority desc' +const urgentTasks = await engine.query({ + object: 'tasks', + filters: { + and: [ + { field: 'completed', operator: 'eq', value: false }, + { field: 'priority', operator: 'eq', value: 'high' } + ] + }, + sort: 'due_date asc' +}) + +console.log(urgentTasks) +// [{ title: 'Learn ObjectQL', priority: 'high', completed: false, due_date: '2024-12-31' }] + +// 5. Switch to PostgreSQL (zero code changes) +const prodEngine = new ObjectQL({ + driver: new PostgreSQLDriver({ + url: 'postgresql://localhost/production' + }) }) -console.log(tasks) // [{ name: 'Learn ObjectQL', status: 'todo', priority: 1 }] +// Same schema, same queries, different database +await prodEngine.registerSchema(schema) +const sameTasks = await prodEngine.query(queryProtocol) ``` +--- + +## Design Rationale + +### Why JSON Protocols? + +**TypeScript/JavaScript SDKs are implementation details**. The real API is the JSON protocol: + +- **Language Agnostic**: Python, Java, Go can all implement ObjectQL +- **Network Transparent**: Protocols can be sent over HTTP, WebSockets, gRPC +- **Versionable**: Protocols are structured data, can be diffed and versioned +- **AI-Friendly**: LLMs can generate and modify JSON protocols easily + +### Why AST Compilation? + +**Direct SQL templating is fragile and insecure**. AST compilation provides: + +- **SQL Injection Protection**: Parameterized queries at AST level +- **Dialect Abstraction**: Single AST compiles to any SQL dialect +- **Query Optimization**: AST can be analyzed and optimized before execution +- **Consistent Semantics**: Same query behavior across all databases + +### Why Driver Abstraction? + +**Database APIs are inconsistent**. Driver interface provides: + +- **Unified Error Handling**: Consistent error types across databases +- **Connection Pooling**: Standard pool management regardless of driver +- **Transaction Semantics**: ACID guarantees with consistent API +- **Testing**: Mock drivers for unit tests without database + +--- + +## Specification Compliance + +ObjectQL implementations must pass the **ObjectQL Compliance Test Suite**: + +- ✅ Schema definition parsing and validation +- ✅ Query protocol execution for all operators +- ✅ Mutation protocol for insert/update/delete +- ✅ Relationship queries (lookup, master-detail) +- ✅ Aggregation queries with grouping +- ✅ Transaction management (ACID) +- ✅ Virtual City multi-tenant isolation +- ✅ Error handling and response formats + +Reference implementations: +- **JavaScript**: [@objectql/core](https://github.com/objectstack-ai/objectql) (Node.js) +- **Python**: [objectql-py](https://github.com/objectstack-ai/objectql-py) (planned) +- **Go**: [objectql-go](https://github.com/objectstack-ai/objectql-go) (planned) + +--- + ## Next Steps -Begin your ObjectQL journey: +1. **Understand Core Concepts**: Read [Core Concepts](/docs/objectql/core-concepts) to learn about schemas, relationships, and Virtual City +2. **Study the Protocol**: Review [Protocol Specification](/docs/objectql/protocol-spec) for complete JSON schema reference +3. **Build with SDK**: Use [Server SDK](/docs/objectql/server-sdk) to integrate ObjectQL in your application +4. **Optimize Performance**: Explore [Performance Guide](/docs/objectql/performance) for production best practices -- **New to ObjectQL?** Start with [Core Concepts](/docs/objectql/core-concepts) -- **Want to see the full API?** Jump to [Server SDK](/docs/objectql/server-sdk) -- **Need specific features?** Check [Core Features](/docs/objectql/core-features) +For philosophical context, see: +- **[The Manifesto](/docs/framework/manifesto)** - Why ObjectQL is protocol-driven and database-agnostic +- **[Architecture](/docs/framework/architecture)** - How ObjectQL fits into the ObjectStack ecosystem diff --git a/content/docs/en/objectui/index.mdx b/content/docs/en/objectui/index.mdx index 4724d32..6953503 100644 --- a/content/docs/en/objectui/index.mdx +++ b/content/docs/en/objectui/index.mdx @@ -1,216 +1,731 @@ --- -title: ObjectUI - The Interface Engine -description: Declarative UI engine with data-driven rendering and protocol-based components +title: ObjectUI Protocol Specification +description: Declarative Interface Engine - Component Protocols, Actions, and Renderer Abstraction --- -# ObjectUI - The Interface Engine +# ObjectUI: The Declarative Interface Engine -ObjectUI is the presentation layer of ObjectStack, providing a declarative UI engine that renders interfaces from JSON protocols. It transforms UI development from imperative code to data-driven declarations. +ObjectUI is the **presentation protocol** of ObjectStack. It defines a JSON-based specification for describing user interfaces declaratively, enabling UI as data rather than code. -## What is ObjectUI? +## Specification Overview -ObjectUI is a **declarative UI engine** that allows you to define user interfaces as JSON protocols instead of writing component code. It provides a complete set of pre-built components that render automatically based on data specifications. +ObjectUI is **not a component library**—it is a **protocol specification** with renderer implementations. The protocol defines: -### Key Capabilities +1. **Component Protocol**: JSON schemas for UI elements (forms, tables, grids, pages) +2. **Action Protocol**: Declarative event handlers (API calls, navigation, dialogs) +3. **Data Binding Protocol**: Automatic synchronization with ObjectQL data layer +4. **Renderer Interface**: Standardized contract for framework implementations -- 🎨 **Declarative UI** - Define interfaces with JSON instead of JSX/code -- 🔄 **Data-Driven Rendering** - UI automatically reflects data changes -- 📦 **Component Protocol** - Rich set of pre-built components -- 🎭 **Theme Support** - Customizable styles and themes -- ⚡ **Performance Optimized** - Smart rendering and updates -- 🔌 **Framework Agnostic** - React renderer with others planned +### Core Design Principles -## How It Works +**Protocol Neutrality**: ObjectUI specifications are renderer-agnostic. The same protocol can be rendered by: +- React renderer (reference implementation) +- Vue renderer (planned) +- Flutter renderer (planned) +- Native mobile renderers (planned) -ObjectUI operates on a simple principle: **UI as Data**. +**Declarative, Not Imperative**: ObjectUI describes *what* to render, not *how* to render it. There are no `onClick` callbacks or `useState` hooks in the protocol—only data structures. -### 1. Define UI Protocol +**Data-Driven**: UI components are bound to ObjectQL data sources. State management, validation, and updates are handled automatically by the renderer. -Describe your interface using JSON: +**Framework Agnostic**: The protocol never assumes React, Vue, or any specific framework. Renderers translate protocols to framework-specific implementations. +--- + +## Protocol Architecture + +```mermaid +sequenceDiagram + participant App as Application + participant Renderer as ObjectUI Renderer + participant Parser as Protocol Parser + participant Component as Component Registry + participant DataLayer as ObjectQL Data Layer + + App->>Renderer: UI Protocol (JSON) + Renderer->>Parser: Parse Protocol + Parser->>Component: Resolve Components + Component->>DataLayer: Bind Data Sources + DataLayer-->>Component: Data Response + Component-->>Renderer: Rendered UI + Renderer-->>App: Interactive Interface + + Note over App,DataLayer: User Interaction + App->>Renderer: User Action + Renderer->>DataLayer: Execute Action (API call) + DataLayer-->>Renderer: Updated Data + Renderer-->>App: Re-render UI +``` + +### Protocol Flow + +1. **Protocol Input**: Application provides JSON UI protocol +2. **Protocol Parsing**: Renderer parses and validates protocol structure +3. **Component Resolution**: Maps protocol types to framework components +4. **Data Binding**: Connects components to ObjectQL data sources +5. **Rendering**: Framework-specific components rendered +6. **Action Handling**: User interactions trigger protocol-defined actions +7. **State Update**: Data changes trigger automatic re-rendering + +This architecture ensures **complete framework independence**—changing from React to Vue requires zero protocol changes. + +--- + +## Core Protocol Components + +### 1. Component Protocol + +Define UI elements as declarative JSON specifications: + +```typescript +interface ComponentProtocol { + type: ComponentType // Component identifier + id?: string // Unique component ID + name?: string // Field name (for form inputs) + label?: string // Display label + visible?: boolean | Expression // Conditional visibility + disabled?: boolean | Expression // Conditional disabled state + style?: StyleProperties // Custom styling + children?: ComponentProtocol[] // Nested components +} + +type ComponentType = + // Container Components + | 'page' | 'card' | 'grid' | 'form' | 'table' | 'list' + // Input Components + | 'input' | 'textarea' | 'select' | 'multiselect' | 'checkbox' | 'switch' + | 'datepicker' | 'timepicker' | 'datetimepicker' + | 'number' | 'currency' | 'percent' + // Display Components + | 'text' | 'heading' | 'image' | 'icon' | 'badge' | 'avatar' + // Action Components + | 'button' | 'link' | 'dropdown' +``` +**Example: Page Component**: ```json { "type": "page", - "title": "Todo List", + "title": "Customer Management", + "description": "Manage customer records", "body": { - "type": "form", - "fields": [ + "type": "grid", + "columns": 2, + "gap": 4, + "items": [ { - "name": "title", - "type": "input", - "label": "Task Name", - "required": true + "type": "card", + "title": "Customer List", + "body": { + "type": "table", + "object": "customers", + "columns": [ + { "field": "name", "label": "Name", "sortable": true }, + { "field": "email", "label": "Email" }, + { "field": "status", "label": "Status", "type": "badge" } + ] + } }, { - "name": "priority", - "type": "select", - "label": "Priority", - "options": ["High", "Medium", "Low"] + "type": "card", + "title": "Add Customer", + "body": { + "type": "form", + "object": "customers", + "action": "insert", + "fields": [ + { "name": "name", "type": "input", "required": true }, + { "name": "email", "type": "input", "inputType": "email" }, + { "name": "status", "type": "select", "options": ["active", "inactive"] } + ] + } } ] } } ``` -### 2. Render with ObjectUI +### 2. Form Protocol -Pass the protocol to the renderer: +Rich form definition with validation and data binding: -```tsx -import { ObjectUIRenderer } from '@objectstack/react-renderer' +```typescript +interface FormProtocol extends ComponentProtocol { + type: 'form' + object?: string // ObjectQL object name + api?: string // Custom API endpoint + method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' + action?: 'insert' | 'update' | 'delete' // ObjectQL action + fields: FieldProtocol[] // Form fields + initialValues?: Record // Default values + submitText?: string // Submit button label + resetText?: string // Reset button label + onSuccess?: ActionProtocol // Success handler + onError?: ActionProtocol // Error handler +} -function App() { - return +interface FieldProtocol extends ComponentProtocol { + name: string // Field identifier + type: ComponentType // Input type + label?: string // Display label + placeholder?: string // Placeholder text + required?: boolean // Validation rule + validation?: ValidationRule[] // Custom validation + dependsOn?: string // Dependent field + visible?: Expression // Conditional visibility + disabled?: Expression // Conditional disabled state +} + +interface ValidationRule { + type: 'required' | 'email' | 'url' | 'min' | 'max' | 'pattern' | 'custom' + value?: any // Rule parameter + message: string // Error message +} +``` + +**Example: Complex Form**: +```json +{ + "type": "form", + "object": "orders", + "action": "insert", + "fields": [ + { + "name": "customer", + "type": "select", + "label": "Customer", + "required": true, + "api": "/api/customers", + "displayField": "name", + "valueField": "id" + }, + { + "name": "order_date", + "type": "datepicker", + "label": "Order Date", + "defaultValue": "{{$now}}", + "required": true + }, + { + "name": "items", + "type": "table", + "label": "Order Items", + "columns": [ + { + "field": "product", + "type": "select", + "api": "/api/products", + "required": true + }, + { "field": "quantity", "type": "number", "min": 1 }, + { + "field": "unit_price", + "type": "currency", + "disabled": true, + "formula": "{{product.price}}" + }, + { + "field": "total", + "type": "currency", + "disabled": true, + "formula": "{{quantity * unit_price}}" + } + ] + }, + { + "name": "grand_total", + "type": "currency", + "label": "Grand Total", + "disabled": true, + "formula": "{{SUM(items, 'total')}}" + } + ], + "submitText": "Create Order", + "onSuccess": { + "type": "navigate", + "path": "/orders/{{response.id}}" + } } ``` -### 3. Automatic UI Generation +### 3. Table Protocol -ObjectUI renders a fully functional interface with forms, validation, actions, and state management—all from the JSON protocol. +Data grid with sorting, filtering, pagination: -## Architecture Overview +```typescript +interface TableProtocol extends ComponentProtocol { + type: 'table' + object?: string // ObjectQL object name + api?: string // Custom API endpoint + columns: ColumnProtocol[] // Column definitions + filters?: FilterProtocol[] // Pre-defined filters + searchable?: boolean // Enable search bar + sortable?: boolean // Enable column sorting + paginated?: boolean // Enable pagination + pageSize?: number // Rows per page + selectable?: boolean // Enable row selection + actions?: ActionProtocol[] // Row actions + bulkActions?: ActionProtocol[] // Bulk actions +} +interface ColumnProtocol { + field: string // Data field name + label: string // Column header + type?: 'text' | 'number' | 'date' | 'boolean' | 'badge' | 'avatar' | 'custom' + sortable?: boolean // Enable sorting + filterable?: boolean // Enable filtering + width?: string // Column width + align?: 'left' | 'center' | 'right' + formatter?: Expression // Custom formatting + visible?: boolean | Expression // Conditional visibility +} ``` -┌─────────────────────────────────────────┐ -│ Application Layer │ -│ (Business Logic) │ -└────────────────┬────────────────────────┘ - │ - │ UI Protocol (JSON) - │ -┌────────────────▼────────────────────────┐ -│ ObjectUI Engine │ -│ ┌────────────┬──────────────────────┐ │ -│ │ Protocol │ Component │ │ -│ │ Parser │ Registry │ │ -│ └────────────┴──────────────────────┘ │ -│ ┌──────────────────────────────────┐ │ -│ │ Render Coordinator │ │ -│ │ (State & Actions) │ │ -│ └──────────────────────────────────┘ │ -└────────────────┬────────────────────────┘ - │ - │ Component Instances - │ -┌────────────────▼────────────────────────┐ -│ React Renderer │ -│ ┌──────┬──────┬──────┬──────┬──────┐ │ -│ │Input │Select│Table │Form │Page │ │ -│ │ │ │ │ │ │ │ -│ └──────┴──────┴──────┴──────┴──────┘ │ -└─────────────────────────────────────────┘ + +**Example: Advanced Table**: +```json +{ + "type": "table", + "object": "products", + "columns": [ + { + "field": "image", + "label": "Image", + "type": "avatar", + "width": "60px" + }, + { + "field": "name", + "label": "Product Name", + "sortable": true, + "filterable": true + }, + { + "field": "category", + "label": "Category", + "type": "badge", + "sortable": true + }, + { + "field": "price", + "label": "Price", + "type": "currency", + "sortable": true, + "align": "right" + }, + { + "field": "stock", + "label": "Stock", + "type": "number", + "sortable": true, + "align": "right", + "formatter": "{{value > 10 ? 'In Stock' : 'Low Stock'}}" + }, + { + "field": "status", + "label": "Status", + "type": "badge", + "filterable": true + } + ], + "filters": [ + { "field": "status", "operator": "eq", "value": "active" } + ], + "searchable": true, + "sortable": true, + "paginated": true, + "pageSize": 50, + "selectable": true, + "actions": [ + { + "label": "Edit", + "type": "navigate", + "path": "/products/{{row.id}}/edit" + }, + { + "label": "Delete", + "type": "api_request", + "api": "/api/products/{{row.id}}", + "method": "DELETE", + "confirm": { + "title": "Delete Product", + "message": "Are you sure you want to delete {{row.name}}?" + } + } + ], + "bulkActions": [ + { + "label": "Activate", + "type": "api_request", + "api": "/api/products/bulk-update", + "method": "PATCH", + "data": { "status": "active" } + }, + { + "label": "Deactivate", + "type": "api_request", + "api": "/api/products/bulk-update", + "method": "PATCH", + "data": { "status": "inactive" } + } + ] +} ``` -## Core Concepts +### 4. Action Protocol -### Declarative vs Imperative +Declarative event handling without imperative code: -**Imperative UI (Traditional):** -```tsx -// Write code to describe HOW to build UI -function TodoForm() { - const [title, setTitle] = useState('') - const [priority, setPriority] = useState('') - - const handleSubmit = (e) => { - e.preventDefault() - // Submit logic... +```typescript +interface ActionProtocol { + type: ActionType + label?: string // Button/link text + icon?: string // Icon name + confirm?: ConfirmDialog // Confirmation dialog + condition?: Expression // Conditional execution +} + +type ActionType = + | APIRequestAction + | NavigateAction + | DialogAction + | ToastAction + | RefreshAction + | CustomAction + +interface APIRequestAction extends ActionProtocol { + type: 'api_request' + api: string // API endpoint + method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' + data?: Record // Request body + params?: Record // Query parameters + onSuccess?: ActionProtocol // Success handler + onError?: ActionProtocol // Error handler +} + +interface NavigateAction extends ActionProtocol { + type: 'navigate' + path: string // Navigation path + target?: '_self' | '_blank' // Target window +} + +interface DialogAction extends ActionProtocol { + type: 'dialog' + title: string // Dialog title + content: ComponentProtocol // Dialog body + width?: string // Dialog width + actions?: ActionProtocol[] // Dialog actions +} + +interface ToastAction extends ActionProtocol { + type: 'toast' + message: string // Toast message + variant?: 'success' | 'error' | 'warning' | 'info' + duration?: number // Display duration (ms) +} +``` + +**Example: Action Chain**: +```json +{ + "type": "button", + "label": "Approve Order", + "action": { + "type": "api_request", + "api": "/api/orders/{{order.id}}/approve", + "method": "POST", + "confirm": { + "title": "Approve Order", + "message": "Are you sure you want to approve order #{{order.order_number}}?" + }, + "onSuccess": { + "type": "toast", + "message": "Order approved successfully", + "variant": "success", + "next": { + "type": "navigate", + "path": "/orders" + } + }, + "onError": { + "type": "toast", + "message": "Failed to approve order: {{error.message}}", + "variant": "error" + } } - - return ( -
- setTitle(e.target.value)} - /> - - -
- ) } ``` -**Declarative UI (ObjectUI):** +### 5. Expression Language + +Dynamic values and conditional logic: + +```typescript +type Expression = string // Format: {{expression}} + +// Variable References +"{{field_name}}" // Current form field +"{{row.field_name}}" // Table row data +"{{$user.id}}" // Current user +"{{$now}}" // Current timestamp +"{{$env.API_URL}}" // Environment variable + +// Operators +"{{value > 10}}" // Comparison +"{{status === 'active'}}" // Equality +"{{price * quantity}}" // Arithmetic +"{{firstname + ' ' + lastname}}" // Concatenation + +// Functions +"{{SUM(items, 'total')}}" // Array aggregation +"{{FILTER(items, 'status eq active')}}" // Array filtering +"{{FORMAT(date, 'YYYY-MM-DD')}}" // Formatting +"{{LOOKUP('products', product_id, 'name')}}" // Data lookup + +// Conditional +"{{status === 'active' ? 'Active' : 'Inactive'}}" // Ternary +``` + +**Example: Dynamic Form**: ```json { "type": "form", - "api": "/api/todos", "fields": [ - { "name": "title", "type": "input", "required": true }, - { "name": "priority", "type": "select", "options": ["High", "Medium", "Low"] } + { + "name": "customer_type", + "type": "select", + "options": ["individual", "business"] + }, + { + "name": "first_name", + "type": "input", + "label": "First Name", + "visible": "{{customer_type === 'individual'}}", + "required": "{{customer_type === 'individual'}}" + }, + { + "name": "last_name", + "type": "input", + "label": "Last Name", + "visible": "{{customer_type === 'individual'}}", + "required": "{{customer_type === 'individual'}}" + }, + { + "name": "company_name", + "type": "input", + "label": "Company Name", + "visible": "{{customer_type === 'business'}}", + "required": "{{customer_type === 'business'}}" + }, + { + "name": "tax_id", + "type": "input", + "label": "Tax ID", + "visible": "{{customer_type === 'business'}}", + "validation": [ + { + "type": "pattern", + "value": "^[0-9]{9}$", + "message": "Tax ID must be 9 digits" + } + ] + } ] } ``` -The declarative approach: -- ✅ Less code to write and maintain -- ✅ Easier to understand and modify -- ✅ Can be generated, stored, and versioned as data -- ✅ Enables dynamic UI generation +--- + +## Renderer Interface + +ObjectUI defines a **standardized renderer contract** that all framework implementations must support: + +```typescript +interface ObjectUIRenderer { + // Core rendering + render(protocol: ComponentProtocol, container: HTMLElement): RenderedComponent + unmount(component: RenderedComponent): void + + // Component registration + registerComponent(type: ComponentType, implementation: ComponentImplementation): void + + // Action handling + registerActionHandler(type: ActionType, handler: ActionHandler): void + + // Data binding + bindDataSource(component: RenderedComponent, source: DataSource): void + + // Theme management + setTheme(theme: ThemeConfig): void + + // Lifecycle hooks + onMount?(component: RenderedComponent): void + onUpdate?(component: RenderedComponent, changes: PropertyChanges): void + onUnmount?(component: RenderedComponent): void +} +``` + +### Supported Renderers + +Official reference implementations: + +| Renderer | Status | Framework | +|----------|--------|-----------| +| **@objectui/react-renderer** | ✅ Stable | React 18+ | +| **@objectui/vue-renderer** | 🚧 Planned | Vue 3+ | +| **@objectui/flutter-renderer** | 🚧 Planned | Flutter | +| **@objectui/native-renderer** | 🚧 Planned | React Native | + +Community renderers welcome—implement the `ObjectUIRenderer` interface and publish as npm package. -### Data-Driven Rendering +--- + +## Advanced Features -ObjectUI components are **data-driven**: +### Component Composition -1. **Protocol defines structure** - JSON describes what to render -2. **Data defines content** - Component fetches or receives data -3. **State triggers updates** - Changes automatically re-render +Build complex UIs from simple components: ```json { - "type": "table", - "api": "/api/users", - "columns": [ - { "name": "name", "label": "Name" }, - { "name": "email", "label": "Email" }, - { "name": "status", "label": "Status" } - ] + "type": "page", + "title": "Dashboard", + "body": { + "type": "grid", + "columns": 3, + "items": [ + { + "type": "card", + "title": "Total Revenue", + "body": { + "type": "text", + "value": "{{SUM(orders, 'total_amount')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + }, + { + "type": "card", + "title": "Active Users", + "body": { + "type": "text", + "value": "{{COUNT(users, 'status eq active')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + }, + { + "type": "card", + "title": "Pending Orders", + "body": { + "type": "text", + "value": "{{COUNT(orders, 'status eq pending')}}", + "style": { "fontSize": "2rem", "fontWeight": "bold" } + } + } + ] + } +} +``` + +### Responsive Layouts + +Automatic adaptation to screen sizes: + +```json +{ + "type": "grid", + "columns": { "mobile": 1, "tablet": 2, "desktop": 4 }, + "gap": { "mobile": 2, "tablet": 3, "desktop": 4 }, + "items": [...] +} +``` + +### Custom Components + +Extend the component library: + +```typescript +// Register custom component in renderer +renderer.registerComponent('chart', ChartComponent) + +// Use in protocol +{ + "type": "chart", + "chartType": "line", + "data": "{{monthly_revenue}}", + "xAxis": "month", + "yAxis": "revenue" } ``` -This table: -- Automatically fetches data from `/api/users` -- Renders columns as specified -- Handles pagination, sorting, filtering -- Updates when data changes +### Theme System + +Customize appearance without changing structure: + +```typescript +renderer.setTheme({ + colors: { + primary: '#007bff', + secondary: '#6c757d', + success: '#28a745', + error: '#dc3545' + }, + fonts: { + body: 'Inter, sans-serif', + heading: 'Poppins, sans-serif' + }, + spacing: { + unit: 8 // 8px base unit + } +}) +``` + +--- ## Use Cases -### Admin Panels +### 1. Admin Panels & Dashboards -Build complete admin interfaces without writing UI code: +**Scenario**: Build complete admin interfaces without writing UI code +**Protocol**: ```json { "type": "page", "title": "User Management", "body": { - "type": "crud", - "api": "/api/users", - "columns": [...], - "filters": [...], - "actions": [...] + "type": "table", + "object": "users", + "columns": [ + { "field": "avatar", "type": "avatar" }, + { "field": "name", "sortable": true }, + { "field": "email", "sortable": true }, + { "field": "role", "type": "badge" }, + { "field": "created_at", "type": "date", "sortable": true } + ], + "actions": [ + { "label": "Edit", "type": "navigate", "path": "/users/{{row.id}}/edit" }, + { "label": "Delete", "type": "api_request", "api": "/api/users/{{row.id}}", "method": "DELETE" } + ] } } ``` -### Dynamic Forms +**Benefits**: +- No React/Vue code required +- Automatic CRUD operations +- Built-in pagination, sorting, filtering +- Can be stored in database and versioned -Create forms that adapt based on configuration: +### 2. Dynamic Forms +**Scenario**: Forms that adapt based on configuration or user permissions + +**Protocol**: ```json { "type": "form", - "api": "/api/submit", + "object": "leads", "fields": [ { "name": "name", "type": "input", "required": true }, + { "name": "email", "type": "input", "inputType": "email" }, { "name": "country", "type": "select", @@ -219,96 +734,192 @@ Create forms that adapt based on configuration: { "name": "state", "type": "select", - "api": "/api/states", + "api": "/api/states?country={{country}}", + "visible": "{{country !== null}}", "dependsOn": "country" + }, + { + "name": "budget", + "type": "currency", + "visible": "{{$user.role === 'sales' || $user.role === 'admin'}}" } ] } ``` -### Low-Code Platforms +**Benefits**: +- Form structure stored as data +- Easy to modify without code deployment +- Permission-based field visibility +- Dependent field logic + +### 3. Low-Code / No-Code Platforms -Enable users to build interfaces through configuration: +**Scenario**: Enable non-developers to build interfaces +**Implementation**: ```typescript // Store UI protocol in database -await db.mutation('pages', { +await db.insert({ + object: 'pages', action: 'insert', data: { - name: 'dashboard', - protocol: { type: 'page', ... } + name: 'customer_dashboard', + protocol: { + type: 'page', + title: 'Customer Dashboard', + body: { ... } + } } }) -// Render from database -const page = await db.query('pages', { filters: [['name', '=', 'dashboard']] }) -return +// Fetch and render +const page = await db.query({ + object: 'pages', + filters: [{ field: 'name', operator: 'eq', value: 'customer_dashboard' }] +}) + +return ``` -## What You'll Learn +**Benefits**: +- UI definitions versionable like data +- Can build visual UI builders +- AI can generate protocols +- Easy to A/B test UI variations + +### 4. Mobile Applications + +**Scenario**: Same protocol, different renderer -In this section, you will discover: +**React Native**: +```tsx +import { ObjectUIRenderer } from '@objectui/native-renderer' + +function App() { + return +} +``` + +**Flutter**: +```dart +import 'package:objectui_flutter/objectui_flutter.dart'; -- ✅ **Core Concepts** - Understanding declarative UI and data-driven rendering -- ✅ **Component Specification** - Complete protocol reference for all components -- ✅ **Renderer Usage** - How to integrate ObjectUI in React applications -- ✅ **Customization** - Theming, styling, and extending components +Widget build(BuildContext context) { + return ObjectUIRenderer(protocol: uiProtocol); +} +``` + +**Benefits**: +- Write UI protocol once +- Render on web, iOS, Android +- Consistent behavior across platforms +- Share business logic -## Getting Started +--- -Ready to dive in? Start with: +## What You'll Learn -1. **[Core Concepts](/docs/objectui/core-concepts)** - Understand declarative UI principles -2. **[Component Spec](/docs/objectui/component-spec)** - Learn the component protocols -3. **[Renderer Usage](/docs/objectui/renderer-usage)** - Integrate in your application +This specification documentation covers: -## Quick Example +- ✅ **[Core Concepts](/docs/objectui/core-concepts)** - Declarative UI, data binding, component composition +- ✅ **[Component Specification](/docs/objectui/component-spec)** - Complete JSON schema reference for all components +- ✅ **[Actions](/docs/objectui/actions)** - Action protocol specifications (API, navigation, dialogs) +- ✅ **[Renderer Usage](/docs/objectui/renderer-usage)** - Integrating ObjectUI in React/Vue/Flutter applications +- ✅ **[Theming](/docs/objectui/theming)** - Customizing appearance and styles +- ✅ **[Best Practices](/docs/objectui/best-practices)** - Design patterns and optimization strategies -Here's a complete example to get you started: +--- + +## Quick Start Example + +Here's a complete end-to-end example: ```tsx -import { ObjectUIRenderer } from '@objectstack/react-renderer' +import { ObjectUIRenderer } from '@objectui/react-renderer' +import '@objectui/react-renderer/styles.css' // 1. Define UI Protocol const todoApp = { type: 'page', - title: 'My Todos', + title: 'Todo Application', body: { type: 'grid', columns: 2, + gap: 4, items: [ + // Add Todo Form { - type: 'form', - title: 'Add Todo', - api: '/api/todos', - method: 'POST', - fields: [ - { - name: 'title', - type: 'input', - label: 'Task', - required: true - }, - { - name: 'completed', - type: 'switch', - label: 'Completed', - defaultValue: false + type: 'card', + title: 'Add Task', + body: { + type: 'form', + object: 'todos', + action: 'insert', + fields: [ + { + name: 'title', + type: 'input', + label: 'Task Name', + required: true + }, + { + name: 'priority', + type: 'select', + label: 'Priority', + options: ['high', 'medium', 'low'], + defaultValue: 'medium' + }, + { + name: 'due_date', + type: 'datepicker', + label: 'Due Date' + } + ], + submitText: 'Add Task', + onSuccess: { + type: 'toast', + message: 'Task created successfully', + variant: 'success' } - ], - submitText: 'Add Task' + } }, + // Todo List Table { - type: 'table', - title: 'Todo List', - api: '/api/todos', - columns: [ - { name: 'title', label: 'Task' }, - { name: 'completed', label: 'Done', type: 'boolean' } - ], - actions: [ - { label: 'Delete', api: '/api/todos/${id}', method: 'DELETE' } - ] + type: 'card', + title: 'My Tasks', + body: { + type: 'table', + object: 'todos', + filters: [ + { field: 'completed', operator: 'eq', value: false } + ], + columns: [ + { field: 'title', label: 'Task', sortable: true }, + { field: 'priority', label: 'Priority', type: 'badge' }, + { field: 'due_date', label: 'Due Date', type: 'date', sortable: true }, + { field: 'completed', label: 'Done', type: 'boolean' } + ], + actions: [ + { + label: 'Complete', + type: 'api_request', + api: '/api/todos/{{row.id}}', + method: 'PATCH', + data: { completed: true } + }, + { + label: 'Delete', + type: 'api_request', + api: '/api/todos/{{row.id}}', + method: 'DELETE', + confirm: { + title: 'Delete Task', + message: 'Are you sure?' + } + } + ] + } } ] } @@ -316,20 +927,80 @@ const todoApp = { // 2. Render function App() { - return + return } + +export default App ``` This creates a fully functional todo application with: -- A form to add todos -- A table showing all todos -- Delete actions for each todo -- Automatic data fetching and updates +- Form to add tasks +- Table showing active tasks +- Complete and delete actions +- Automatic data fetching from ObjectQL +- No imperative React code required + +--- + +## Design Rationale + +### Why JSON Protocols? + +**React/Vue components are implementation details**. The real UI is the JSON protocol: + +- **Framework Agnostic**: Same protocol renders in React, Vue, Flutter +- **Versionable**: UI stored as structured data in database +- **AI-Friendly**: LLMs excel at generating JSON structures +- **Portable**: Export/import UI definitions between projects + +### Why Declarative? + +**Imperative UI code is fragile and verbose**. Declarative protocols provide: + +- **Maintainability**: Change structure, not code +- **Consistency**: All forms/tables follow same patterns +- **Testability**: Protocols are data, easily validated +- **Composition**: Build complex UIs from simple building blocks + +### Why Data-Driven? + +**Manual state management is error-prone**. Automatic data binding provides: + +- **Consistency**: UI always reflects data state +- **Less Code**: No useState, useEffect, or state management libraries +- **Performance**: Smart diffing and updates handled by renderer +- **Simplicity**: Developers focus on structure, not synchronization + +--- + +## Specification Compliance + +ObjectUI renderers must pass the **ObjectUI Compliance Test Suite**: + +- ✅ Protocol parsing and validation +- ✅ All component types rendering correctly +- ✅ Action execution and error handling +- ✅ Data binding and updates +- ✅ Expression evaluation +- ✅ Conditional visibility and disabled states +- ✅ Form validation and submission +- ✅ Table sorting, filtering, pagination +- ✅ Responsive layouts + +Reference implementations: +- **React**: [@objectui/react-renderer](https://github.com/objectstack-ai/objectui) (React 18+) +- **Vue**: [@objectui/vue-renderer](https://github.com/objectstack-ai/objectui-vue) (planned) +- **Flutter**: [objectui_flutter](https://github.com/objectstack-ai/objectui-flutter) (planned) + +--- ## Next Steps -Begin your ObjectUI journey: +1. **Understand Core Concepts**: Read [Core Concepts](/docs/objectui/core-concepts) to learn declarative UI principles +2. **Study Component Protocols**: Review [Component Specification](/docs/objectui/component-spec) for complete reference +3. **Build with Renderer**: Use [Renderer Usage](/docs/objectui/renderer-usage) to integrate ObjectUI in your application +4. **Customize Appearance**: Explore [Theming](/docs/objectui/theming) for styling and customization -- **New to declarative UI?** Start with [Core Concepts](/docs/objectui/core-concepts) -- **Need component reference?** Jump to [Component Spec](/docs/objectui/component-spec) -- **Ready to build?** Check [Renderer Usage](/docs/objectui/renderer-usage) +For philosophical context, see: +- **[The Manifesto](/docs/framework/manifesto)** - Why ObjectUI is protocol-driven and framework-agnostic +- **[Architecture](/docs/framework/architecture)** - How ObjectUI fits into the ObjectStack ecosystem diff --git a/content/docs/index.mdx b/content/docs/index.mdx index 7f6b172..11ba372 100644 --- a/content/docs/index.mdx +++ b/content/docs/index.mdx @@ -1,32 +1,261 @@ --- -title: Introduction -description: ObjectStack - The Protocol-Driven Development Platform +title: ObjectStack Specification +description: Protocol-Driven, Local-First, Database-Agnostic Full-Stack Development Platform --- -# ObjectStack Documentation +# ObjectStack Platform Specification -**ObjectStack** is a full-stack, local-first development platform designed for **data sovereignty** and **technical decoupling**. +**ObjectStack** is a protocol-driven full-stack development platform that separates business logic from technical implementation through standardized JSON protocols. It enables developers to build portable, database-agnostic applications with complete data sovereignty. -It standardizes the development process using a "Protocol-Driven" architecture, separating business logic from technical implementation. +## Core Architecture Principles -## Core Products +ObjectStack is built on three unshakable pillars: -ObjectStack consists of three integrated engines: +### 1. Protocol-Driven Architecture +Logic resides in **declarative protocols** (JSON), not in imperative code. Business definitions are data, not functions. This enables: +- **Portability**: Protocols are language and framework agnostic +- **Composability**: Complex systems built from simple, declarative blocks +- **AI-Generation**: 80% of application code generated from protocol specifications +- **Version Control**: Business logic versioned as structured data -### ObjectQL (Backend) -[ObjectQL](/docs/objectql): The universal data protocol. Define your data models once in JSON schema, and run them on any database (SQLite, PostgreSQL, Oracle, etc.). +### 2. Local-First by Design +Applications work **offline by default**. Cloud connectivity is optional, not mandatory. This ensures: +- **Data Sovereignty**: Users own their data, not platforms +- **Zero Vendor Lock-in**: Data exportable in standard formats (.oos, .json) +- **Privacy by Default**: No telemetry or cloud dependencies required +- **Resilience**: Applications function without network connectivity -### ObjectUI (Frontend) -[ObjectUI](/docs/objectui): The declarative UI engine. Render enterprise-grade interfaces directly from your data protocols without writing repetitive component code. +### 3. Database Agnostic +Write once, run on **any database**. ObjectQL abstracts the data layer completely: +- **Cross-Database Protocol**: Single query syntax for MySQL, PostgreSQL, Oracle, SQLite, SQL Server +- **Zero Migration Cost**: Switch databases without changing application code +- **Dialect Abstraction**: Engine handles database-specific SQL generation +- **Unified Driver Interface**: Consistent API regardless of underlying storage -### ObjectOS (Runtime) -[ObjectOS](/docs/objectos): The operating system for your apps. Binds ObjectQL and ObjectUI together with built-in identity management, security, and access control. +--- + +## Platform Components + +ObjectStack consists of three decoupled engines that communicate via standardized JSON protocols: + +```mermaid +graph TB + subgraph "Application Layer" + App[Your Application] + end + + subgraph "ObjectStack Platform" + OS[ObjectOS
Runtime & Orchestration] + UI[ObjectUI
Declarative UI Engine] + QL[ObjectQL
Data Protocol Engine] + end + + subgraph "Infrastructure Layer" + DB[(Database
MySQL/PG/Oracle/SQLite)] + Renderer[UI Renderer
React/Vue/Flutter] + end + + App --> OS + OS --> UI + OS --> QL + UI --> Renderer + QL --> DB + + style OS fill:#e1f5ff + style UI fill:#fff3e0 + style QL fill:#f3e5f5 +``` + +### ObjectQL: The Data Protocol Engine + +**Role**: Database-agnostic query engine and schema compiler + +ObjectQL defines a universal JSON-based query language that compiles to native SQL for any supported database. It eliminates vendor lock-in by abstracting the data layer completely. + +**Key Capabilities**: +- **Schema Definition**: Declare data models as JSON specifications +- **Query Protocol**: Unified JSON syntax for all CRUD operations +- **AST Compilation**: Transpiles protocols to database-specific SQL +- **Virtual City**: Multi-tenant data isolation mechanism +- **Driver Abstraction**: Pluggable database drivers (MySQL, PostgreSQL, Oracle, SQLite, SQL Server) + +[→ ObjectQL Specification](/docs/objectql) + +### ObjectUI: The Declarative UI Engine + +**Role**: Protocol-based interface renderer + +ObjectUI transforms UI development from imperative code to declarative JSON specifications. Interfaces are data, not functions. + +**Key Capabilities**: +- **Component Protocol**: JSON definitions for forms, tables, grids, dashboards +- **Data Binding**: Automatic synchronization with ObjectQL data layer +- **Action Protocol**: Declarative event handling (API calls, navigation, dialogs) +- **Renderer Agnostic**: React implementation available, Vue/Flutter planned +- **Theme System**: Customizable styling without changing structure + +[→ ObjectUI Specification](/docs/objectui) + +### ObjectOS: The Runtime Platform + +**Role**: Application orchestration and platform services + +ObjectOS binds ObjectQL and ObjectUI into a cohesive runtime environment, providing identity management, access control, and deployment capabilities. + +**Key Capabilities**: +- **QL-UI Binding**: Automatic connection between data and interface layers +- **Identity System**: Built-in user management with RBAC +- **Field-Level Security**: Fine-grained data access control +- **Plugin Architecture**: Extensible business logic layer +- **Deployment Modes**: Standalone (.oos files), Server (Docker), Multi-tenant SaaS + +[→ ObjectOS Specification](/docs/objectos) + +--- + +## Why ObjectStack? + +### For Individual Developers +Build local-first applications **without server infrastructure**: +- Personal tools (notes, CRM, project management) +- Offline-capable applications with SQLite +- Zero deployment complexity—just a single .oos file +- Complete privacy and data ownership + +### For Enterprise IT +Unify **heterogeneous legacy systems** through a standard protocol layer: +- Connect multiple databases (Oracle, SQL Server, MySQL) +- Provide unified ObjectQL API across all systems +- Eliminate data silos with consistent query interface +- Reduce integration complexity by 10x + +### For SaaS Startups +Focus on **core business logic**, not infrastructure: +- Skip months of CRUD/auth/permissions boilerplate +- Multi-tenancy built-in at protocol level +- Database-agnostic allows customer choice +- Scale from SQLite to PostgreSQL without code changes + +### For Low-Code Platform Vendors +Offer **true portability** without vendor lock-in: +- Customers choose their own database +- Export/import applications as standard .oos files +- Protocol-based design enables visual editing tools +- AI-friendly specifications for code generation + +--- + +## Design Philosophy + +ObjectStack follows the principles outlined in **[The Manifesto](/docs/framework/manifesto)**: + +1. **Protocol Neutrality**: Specifications before implementations. No database, language, or framework dependencies in the protocol layer. + +2. **Mechanism over Policy**: Protocols define interfaces (mechanisms), not implementations (policies). User systems and business logic belong in ObjectOS, not in ObjectQL/UI specs. + +3. **Data Sovereignty**: Local-first by mandate. All core functionality must work offline. Data must be exportable in standard formats. + +4. **Stability Pledge**: Breaking changes require 2 major version migration windows. Infrastructure must be stable. + +These principles are **unshakable and non-negotiable**. Features that violate them cannot be added to ObjectStack. + +--- ## Getting Started -Ready to build? Choose your path: +Choose your learning path based on your role: + +### Quick Start (5 minutes) +Get a working application running immediately: +- **[Quick Start Guide](/docs/framework/quickstart)**: Build your first ObjectStack app + +### Conceptual Foundation (30 minutes) +Understand the philosophy and architecture: +- **[Welcome to ObjectStack](/docs/framework/welcome)**: Platform overview and value proposition +- **[The Manifesto](/docs/framework/manifesto)**: Core principles and design decisions +- **[Architecture Guide](/docs/framework/architecture)**: Technical design and component relationships + +### Component Specifications (2-3 hours each) +Deep dive into each engine's protocol specifications: +- **[ObjectQL Spec](/docs/objectql)**: Schema definition, query DSL, aggregations +- **[ObjectUI Spec](/docs/objectui)**: Component protocols, actions, rendering +- **[ObjectOS Spec](/docs/objectos)**: Identity management, RBAC, deployment + +### AI-Assisted Development +Learn how to leverage LLMs for rapid development: +- **[The AI Codex](/docs/framework/ai-codex)**: Using AI to generate 80% of your application from protocol specs + +--- + +## Example: Todo Application in Protocols + +A complete application defined as declarative JSON: + +**Data Layer (ObjectQL Schema)**: +```json +{ + "objects": { + "todos": { + "fields": { + "title": { "type": "text", "required": true }, + "completed": { "type": "boolean", "defaultValue": false }, + "priority": { "type": "select", "options": ["high", "medium", "low"] }, + "owner": { "type": "lookup", "reference_to": "_users" } + }, + "permission_set": { + "user": { + "allowRead": true, + "allowCreate": true, + "allowEdit": "owner eq $user.id", + "allowDelete": "owner eq $user.id" + } + } + } + } +} +``` + +**Interface Layer (ObjectUI Protocol)**: +```json +{ + "type": "page", + "title": "My Tasks", + "body": { + "type": "table", + "object": "todos", + "filters": [["completed", "=", false]], + "columns": [ + { "field": "title", "label": "Task" }, + { "field": "priority", "label": "Priority" }, + { "field": "completed", "label": "Done", "type": "boolean" } + ], + "actions": [ + { "label": "Mark Complete", "type": "update", "data": { "completed": true } }, + { "label": "Delete", "type": "delete", "confirm": true } + ] + } +} +``` + +**Result**: A fully functional, database-agnostic, permission-controlled task management application—defined entirely as data. + +--- + +## Community and Ecosystem + +- **GitHub**: [github.com/objectstack-ai](https://github.com/objectstack-ai) +- **Protocol Specifications**: This documentation site (objectstack.org) +- **Reference Implementations**: Open-source engines (MIT/Apache 2.0) +- **Community Plugins**: Extensible through ObjectOS plugin architecture + +--- + +## Next Steps + +1. **Understand the Philosophy**: Read **[The Manifesto](/docs/framework/manifesto)** to understand ObjectStack's core principles +2. **Build Your First App**: Follow the **[Quick Start Guide](/docs/framework/quickstart)** to deploy a working application +3. **Learn the Protocols**: Study **[ObjectQL](/docs/objectql)**, **[ObjectUI](/docs/objectui)**, and **[ObjectOS](/docs/objectos)** specifications +4. **Explore Use Cases**: Review **[Architecture](/docs/framework/architecture)** for enterprise patterns -- 🚀 **[Quick Start Guide](/docs/framework/quickstart)**: Create your first app in under 10 minutes. -- 💡 **[Core Concepts](/docs/framework/welcome)**: Learn about the philosophy behind ObjectStack. -- 🏗️ **[Architecture](/docs/framework/architecture)**: Deep dive into the technical design. +Welcome to the ObjectStack ecosystem. Let's build the future of protocol-driven development.