diff --git a/README.md b/README.md
index e510bf1..385cdca 100644
--- a/README.md
+++ b/README.md
@@ -29,31 +29,55 @@ The official documentation is built with Fumadocs and Next.js.
| **[`@objectstack/spec`](packages/spec)** | **THE PROTOCOL**. Contains all Zod definitions, Types, and JSON Schemas. | 🟢 **Active** |
| **[`@objectstack/docs`](apps/docs)** | Documentation site built with Fumadocs and Next.js. | 🟢 **Active** |
| `content/docs/` | Documentation content (MDX files). Shared resource. | 🟢 **Active** |
+| **Examples** | Reference implementations demonstrating protocol features | |
+| └─ [`examples/crm`](examples/crm) | **Full-featured CRM** - 6 objects, workflows, validations, views, dashboards, reports | 🟢 **Complete** |
+| └─ [`examples/todo`](examples/todo) | **Quick-start** - Simple task management with 7 field types | 🟢 **Active** |
+| └─ [`examples/host`](examples/host) | Server runtime with kernel/plugin loading pattern | 🟡 **Experimental** |
+| └─ [`examples/plugin-bi`](examples/plugin-bi) | Business Intelligence plugin example | 🟡 **Experimental** |
| *Other packages* | *Legacy/Migration in progress* | 🟡 *Legacy* |
## 🛠️ The Protocol Architecture
-The ObjectStack Protocol (`@objectstack/spec`) is divided into three layers:
+The ObjectStack Protocol (`@objectstack/spec`) is divided into five core modules:
### 1. Data Protocol (ObjectQL)
-Defines the "Shape of Data".
-- **Schema:** Objects, Fields, Validation.
-- **Logic:** Formulas, Rollups.
-- **Security:** Permissions, Sharing Rules.
-- **Query:** Abstract Syntax Tree (AST) for unified data access.
+Defines the "Shape of Data" and business logic.
+- **Schema:** Objects, Fields (23+ types including text, number, select, lookup, formula, autonumber, etc.)
+- **Logic:** Workflows, Triggers, Validation Rules, Formulas
+- **Security:** Permissions, Sharing Rules
+- **Query:** Abstract Syntax Tree (AST) for unified data access across drivers
+- **Automation:** Flow definitions, Dataset mappings
### 2. UI Protocol (ObjectUI)
-Defines the "Shape of Interaction".
-- **Views:** Grids, Kanbans, Calendars.
-- **Pages:** FlexiPage layouts (Regions & Components).
-- **Navigation:** Apps, Navigation.
-- **Analytics:** Reports, Dashboards.
+Defines the "Shape of Interaction" for rendering interfaces.
+- **Views:** Grid, Kanban, Calendar, Gantt, List configurations
+- **Pages:** FlexiPage layouts with regions and components
+- **Navigation:** App menus and navigation structures
+- **Analytics:** Reports (Tabular, Summary, Matrix), Dashboards with widgets
+- **Actions:** Script, URL, Modal, Flow-triggered actions
+- **Theming:** Color palettes, typography, breakpoints, animations
### 3. System Protocol (ObjectOS)
-Defines the "Runtime Environment".
-- **Manifest:** Application packaging (`objectstack.config.ts`).
-- **Identity:** Auth, Roles, Territories.
-- **Integration:** Webhooks, ETL Mappings.
+Defines the "Runtime Environment" and platform capabilities.
+- **Manifest:** Application packaging (`objectstack.config.ts`)
+- **Identity:** Authentication, Roles, Territories, Licenses
+- **Integration:** Webhooks, API contracts, ETL Mappings
+- **Datasource:** Driver definitions for SQL, NoSQL, SaaS connectors
+- **Discovery:** Plugin discovery and loading mechanisms
+- **I18n:** Translation and internationalization support
+
+### 4. AI Protocol
+Defines AI agent integration capabilities.
+- **Agent:** AI agent definitions and configurations
+- **Tools:** AI tool integrations
+- **Knowledge:** Knowledge base structures
+- **Models:** AI model configurations
+
+### 5. API Protocol
+Defines standardized API contracts.
+- **Envelopes:** Response structures (BaseResponse, ListRecordResponse, etc.)
+- **Requests:** Request payloads (CreateRequest, UpdateRequest, BulkRequest, etc.)
+- **Contracts:** API endpoint definitions and specifications
## 🚀 Development
diff --git a/content/docs/guides/field-types.cn.mdx b/content/docs/guides/field-types.cn.mdx
new file mode 100644
index 0000000..df623d3
--- /dev/null
+++ b/content/docs/guides/field-types.cn.mdx
@@ -0,0 +1,756 @@
+---
+title: 字段类型参考
+description: ObjectStack 所有字段类型的完整指南,包含示例和配置选项
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+# 字段类型参考
+
+ObjectStack 支持 **30+ 种字段类型**,涵盖文本、数字、日期、选择、关联、媒体、计算和增强类型。本指南为每种类型提供实用示例。
+
+## 核心文本字段
+
+### Text (文本)
+单行文本输入,用于短字符串。
+
+```typescript
+import { Field } from '@objectstack/spec';
+
+// 基础文本字段
+name: Field.text({
+ label: '姓名',
+ required: true,
+ maxLength: 255,
+})
+
+// 可搜索文本字段
+account_name: Field.text({
+ label: '账户名称',
+ searchable: true,
+ unique: true,
+})
+```
+
+**配置选项:**
+- `required` - 设为必填字段
+- `maxLength` - 最大字符限制
+- `minLength` - 最小字符限制
+- `searchable` - 启用全文搜索
+- `unique` - 强制唯一性约束
+- `defaultValue` - 设置默认值
+
+---
+
+### Textarea (多行文本)
+多行文本输入,用于较长内容。
+
+```typescript
+description: Field.textarea({
+ label: '描述',
+ maxLength: 5000,
+ rows: 5, // UI 初始高度提示
+})
+```
+
+---
+
+### Email (电子邮件)
+带验证的电子邮件地址字段。
+
+```typescript
+email: Field.email({
+ label: '电子邮件',
+ required: true,
+ unique: true,
+})
+```
+
+
+ 自动验证邮箱格式:`user@domain.com`
+
+
+---
+
+### URL (网址)
+网站/链接字段,带 URL 验证。
+
+```typescript
+website: Field.url({
+ label: '网站',
+ placeholder: 'https://example.com',
+})
+```
+
+---
+
+### Phone (电话)
+带格式验证的电话号码字段。
+
+```typescript
+phone: Field.phone({
+ label: '电话号码',
+ format: 'international', // 或 'us', 'uk'
+})
+```
+
+---
+
+### Password (密码)
+带加密的安全密码字段。
+
+```typescript
+api_key: Field.password({
+ label: 'API 密钥',
+ encryption: true, // 静态加密
+ readonly: true,
+})
+```
+
+
+ 密码字段在 UI 中自动掩码,如果 `encryption: true` 则加密存储
+
+
+---
+
+## 富内容字段
+
+### Markdown
+支持预览的 Markdown 文本编辑器。
+
+```typescript
+documentation: Field.markdown({
+ label: '文档',
+ description: '支持完整 Markdown 语法',
+})
+```
+
+---
+
+### HTML
+原始 HTML 编辑器(谨慎使用)。
+
+```typescript
+html_content: Field.html({
+ label: 'HTML 内容',
+ description: '原始 HTML - 渲染前需要净化',
+})
+```
+
+
+ 渲染前务必净化 HTML 内容,防止 XSS 攻击
+
+
+---
+
+### Rich Text (富文本)
+带格式化工具栏的所见即所得编辑器。
+
+```typescript
+notes: Field.richtext({
+ label: '备注',
+ description: '富文本支持格式化、列表、链接',
+})
+```
+
+**支持:**
+- 粗体、斜体、下划线
+- 标题、列表、引用
+- 链接和图片
+- 表格
+
+---
+
+## 数字字段
+
+### Number (数字)
+整数或小数的数值字段。
+
+```typescript
+quantity: Field.number({
+ label: '数量',
+ min: 0,
+ max: 1000,
+ defaultValue: 1,
+})
+
+// 小数
+temperature: Field.number({
+ label: '温度',
+ precision: 5, // 总位数
+ scale: 2, // 小数位
+})
+```
+
+---
+
+### Currency (货币)
+带货币符号的金额值。
+
+```typescript
+annual_revenue: Field.currency({
+ label: '年收入',
+ precision: 18,
+ scale: 2,
+ min: 0,
+})
+```
+
+**显示:** `$1,234.56`(带货币符号格式化)
+
+---
+
+### Percent (百分比)
+百分比值(0-100 或 0-1)。
+
+```typescript
+probability: Field.percent({
+ label: '赢单概率',
+ min: 0,
+ max: 100,
+ scale: 1, // 一位小数
+})
+```
+
+**显示:** `75.5%`
+
+---
+
+## 日期和时间字段
+
+### Date (日期)
+日期选择器(无时间组件)。
+
+```typescript
+due_date: Field.date({
+ label: '截止日期',
+ defaultValue: 'today',
+})
+
+birthday: Field.date({
+ label: '生日',
+ min: '1900-01-01',
+ max: 'today',
+})
+```
+
+**格式:** `YYYY-MM-DD`
+
+---
+
+### DateTime (日期时间)
+支持时区的日期时间选择器。
+
+```typescript
+created_at: Field.datetime({
+ label: '创建时间',
+ readonly: true,
+ defaultValue: 'now',
+})
+```
+
+**格式:** `YYYY-MM-DD HH:mm:ss`
+
+---
+
+### Time (时间)
+时间选择器(无日期组件)。
+
+```typescript
+meeting_time: Field.time({
+ label: '会议时间',
+ format: '24h', // 或 '12h'
+})
+```
+
+**格式:** `HH:mm:ss`
+
+---
+
+## 布尔字段
+
+### Boolean (布尔值)
+真/假值的复选框。
+
+```typescript
+is_active: Field.boolean({
+ label: '激活',
+ defaultValue: true,
+})
+
+is_completed: Field.boolean({
+ label: '已完成',
+ defaultValue: false,
+})
+```
+
+**显示:** 复选框或切换开关
+
+---
+
+## 选择字段
+
+### Select (选择)
+带预定义选项的下拉菜单。
+
+```typescript
+// 简单选项(字符串数组)
+priority: Field.select({
+ label: '优先级',
+ options: ['低', '中', '高', '紧急'],
+})
+
+// 高级选项(带值和颜色)
+status: Field.select({
+ label: '状态',
+ options: [
+ { label: '开放', value: 'open', color: '#00AA00', default: true },
+ { label: '进行中', value: 'in_progress', color: '#FFA500' },
+ { label: '已关闭', value: 'closed', color: '#999999' },
+ ],
+})
+
+// 多选
+tags: Field.select({
+ label: '标签',
+ multiple: true, // 允许多选
+ options: ['错误', '功能', '增强', '文档'],
+})
+```
+
+**配置:**
+- `options` - 字符串标签数组或选项对象
+- `multiple` - 允许多选(存储为数组)
+- `color` - 徽章和图表的颜色
+
+---
+
+## 关联字段
+
+### Lookup (查找)
+引用另一个对象(多对一)。
+
+```typescript
+// 基础查找
+account: Field.lookup('account', {
+ label: '账户',
+ required: true,
+})
+
+// 过滤查找
+contact: Field.lookup('contact', {
+ label: '联系人',
+ referenceFilters: ['account_id = $parent.account_id'], // 按父记录过滤
+})
+
+// 多重查找
+related_cases: Field.lookup('case', {
+ label: '相关案例',
+ multiple: true, // 多对多
+})
+```
+
+**配置:**
+- `reference` - 目标对象名称(snake_case)
+- `referenceFilters` - 查找对话框的过滤条件
+- `deleteBehavior` - `'set_null'`、`'cascade'` 或 `'restrict'`
+- `multiple` - 允许多个引用
+
+---
+
+### Master-Detail (主从)
+带级联删除的父子关系。
+
+```typescript
+account: Field.masterDetail('account', {
+ label: '账户',
+ required: true,
+ deleteBehavior: 'cascade', // 删除父记录时删除子记录
+ writeRequiresMasterRead: true, // 安全强制
+})
+```
+
+
+ **主从关系 vs 查找:**
+ - **主从关系:** 紧密耦合,级联删除,子记录继承安全性
+ - **查找:** 松散耦合,删除时置空,独立安全性
+
+
+---
+
+## 媒体字段
+
+### Image (图片)
+带预览的图片上传。
+
+```typescript
+product_image: Field.image({
+ label: '产品图片',
+ multiple: false,
+ maxFileSize: 5 * 1024 * 1024, // 5MB
+ acceptedFormats: ['image/jpeg', 'image/png', 'image/webp'],
+})
+
+// 多图片
+gallery: Field.image({
+ label: '图库',
+ multiple: true,
+ maxFiles: 10,
+})
+```
+
+---
+
+### File (文件)
+任意文件类型的文件上传字段。
+
+```typescript
+attachment: Field.file({
+ label: '附件',
+ maxFileSize: 25 * 1024 * 1024, // 25MB
+ acceptedFormats: ['application/pdf', 'application/msword'],
+})
+```
+
+---
+
+### Avatar (头像)
+个人资料图片/头像上传。
+
+```typescript
+profile_picture: Field.avatar({
+ label: '头像',
+ maxFileSize: 2 * 1024 * 1024, // 2MB
+ cropAspectRatio: 1, // 正方形裁剪
+})
+```
+
+---
+
+## 计算字段
+
+### Formula (公式)
+基于表达式的计算字段。
+
+```typescript
+full_name: Field.formula({
+ label: '全名',
+ expression: 'CONCAT(first_name, " ", last_name)',
+ readonly: true,
+})
+
+full_address: Field.formula({
+ label: '完整地址',
+ expression: 'CONCAT(street, ", ", city, ", ", state, " ", postal_code)',
+})
+
+days_open: Field.formula({
+ label: '开放天数',
+ expression: 'DAYS_BETWEEN(created_at, NOW())',
+ type: 'number',
+})
+```
+
+
+ 公式字段自动计算且只读。可用函数请参见 [公式函数](/docs/references/data/formulas)。
+
+
+---
+
+### Summary (汇总)
+从关联记录聚合数据。
+
+```typescript
+total_opportunities: Field.summary({
+ label: '总机会金额',
+ summaryOperations: {
+ object: 'opportunity',
+ field: 'amount',
+ function: 'sum',
+ },
+})
+
+open_cases_count: Field.summary({
+ label: '开放案例数',
+ summaryOperations: {
+ object: 'case',
+ field: 'id',
+ function: 'count',
+ },
+})
+```
+
+**可用函数:**
+- `count` - 计数关联记录
+- `sum` - 求和数值字段
+- `avg` - 平均数值字段
+- `min` - 最小值
+- `max` - 最大值
+
+---
+
+### Autonumber (自动编号)
+自动递增的唯一标识符。
+
+```typescript
+account_number: Field.autonumber({
+ label: '账户编号',
+ format: 'ACC-{0000}', // ACC-0001, ACC-0002, 等
+})
+
+case_id: Field.autonumber({
+ label: '案例 ID',
+ format: 'CASE-{YYYY}-{00000}', // CASE-2024-00001
+})
+```
+
+**格式标记:**
+- `{0000}` - 补零数字
+- `{YYYY}` - 年份
+- `{MM}` - 月份
+- `{DD}` - 日期
+
+---
+
+## 增强字段类型
+
+### Location (位置)
+带地图显示的 GPS 坐标。
+
+```typescript
+coordinates: Field.location({
+ label: '位置',
+ displayMap: true,
+ allowGeocoding: true, // 将地址转换为坐标
+})
+```
+
+**数据结构:**
+```typescript
+{
+ latitude: 37.7749,
+ longitude: -122.4194,
+ altitude: 100, // 可选
+ accuracy: 10, // 可选(米)
+}
+```
+
+---
+
+### Address (地址)
+结构化地址字段。
+
+```typescript
+billing_address: Field.address({
+ label: '账单地址',
+ addressFormat: 'us', // 'us'、'uk' 或 'international'
+})
+```
+
+**数据结构:**
+```typescript
+{
+ street: '123 Main St',
+ city: 'San Francisco',
+ state: 'CA',
+ postalCode: '94105',
+ country: 'United States',
+ countryCode: 'US',
+ formatted: '123 Main St, San Francisco, CA 94105',
+}
+```
+
+---
+
+### Code (代码)
+带语法高亮的代码编辑器。
+
+```typescript
+code_snippet: Field.code('javascript', {
+ label: '代码片段',
+ lineNumbers: true,
+ theme: 'monokai',
+})
+
+sql_query: Field.code('sql', {
+ label: 'SQL 查询',
+ readonly: false,
+})
+```
+
+**支持的语言:**
+- `javascript`、`typescript`、`python`、`java`、`sql`、`html`、`css`、`json`、`yaml`、`markdown` 等
+
+---
+
+### Color (颜色)
+支持多种格式的颜色选择器。
+
+```typescript
+category_color: Field.color({
+ label: '分类颜色',
+ colorFormat: 'hex', // 'hex'、'rgb'、'rgba'、'hsl'
+ presetColors: ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'],
+ allowAlpha: false,
+})
+
+theme_color: Field.color({
+ label: '主题颜色',
+ colorFormat: 'rgba',
+ allowAlpha: true, // 支持透明度
+})
+```
+
+---
+
+### Rating (评分)
+星级评分字段。
+
+```typescript
+priority: Field.rating(3, {
+ label: '优先级',
+ description: '1-3 星',
+})
+
+satisfaction: Field.rating(5, {
+ label: '客户满意度',
+ allowHalf: true, // 允许 0.5 增量
+})
+```
+
+**配置:**
+- 第一个参数:`maxRating`(默认:5)
+- `allowHalf` - 允许半星评分(例如 3.5)
+
+---
+
+### Signature (签名)
+数字签名捕获。
+
+```typescript
+customer_signature: Field.signature({
+ label: '客户签名',
+ required: true,
+ readonly: false,
+})
+```
+
+**存储为:** Base64 编码的图片数据
+
+---
+
+## 字段配置参考
+
+### 通用属性
+
+所有字段都支持这些通用属性:
+
+```typescript
+{
+ // 标识
+ name: 'field_name', // snake_case 机器名称
+ label: '字段标签', // 人类可读标签
+ description: '帮助文本', // 工具提示/帮助文本
+
+ // 约束
+ required: false, // 是否必填
+ unique: false, // 强制唯一性
+ defaultValue: null, // 默认值
+
+ // UI 行为
+ hidden: false, // 从默认 UI 隐藏
+ readonly: false, // UI 中只读
+ searchable: false, // 启用搜索索引
+
+ // 数据库
+ index: false, // 创建数据库索引
+ externalId: false, // 用于 upsert 操作
+ encryption: false, // 静态加密
+}
+```
+
+---
+
+## 最佳实践
+
+### 命名约定
+
+```typescript
+// ✅ 正确:字段名使用 snake_case
+account_name: Field.text({ label: '账户名称' })
+annual_revenue: Field.currency({ label: '年收入' })
+
+// ❌ 错误:camelCase 或 PascalCase
+accountName: Field.text({ label: '账户名称' })
+AnnualRevenue: Field.currency({ label: '年收入' })
+```
+
+### 必填字段
+
+```typescript
+// ✅ 正确:必填关键字段
+name: Field.text({
+ label: '名称',
+ required: true,
+ maxLength: 255,
+})
+
+// ✅ 正确:可选字段提供灵活性
+middle_name: Field.text({
+ label: '中间名',
+ required: false,
+})
+```
+
+### 可搜索字段
+
+```typescript
+// ✅ 正确:关键字段可搜索
+account_name: Field.text({
+ searchable: true,
+ label: '账户名称',
+})
+
+// ❌ 错误:不要索引大文本字段
+description: Field.textarea({
+ searchable: true, // 可能影响性能
+})
+```
+
+### 默认值
+
+```typescript
+// ✅ 正确:使用有意义的默认值
+status: Field.select({
+ options: [
+ { label: '开放', value: 'open', default: true },
+ { label: '关闭', value: 'closed' },
+ ],
+})
+
+created_at: Field.datetime({
+ defaultValue: 'now',
+ readonly: true,
+})
+```
+
+---
+
+## CRM 示例
+
+参见 **[CRM 示例](/examples/crm)** 了解所有字段类型的实际使用:
+
+- **账户:** 自动编号、公式、货币、带颜色的选择
+- **联系人:** 主从关系、公式(全名)、头像、电子邮件、电话
+- **机会:** 工作流自动化、状态机、百分比、日期时间
+- **案例:** 评分(满意度)、SLA 跟踪、公式计算
+- **任务:** 代码、颜色、评分、位置、签名
+
+---
+
+## 下一步
+
+- [对象架构指南](/docs/guides/object-schema)
+- [验证规则](/docs/guides/validation-rules)
+- [工作流自动化](/docs/guides/workflows)
+- [字段 API 参考](/docs/references/data/core/Field)
diff --git a/content/docs/guides/field-types.mdx b/content/docs/guides/field-types.mdx
new file mode 100644
index 0000000..be8a9c3
--- /dev/null
+++ b/content/docs/guides/field-types.mdx
@@ -0,0 +1,756 @@
+---
+title: Field Types Reference
+description: Complete guide to all ObjectStack field types with examples and configuration options
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+# Field Types Reference
+
+ObjectStack supports **30+ field types** covering text, numbers, dates, selections, relationships, media, calculations, and enhanced types. This guide provides practical examples for each type.
+
+## Core Text Fields
+
+### Text
+Single-line text input for short strings.
+
+```typescript
+import { Field } from '@objectstack/spec';
+
+// Basic text field
+name: Field.text({
+ label: 'Full Name',
+ required: true,
+ maxLength: 255,
+})
+
+// Searchable text field
+account_name: Field.text({
+ label: 'Account Name',
+ searchable: true,
+ unique: true,
+})
+```
+
+**Configuration Options:**
+- `required` - Make field mandatory
+- `maxLength` - Maximum character limit
+- `minLength` - Minimum character limit
+- `searchable` - Enable full-text search
+- `unique` - Enforce uniqueness constraint
+- `defaultValue` - Set default value
+
+---
+
+### Textarea
+Multi-line text input for longer content.
+
+```typescript
+description: Field.textarea({
+ label: 'Description',
+ maxLength: 5000,
+ rows: 5, // UI hint for initial height
+})
+```
+
+---
+
+### Email
+Email address field with validation.
+
+```typescript
+email: Field.email({
+ label: 'Email Address',
+ required: true,
+ unique: true,
+})
+```
+
+
+ Automatically validates email format: `user@domain.com`
+
+
+---
+
+### URL
+Website/link field with URL validation.
+
+```typescript
+website: Field.url({
+ label: 'Website',
+ placeholder: 'https://example.com',
+})
+```
+
+---
+
+### Phone
+Phone number field with format validation.
+
+```typescript
+phone: Field.phone({
+ label: 'Phone Number',
+ format: 'international', // or 'us', 'uk'
+})
+```
+
+---
+
+### Password
+Secure password field with encryption.
+
+```typescript
+api_key: Field.password({
+ label: 'API Key',
+ encryption: true, // Encrypt at rest
+ readonly: true,
+})
+```
+
+
+ Password fields are automatically masked in UI and encrypted if `encryption: true`
+
+
+---
+
+## Rich Content Fields
+
+### Markdown
+Markdown text editor with preview.
+
+```typescript
+documentation: Field.markdown({
+ label: 'Documentation',
+ description: 'Supports full Markdown syntax',
+})
+```
+
+---
+
+### HTML
+Raw HTML editor (use with caution).
+
+```typescript
+html_content: Field.html({
+ label: 'HTML Content',
+ description: 'Raw HTML - sanitize before rendering',
+})
+```
+
+
+ Always sanitize HTML content before rendering to prevent XSS attacks
+
+
+---
+
+### Rich Text
+WYSIWYG editor with formatting toolbar.
+
+```typescript
+notes: Field.richtext({
+ label: 'Notes',
+ description: 'Rich text with formatting, lists, links',
+})
+```
+
+**Supports:**
+- Bold, italic, underline
+- Headings, lists, quotes
+- Links and images
+- Tables
+
+---
+
+## Number Fields
+
+### Number
+Numeric field for integers or decimals.
+
+```typescript
+quantity: Field.number({
+ label: 'Quantity',
+ min: 0,
+ max: 1000,
+ defaultValue: 1,
+})
+
+// Decimal numbers
+temperature: Field.number({
+ label: 'Temperature',
+ precision: 5, // Total digits
+ scale: 2, // Decimal places
+})
+```
+
+---
+
+### Currency
+Monetary value with currency symbol.
+
+```typescript
+annual_revenue: Field.currency({
+ label: 'Annual Revenue',
+ precision: 18,
+ scale: 2,
+ min: 0,
+})
+```
+
+**Display:** `$1,234.56` (formatted with currency symbol)
+
+---
+
+### Percent
+Percentage value (0-100 or 0-1).
+
+```typescript
+probability: Field.percent({
+ label: 'Win Probability',
+ min: 0,
+ max: 100,
+ scale: 1, // One decimal place
+})
+```
+
+**Display:** `75.5%`
+
+---
+
+## Date & Time Fields
+
+### Date
+Date picker (no time component).
+
+```typescript
+due_date: Field.date({
+ label: 'Due Date',
+ defaultValue: 'today',
+})
+
+birthday: Field.date({
+ label: 'Birthday',
+ min: '1900-01-01',
+ max: 'today',
+})
+```
+
+**Format:** `YYYY-MM-DD`
+
+---
+
+### DateTime
+Date and time picker with timezone support.
+
+```typescript
+created_at: Field.datetime({
+ label: 'Created At',
+ readonly: true,
+ defaultValue: 'now',
+})
+```
+
+**Format:** `YYYY-MM-DD HH:mm:ss`
+
+---
+
+### Time
+Time picker (no date component).
+
+```typescript
+meeting_time: Field.time({
+ label: 'Meeting Time',
+ format: '24h', // or '12h'
+})
+```
+
+**Format:** `HH:mm:ss`
+
+---
+
+## Boolean Field
+
+### Boolean
+Checkbox for true/false values.
+
+```typescript
+is_active: Field.boolean({
+ label: 'Active',
+ defaultValue: true,
+})
+
+is_completed: Field.boolean({
+ label: 'Completed',
+ defaultValue: false,
+})
+```
+
+**Display:** Checkbox or toggle switch
+
+---
+
+## Selection Fields
+
+### Select
+Dropdown with predefined options.
+
+```typescript
+// Simple options (string array)
+priority: Field.select({
+ label: 'Priority',
+ options: ['Low', 'Medium', 'High', 'Critical'],
+})
+
+// Advanced options (with values and colors)
+status: Field.select({
+ label: 'Status',
+ options: [
+ { label: 'Open', value: 'open', color: '#00AA00', default: true },
+ { label: 'In Progress', value: 'in_progress', color: '#FFA500' },
+ { label: 'Closed', value: 'closed', color: '#999999' },
+ ],
+})
+
+// Multi-select
+tags: Field.select({
+ label: 'Tags',
+ multiple: true, // Allow multiple selections
+ options: ['Bug', 'Feature', 'Enhancement', 'Documentation'],
+})
+```
+
+**Configuration:**
+- `options` - Array of string labels or option objects
+- `multiple` - Allow multiple selections (stores as array)
+- `color` - Color for badges and charts
+
+---
+
+## Relational Fields
+
+### Lookup
+Reference to another object (many-to-one).
+
+```typescript
+// Basic lookup
+account: Field.lookup('account', {
+ label: 'Account',
+ required: true,
+})
+
+// Filtered lookup
+contact: Field.lookup('contact', {
+ label: 'Contact',
+ referenceFilters: ['account_id = $parent.account_id'], // Filter by parent
+})
+
+// Multiple lookup
+related_cases: Field.lookup('case', {
+ label: 'Related Cases',
+ multiple: true, // Many-to-many
+})
+```
+
+**Configuration:**
+- `reference` - Target object name (snake_case)
+- `referenceFilters` - Filter criteria for lookup dialog
+- `deleteBehavior` - `'set_null'`, `'cascade'`, or `'restrict'`
+- `multiple` - Allow multiple references
+
+---
+
+### Master-Detail
+Parent-child relationship with cascade delete.
+
+```typescript
+account: Field.masterDetail('account', {
+ label: 'Account',
+ required: true,
+ deleteBehavior: 'cascade', // Delete children when parent deleted
+ writeRequiresMasterRead: true, // Security enforcement
+})
+```
+
+
+ **Master-Detail vs Lookup:**
+ - **Master-Detail:** Tight coupling, cascade deletes, child inherits security
+ - **Lookup:** Loose coupling, set null on delete, independent security
+
+
+---
+
+## Media Fields
+
+### Image
+Image upload with preview.
+
+```typescript
+product_image: Field.image({
+ label: 'Product Image',
+ multiple: false,
+ maxFileSize: 5 * 1024 * 1024, // 5MB
+ acceptedFormats: ['image/jpeg', 'image/png', 'image/webp'],
+})
+
+// Multiple images
+gallery: Field.image({
+ label: 'Gallery',
+ multiple: true,
+ maxFiles: 10,
+})
+```
+
+---
+
+### File
+File upload field for any file type.
+
+```typescript
+attachment: Field.file({
+ label: 'Attachment',
+ maxFileSize: 25 * 1024 * 1024, // 25MB
+ acceptedFormats: ['application/pdf', 'application/msword'],
+})
+```
+
+---
+
+### Avatar
+Profile picture/avatar upload.
+
+```typescript
+profile_picture: Field.avatar({
+ label: 'Profile Picture',
+ maxFileSize: 2 * 1024 * 1024, // 2MB
+ cropAspectRatio: 1, // Square crop
+})
+```
+
+---
+
+## Calculated Fields
+
+### Formula
+Calculated field based on expression.
+
+```typescript
+full_name: Field.formula({
+ label: 'Full Name',
+ expression: 'CONCAT(first_name, " ", last_name)',
+ readonly: true,
+})
+
+full_address: Field.formula({
+ label: 'Full Address',
+ expression: 'CONCAT(street, ", ", city, ", ", state, " ", postal_code)',
+})
+
+days_open: Field.formula({
+ label: 'Days Open',
+ expression: 'DAYS_BETWEEN(created_at, NOW())',
+ type: 'number',
+})
+```
+
+
+ Formula fields are automatically calculated and readonly. See [Formula Functions](/docs/references/data/formulas) for available functions.
+
+
+---
+
+### Summary (Rollup)
+Aggregate data from related records.
+
+```typescript
+total_opportunities: Field.summary({
+ label: 'Total Opportunities',
+ summaryOperations: {
+ object: 'opportunity',
+ field: 'amount',
+ function: 'sum',
+ },
+})
+
+open_cases_count: Field.summary({
+ label: 'Open Cases',
+ summaryOperations: {
+ object: 'case',
+ field: 'id',
+ function: 'count',
+ },
+})
+```
+
+**Available Functions:**
+- `count` - Count related records
+- `sum` - Sum numeric field
+- `avg` - Average numeric field
+- `min` - Minimum value
+- `max` - Maximum value
+
+---
+
+### Autonumber
+Auto-incrementing unique identifier.
+
+```typescript
+account_number: Field.autonumber({
+ label: 'Account Number',
+ format: 'ACC-{0000}', // ACC-0001, ACC-0002, etc.
+})
+
+case_id: Field.autonumber({
+ label: 'Case ID',
+ format: 'CASE-{YYYY}-{00000}', // CASE-2024-00001
+})
+```
+
+**Format Tokens:**
+- `{0000}` - Zero-padded number
+- `{YYYY}` - Year
+- `{MM}` - Month
+- `{DD}` - Day
+
+---
+
+## Enhanced Field Types
+
+### Location
+GPS coordinates with map display.
+
+```typescript
+coordinates: Field.location({
+ label: 'Location',
+ displayMap: true,
+ allowGeocoding: true, // Convert address to coordinates
+})
+```
+
+**Data Structure:**
+```typescript
+{
+ latitude: 37.7749,
+ longitude: -122.4194,
+ altitude: 100, // Optional
+ accuracy: 10, // Optional (meters)
+}
+```
+
+---
+
+### Address
+Structured address field.
+
+```typescript
+billing_address: Field.address({
+ label: 'Billing Address',
+ addressFormat: 'us', // 'us', 'uk', or 'international'
+})
+```
+
+**Data Structure:**
+```typescript
+{
+ street: '123 Main St',
+ city: 'San Francisco',
+ state: 'CA',
+ postalCode: '94105',
+ country: 'United States',
+ countryCode: 'US',
+ formatted: '123 Main St, San Francisco, CA 94105',
+}
+```
+
+---
+
+### Code
+Code editor with syntax highlighting.
+
+```typescript
+code_snippet: Field.code('javascript', {
+ label: 'Code Snippet',
+ lineNumbers: true,
+ theme: 'monokai',
+})
+
+sql_query: Field.code('sql', {
+ label: 'SQL Query',
+ readonly: false,
+})
+```
+
+**Supported Languages:**
+- `javascript`, `typescript`, `python`, `java`, `sql`, `html`, `css`, `json`, `yaml`, `markdown`, and more
+
+---
+
+### Color
+Color picker with multiple formats.
+
+```typescript
+category_color: Field.color({
+ label: 'Category Color',
+ colorFormat: 'hex', // 'hex', 'rgb', 'rgba', 'hsl'
+ presetColors: ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'],
+ allowAlpha: false,
+})
+
+theme_color: Field.color({
+ label: 'Theme Color',
+ colorFormat: 'rgba',
+ allowAlpha: true, // Support transparency
+})
+```
+
+---
+
+### Rating
+Star rating field.
+
+```typescript
+priority: Field.rating(3, {
+ label: 'Priority',
+ description: '1-3 stars',
+})
+
+satisfaction: Field.rating(5, {
+ label: 'Customer Satisfaction',
+ allowHalf: true, // Allow 0.5 increments
+})
+```
+
+**Configuration:**
+- First parameter: `maxRating` (default: 5)
+- `allowHalf` - Allow half-star ratings (e.g., 3.5)
+
+---
+
+### Signature
+Digital signature capture.
+
+```typescript
+customer_signature: Field.signature({
+ label: 'Customer Signature',
+ required: true,
+ readonly: false,
+})
+```
+
+**Stored as:** Base64-encoded image data
+
+---
+
+## Field Configuration Reference
+
+### Common Properties
+
+All fields support these common properties:
+
+```typescript
+{
+ // Identity
+ name: 'field_name', // snake_case machine name
+ label: 'Field Label', // Human-readable label
+ description: 'Help text', // Tooltip/help text
+
+ // Constraints
+ required: false, // Is mandatory
+ unique: false, // Enforce uniqueness
+ defaultValue: null, // Default value
+
+ // UI Behavior
+ hidden: false, // Hide from default UI
+ readonly: false, // Read-only in UI
+ searchable: false, // Enable search indexing
+
+ // Database
+ index: false, // Create database index
+ externalId: false, // Use for upsert operations
+ encryption: false, // Encrypt at rest
+}
+```
+
+---
+
+## Best Practices
+
+### Naming Conventions
+
+```typescript
+// ✅ GOOD: snake_case for field names
+account_name: Field.text({ label: 'Account Name' })
+annual_revenue: Field.currency({ label: 'Annual Revenue' })
+
+// ❌ BAD: camelCase or PascalCase
+accountName: Field.text({ label: 'Account Name' })
+AnnualRevenue: Field.currency({ label: 'Annual Revenue' })
+```
+
+### Required Fields
+
+```typescript
+// ✅ GOOD: Require essential fields
+name: Field.text({
+ label: 'Name',
+ required: true,
+ maxLength: 255,
+})
+
+// ✅ GOOD: Optional fields for flexibility
+middle_name: Field.text({
+ label: 'Middle Name',
+ required: false,
+})
+```
+
+### Searchable Fields
+
+```typescript
+// ✅ GOOD: Make key fields searchable
+account_name: Field.text({
+ searchable: true,
+ label: 'Account Name',
+})
+
+// ❌ BAD: Don't index large text fields
+description: Field.textarea({
+ searchable: true, // Can impact performance
+})
+```
+
+### Default Values
+
+```typescript
+// ✅ GOOD: Use meaningful defaults
+status: Field.select({
+ options: [
+ { label: 'Open', value: 'open', default: true },
+ { label: 'Closed', value: 'closed' },
+ ],
+})
+
+created_at: Field.datetime({
+ defaultValue: 'now',
+ readonly: true,
+})
+```
+
+---
+
+## Examples from CRM
+
+See the **[CRM Example](/examples/crm)** for real-world usage of all field types:
+
+- **Account:** Autonumber, formula, currency, select with colors
+- **Contact:** Master-detail, formula (full_name), avatar, email, phone
+- **Opportunity:** Workflow automation, state machine, percent, datetime
+- **Case:** Rating (satisfaction), SLA tracking, formula calculations
+- **Task:** Code, color, rating, location, signature
+
+---
+
+## Next Steps
+
+- [Object Schema Guide](/docs/guides/object-schema)
+- [Validation Rules](/docs/guides/validation-rules)
+- [Workflow Automation](/docs/guides/workflows)
+- [Field API Reference](/docs/references/data/core/Field)
diff --git a/content/docs/guides/getting-started.cn.mdx b/content/docs/guides/getting-started.cn.mdx
index 49b95de..fface86 100644
--- a/content/docs/guides/getting-started.cn.mdx
+++ b/content/docs/guides/getting-started.cn.mdx
@@ -3,12 +3,12 @@ title: 快速开始
description: 5 分钟内构建你的第一个 ObjectStack 应用程序
---
-ObjectStack 是一个协议,但 `@objectstack/spec` 是提供 Zod schemas 和严格类型的参考实现库,用于构建有效的元数据。
+ObjectStack 是协议优先的平台。`@objectstack/spec` 包提供了 Zod 模式和严格的 TypeScript 类型来构建有效的元数据定义。
-## 初始化你的项目
+## 初始化项目
你可以从头开始或将 ObjectStack 添加到现有的 TypeScript 项目中。
@@ -22,44 +22,251 @@ npx tsc --init
-## 定义你的第一个对象
+## 定义第一个对象
-创建一个名为 `src/objects/contact.schema.ts` 的文件。
-这就是 **Zod 优先定义** 的强大之处。你可以开箱即用地获得自动完成和验证。
+创建文件 `src/domains/crm/contact.object.ts`。
+这就是 **Zod 优先定义** 的强大之处。你可以获得开箱即用的自动完成和验证。
```typescript
import { ObjectSchema, Field } from '@objectstack/spec';
export const Contact = ObjectSchema.create({
name: 'contact',
- label: 'Contact',
+ label: '联系人',
+ pluralLabel: '联系人',
+ icon: 'user',
+ description: '与账户关联的人员',
+ nameField: 'full_name',
+
fields: {
- first_name: Field.text({ label: 'First Name', required: true }),
- last_name: Field.text({ label: 'Last Name', required: true }),
- email: Field.text({ format: 'email' }),
- type: Field.select(['Customer', 'Partner', 'Vendor']),
+ // 基本信息
+ first_name: Field.text({
+ label: '名',
+ required: true,
+ maxLength: 100,
+ }),
+
+ last_name: Field.text({
+ label: '姓',
+ required: true,
+ maxLength: 100,
+ }),
+
+ // 公式字段 - 自动计算
+ full_name: Field.formula({
+ label: '全名',
+ expression: 'CONCAT(first_name, " ", last_name)',
+ }),
+
+ // 联系信息
+ email: Field.email({
+ label: '电子邮件',
+ unique: true,
+ }),
+
+ phone: Field.phone({
+ label: '电话',
+ }),
+
+ // 带预定义选项的选择字段
+ type: Field.select({
+ label: '联系人类型',
+ options: [
+ { label: '客户', value: 'customer', default: true },
+ { label: '合作伙伴', value: 'partner' },
+ { label: '供应商', value: 'vendor' },
+ ],
+ }),
+
+ // 与账户的关系
+ account: Field.masterDetail('account', {
+ label: '账户',
+ required: true,
+ deleteBehavior: 'cascade',
+ }),
},
+
enable: {
- api: true,
- audit: true
+ apiEnabled: true,
+ trackHistory: true,
}
});
```
+
+## 添加账户对象
+
+创建 `src/domains/crm/account.object.ts` 作为父对象:
+
+```typescript
+import { ObjectSchema, Field } from '@objectstack/spec';
+
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: '账户',
+ pluralLabel: '账户',
+ icon: 'building',
+ nameField: 'name',
+
+ fields: {
+ // 自动编号字段
+ account_number: Field.autonumber({
+ label: '账户编号',
+ format: 'ACC-{0000}',
+ }),
+
+ name: Field.text({
+ label: '账户名称',
+ required: true,
+ searchable: true,
+ maxLength: 255,
+ }),
+
+ // 货币字段
+ annual_revenue: Field.currency({
+ label: '年收入',
+ min: 0,
+ }),
+
+ // 带自定义颜色的选择字段(用于看板)
+ type: Field.select({
+ label: '账户类型',
+ options: [
+ { label: '潜在客户', value: 'prospect', color: '#FFA500', default: true },
+ { label: '客户', value: 'customer', color: '#00AA00' },
+ { label: '合作伙伴', value: 'partner', color: '#0000FF' },
+ ],
+ }),
+ },
+
+ enable: {
+ apiEnabled: true,
+ trackHistory: true,
+ }
+});
+```
+
+
+
+## 创建应用程序清单
+
+创建 `objectstack.config.ts` 将对象打包到应用中:
+
+```typescript
+import { defineManifest } from '@objectstack/spec';
+import { Account } from './src/domains/crm/account.object';
+import { Contact } from './src/domains/crm/contact.object';
+
+export default defineManifest({
+ name: 'my_crm',
+ label: '我的 CRM',
+ version: '1.0.0',
+ description: '简单的 CRM 应用程序',
+
+ objects: [Account, Contact],
+
+ navigation: {
+ tabs: [
+ {
+ label: '销售',
+ items: [
+ { type: 'object', object: 'account' },
+ { type: 'object', object: 'contact' },
+ ],
+ },
+ ],
+ },
+});
+```
+
+
## 验证协议
-创建一个构建脚本 `src/build.ts` 来验证你的定义是否符合 ObjectStack 协议。
+创建构建脚本 `src/build.ts` 来验证你的定义:
```typescript
-import { Contact } from './objects/contact.schema';
+import config from '../objectstack.config';
-// 如果你的 schema 无效,这将抛出 ZodError
-const protocol = Contact.parse(Contact);
+// 如果模式无效,这将抛出 ZodError
+console.log(`✅ 应用 '${config.label}' 有效!`);
+console.log(`📦 对象: ${config.objects.map(o => o.name).join(', ')}`);
-console.log(`✅ Object '${protocol.name}' is valid ObjectStack Metadata!`);
-console.log(JSON.stringify(protocol, null, 2));
+// 导出为 JSON 供运行时使用
+import fs from 'fs';
+fs.writeFileSync(
+ 'dist/manifest.json',
+ JSON.stringify(config, null, 2)
+);
+```
+
+运行它:
+
+```bash
+npx tsx src/build.ts
+```
+
+
+
+## 探索高级功能
+
+现在你有了一个可工作的应用,探索高级功能:
+
+### 1. 添加验证规则
+
+```typescript
+validations: [
+ {
+ name: 'unique_email',
+ type: 'unique',
+ fields: ['email'],
+ message: '电子邮件已存在',
+ },
+ {
+ name: 'positive_revenue',
+ type: 'script',
+ expression: 'annual_revenue >= 0',
+ message: '收入必须为正数',
+ },
+]
+```
+
+### 2. 添加工作流规则
+
+```typescript
+workflows: [
+ {
+ name: 'update_last_activity',
+ trigger: 'on_update',
+ actions: [
+ {
+ type: 'field_update',
+ field: 'last_activity_date',
+ value: 'TODAY()',
+ },
+ ],
+ },
+]
+```
+
+### 3. 配置视图
+
+```typescript
+views: {
+ list: {
+ type: 'grid',
+ columns: ['account_number', 'name', 'type', 'annual_revenue'],
+ filters: [
+ { field: 'type', operator: '=', value: 'customer' }
+ ],
+ },
+ kanban: {
+ type: 'kanban',
+ groupBy: 'type',
+ columns: ['name', 'annual_revenue'],
+ },
+}
```
@@ -68,10 +275,15 @@ console.log(JSON.stringify(protocol, null, 2));
现在你有了有效的元数据,你可以:
-1. **生成 SQL**:使用协议编译器(即将推出)生成 `CREATE TABLE` 语句。
-2. **生成 UI**:将 JSON 传入 `` React 组件。
-3. **部署**:将 JSON 推送到 ObjectOS 内核。
+1. **探索示例**:查看 [CRM 示例](/examples/crm) 了解完整功能实现
+2. **学习字段类型**:参见 [字段类型指南](/docs/guides/field-types) 了解所有 30+ 种字段类型
+3. **构建 UI**:使用 ObjectStack 运行时的元数据来生成界面
+4. **部署**:推送到 ObjectStack 内核用于生产环境
+**其他资源:**
+- [对象模式参考](/docs/references/data/core/Object)
+- [验证规则](/docs/guides/validation-rules)
+- [工作流自动化](/docs/guides/workflows)
diff --git a/content/docs/guides/getting-started.mdx b/content/docs/guides/getting-started.mdx
index ebdb5ca..21654c3 100644
--- a/content/docs/guides/getting-started.mdx
+++ b/content/docs/guides/getting-started.mdx
@@ -3,7 +3,7 @@ title: Getting Started
description: Build your first ObjectStack application in 5 minutes.
---
-ObjectStack is a protocol, but `@objectstack/spec` is the reference implementation library that provides the Zod schemas and strict types to build valid metadata.
+ObjectStack is a protocol-first platform. The `@objectstack/spec` package provides Zod schemas and strict TypeScript types to build valid metadata definitions.
@@ -24,7 +24,7 @@ npx tsc --init
## Define your first Object
-Create a file named `src/objects/contact.schema.ts`.
+Create a file named `src/domains/crm/contact.object.ts`.
This is where the power of **Zod-First Definition** comes in. You get autocomplete and validation out of the box.
```typescript
@@ -33,33 +33,240 @@ import { ObjectSchema, Field } from '@objectstack/spec';
export const Contact = ObjectSchema.create({
name: 'contact',
label: 'Contact',
+ pluralLabel: 'Contacts',
+ icon: 'user',
+ description: 'People associated with accounts',
+ nameField: 'full_name',
+
fields: {
- first_name: Field.text({ label: 'First Name', required: true }),
- last_name: Field.text({ label: 'Last Name', required: true }),
- email: Field.text({ format: 'email' }),
- type: Field.select(['Customer', 'Partner', 'Vendor']),
+ // Basic Information
+ first_name: Field.text({
+ label: 'First Name',
+ required: true,
+ maxLength: 100,
+ }),
+
+ last_name: Field.text({
+ label: 'Last Name',
+ required: true,
+ maxLength: 100,
+ }),
+
+ // Formula field - automatically calculated
+ full_name: Field.formula({
+ label: 'Full Name',
+ expression: 'CONCAT(first_name, " ", last_name)',
+ }),
+
+ // Contact Information
+ email: Field.email({
+ label: 'Email',
+ unique: true,
+ }),
+
+ phone: Field.phone({
+ label: 'Phone',
+ }),
+
+ // Selection with predefined options
+ type: Field.select({
+ label: 'Contact Type',
+ options: [
+ { label: 'Customer', value: 'customer', default: true },
+ { label: 'Partner', value: 'partner' },
+ { label: 'Vendor', value: 'vendor' },
+ ],
+ }),
+
+ // Relationship to Account
+ account: Field.masterDetail('account', {
+ label: 'Account',
+ required: true,
+ deleteBehavior: 'cascade',
+ }),
},
+
enable: {
- api: true,
- audit: true
+ apiEnabled: true,
+ trackHistory: true,
}
});
```
+
+## Add an Account Object
+
+Create `src/domains/crm/account.object.ts` for the parent object:
+
+```typescript
+import { ObjectSchema, Field } from '@objectstack/spec';
+
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: 'Account',
+ pluralLabel: 'Accounts',
+ icon: 'building',
+ nameField: 'name',
+
+ fields: {
+ // Autonumber field
+ account_number: Field.autonumber({
+ label: 'Account Number',
+ format: 'ACC-{0000}',
+ }),
+
+ name: Field.text({
+ label: 'Account Name',
+ required: true,
+ searchable: true,
+ maxLength: 255,
+ }),
+
+ // Currency field
+ annual_revenue: Field.currency({
+ label: 'Annual Revenue',
+ min: 0,
+ }),
+
+ // Select with custom colors (for kanban boards)
+ type: Field.select({
+ label: 'Account Type',
+ options: [
+ { label: 'Prospect', value: 'prospect', color: '#FFA500', default: true },
+ { label: 'Customer', value: 'customer', color: '#00AA00' },
+ { label: 'Partner', value: 'partner', color: '#0000FF' },
+ ],
+ }),
+ },
+
+ enable: {
+ apiEnabled: true,
+ trackHistory: true,
+ }
+});
+```
+
+
+
+## Create Application Manifest
+
+Create `objectstack.config.ts` to bundle your objects into an app:
+
+```typescript
+import { defineManifest } from '@objectstack/spec';
+import { Account } from './src/domains/crm/account.object';
+import { Contact } from './src/domains/crm/contact.object';
+
+export default defineManifest({
+ name: 'my_crm',
+ label: 'My CRM',
+ version: '1.0.0',
+ description: 'Simple CRM application',
+
+ objects: [Account, Contact],
+
+ navigation: {
+ tabs: [
+ {
+ label: 'Sales',
+ items: [
+ { type: 'object', object: 'account' },
+ { type: 'object', object: 'contact' },
+ ],
+ },
+ ],
+ },
+});
+```
+
+
## Validate the Protocol
-Create a build script `src/build.ts` to verify your definitions comply with the ObjectStack Protocol.
+Create a build script `src/build.ts` to verify your definitions:
```typescript
-import { Contact } from './objects/contact.schema';
+import config from '../objectstack.config';
// This will throw a ZodError if your schema is invalid
-const protocol = Contact.parse(Contact);
+console.log(`✅ App '${config.label}' is valid!`);
+console.log(`📦 Objects: ${config.objects.map(o => o.name).join(', ')}`);
-console.log(`✅ Object '${protocol.name}' is valid ObjectStack Metadata!`);
-console.log(JSON.stringify(protocol, null, 2));
+// Export as JSON for runtime use
+import fs from 'fs';
+fs.writeFileSync(
+ 'dist/manifest.json',
+ JSON.stringify(config, null, 2)
+);
+```
+
+Run it:
+
+```bash
+npx tsx src/build.ts
+```
+
+
+
+## Explore Advanced Features
+
+Now that you have a working app, explore advanced features:
+
+### 1. Add Validation Rules
+
+```typescript
+validations: [
+ {
+ name: 'unique_email',
+ type: 'unique',
+ fields: ['email'],
+ message: 'Email already exists',
+ },
+ {
+ name: 'positive_revenue',
+ type: 'script',
+ expression: 'annual_revenue >= 0',
+ message: 'Revenue must be positive',
+ },
+]
+```
+
+### 2. Add Workflow Rules
+
+```typescript
+workflows: [
+ {
+ name: 'update_last_activity',
+ trigger: 'on_update',
+ actions: [
+ {
+ type: 'field_update',
+ field: 'last_activity_date',
+ value: 'TODAY()',
+ },
+ ],
+ },
+]
+```
+
+### 3. Configure Views
+
+```typescript
+views: {
+ list: {
+ type: 'grid',
+ columns: ['account_number', 'name', 'type', 'annual_revenue'],
+ filters: [
+ { field: 'type', operator: '=', value: 'customer' }
+ ],
+ },
+ kanban: {
+ type: 'kanban',
+ groupBy: 'type',
+ columns: ['name', 'annual_revenue'],
+ },
+}
```
@@ -68,10 +275,15 @@ console.log(JSON.stringify(protocol, null, 2));
Now that you have valid metadata, you can:
-1. **Generate SQL**: Use the Protocol Compiler (Coming Soon) to generate `CREATE TABLE` statements.
-2. **Generate UI**: Feed the JSON into the `` React component.
-3. **Deploy**: Push the JSON to an ObjectOS Kernel.
+1. **Explore Examples**: Check out the [CRM Example](/examples/crm) for a full-featured implementation
+2. **Learn Field Types**: See the [Field Types Guide](/docs/guides/field-types) for all 30+ field types
+3. **Build UI**: Use the metadata with ObjectStack runtime to generate interfaces
+4. **Deploy**: Push to an ObjectStack kernel for production use
+**Additional Resources:**
+- [Object Schema Reference](/docs/references/data/core/Object)
+- [Validation Rules](/docs/guides/validation-rules)
+- [Workflow Automation](/docs/guides/workflows)
diff --git a/content/docs/guides/meta.cn.json b/content/docs/guides/meta.cn.json
index 2e84624..b769a4f 100644
--- a/content/docs/guides/meta.cn.json
+++ b/content/docs/guides/meta.cn.json
@@ -5,6 +5,9 @@
"getting-started",
"installation",
"project-structure",
+ "field-types",
+ "view-configuration",
+ "workflows-validation",
"custom-driver"
]
-}
+}
\ No newline at end of file
diff --git a/content/docs/guides/meta.json b/content/docs/guides/meta.json
index 1618fe0..78b2596 100644
--- a/content/docs/guides/meta.json
+++ b/content/docs/guides/meta.json
@@ -5,6 +5,9 @@
"getting-started",
"installation",
"project-structure",
+ "field-types",
+ "view-configuration",
+ "workflows-validation",
"custom-driver"
]
}
\ No newline at end of file
diff --git a/content/docs/guides/view-configuration.mdx b/content/docs/guides/view-configuration.mdx
new file mode 100644
index 0000000..dad717a
--- /dev/null
+++ b/content/docs/guides/view-configuration.mdx
@@ -0,0 +1,807 @@
+---
+title: View Configuration
+description: Complete guide to configuring Grid, Kanban, Calendar, Gantt views and forms in ObjectStack
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+# View Configuration Guide
+
+ObjectStack provides **5 list view types** and **3 form layouts** to visualize and interact with data. This guide covers all configuration options with practical examples.
+
+## List View Types
+
+1. **Grid** - Traditional table/spreadsheet view
+2. **Kanban** - Card-based workflow board
+3. **Calendar** - Date-based visualization
+4. **Gantt** - Timeline/project management view
+5. **Map** - Geographic location view
+
+---
+
+## 1. Grid View
+
+Traditional table view with rows and columns.
+
+### Basic Configuration
+
+```typescript
+import { ObjectSchema, Field } from '@objectstack/spec';
+
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: 'Account',
+
+ fields: {
+ account_number: Field.autonumber({ label: 'Account Number', format: 'ACC-{0000}' }),
+ name: Field.text({ label: 'Account Name' }),
+ type: Field.select({
+ label: 'Type',
+ options: [
+ { label: 'Customer', value: 'customer' },
+ { label: 'Partner', value: 'partner' },
+ ],
+ }),
+ annual_revenue: Field.currency({ label: 'Annual Revenue' }),
+ industry: Field.select({ label: 'Industry', options: ['Tech', 'Finance', 'Healthcare'] }),
+ created_at: Field.datetime({ label: 'Created' }),
+ },
+
+ views: {
+ list: {
+ type: 'grid',
+ columns: ['account_number', 'name', 'type', 'annual_revenue', 'industry'],
+ sort: [
+ { field: 'created_at', order: 'desc' }
+ ],
+ },
+ },
+});
+```
+
+### Advanced Grid Configuration
+
+```typescript
+views: {
+ // Default grid view
+ list: {
+ type: 'grid',
+ columns: ['name', 'type', 'annual_revenue', 'owner'],
+
+ // Filter configuration
+ filter: [
+ { field: 'type', operator: '=', value: 'customer' },
+ { field: 'annual_revenue', operator: '>', value: 100000 },
+ ],
+
+ // Sorting
+ sort: [
+ { field: 'annual_revenue', order: 'desc' },
+ { field: 'name', order: 'asc' },
+ ],
+
+ // Search configuration
+ searchableFields: ['name', 'account_number'],
+ },
+
+ // Additional named views
+ listViews: {
+ // High-value customers
+ high_value: {
+ name: 'high_value',
+ label: 'High Value Customers',
+ type: 'grid',
+ columns: ['name', 'annual_revenue', 'owner', 'last_activity'],
+ filter: [
+ { field: 'type', operator: '=', value: 'customer' },
+ { field: 'annual_revenue', operator: '>=', value: 500000 },
+ ],
+ sort: [{ field: 'annual_revenue', order: 'desc' }],
+ },
+
+ // Recently created
+ recent: {
+ name: 'recent',
+ label: 'Recently Created',
+ type: 'grid',
+ columns: ['name', 'type', 'created_at', 'owner'],
+ sort: [{ field: 'created_at', order: 'desc' }],
+ },
+ },
+}
+```
+
+### Filter Operators
+
+Available filter operators:
+
+```typescript
+// Comparison
+{ field: 'amount', operator: '=', value: 1000 }
+{ field: 'amount', operator: '!=', value: 0 }
+{ field: 'amount', operator: '>', value: 5000 }
+{ field: 'amount', operator: '>=', value: 1000 }
+{ field: 'amount', operator: '<', value: 10000 }
+{ field: 'amount', operator: '<=', value: 50000 }
+
+// String
+{ field: 'name', operator: 'contains', value: 'tech' }
+{ field: 'name', operator: 'startsWith', value: 'A' }
+{ field: 'name', operator: 'endsWith', value: 'Inc' }
+
+// NULL checks
+{ field: 'description', operator: 'isNull' }
+{ field: 'description', operator: 'isNotNull' }
+
+// Multi-value
+{ field: 'type', operator: 'in', value: ['customer', 'partner'] }
+{ field: 'type', operator: 'notIn', value: ['former'] }
+```
+
+---
+
+## 2. Kanban View
+
+Card-based workflow board grouped by a select field.
+
+### Basic Configuration
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ name: Field.text({ label: 'Opportunity Name' }),
+ stage: Field.select({
+ label: 'Stage',
+ options: [
+ { label: 'Prospecting', value: 'prospecting', color: '#FFA500' },
+ { label: 'Qualification', value: 'qualification', color: '#FFD700' },
+ { label: 'Proposal', value: 'proposal', color: '#4169E1' },
+ { label: 'Negotiation', value: 'negotiation', color: '#9370DB' },
+ { label: 'Closed Won', value: 'closed_won', color: '#00AA00' },
+ { label: 'Closed Lost', value: 'closed_lost', color: '#DC143C' },
+ ],
+ }),
+ amount: Field.currency({ label: 'Amount' }),
+ account: Field.lookup('account', { label: 'Account' }),
+ close_date: Field.date({ label: 'Close Date' }),
+ },
+
+ views: {
+ list: {
+ type: 'kanban',
+ columns: ['name', 'account', 'amount', 'close_date'], // Fields shown on cards
+
+ kanban: {
+ groupByField: 'stage', // Creates columns for each stage
+ summarizeField: 'amount', // Sum amounts at top of each column
+ },
+ },
+ },
+});
+```
+
+### Advanced Kanban
+
+```typescript
+views: {
+ listViews: {
+ sales_pipeline: {
+ name: 'sales_pipeline',
+ label: 'Sales Pipeline',
+ type: 'kanban',
+
+ // Card fields
+ columns: ['name', 'account', 'amount', 'probability', 'owner'],
+
+ // Kanban configuration
+ kanban: {
+ groupByField: 'stage',
+ summarizeField: 'amount', // Show total $ per column
+ },
+
+ // Filter to active opportunities only
+ filter: [
+ { field: 'is_active', operator: '=', value: true },
+ ],
+
+ // Sort cards within columns
+ sort: [
+ { field: 'amount', order: 'desc' },
+ ],
+ },
+ },
+}
+```
+
+### Kanban Features
+
+- **Drag & Drop**: Users can drag cards between columns (updates `groupByField`)
+- **Column Headers**: Show count and sum (if `summarizeField` defined)
+- **Colors**: Use option colors from select field for column headers
+- **Filters**: Apply filters to show subset of records
+
+---
+
+## 3. Calendar View
+
+Date-based visualization for events, tasks, and deadlines.
+
+### Basic Configuration
+
+```typescript
+export const Event = ObjectSchema.create({
+ name: 'event',
+ label: 'Event',
+
+ fields: {
+ title: Field.text({ label: 'Event Title' }),
+ start_date: Field.datetime({ label: 'Start Date' }),
+ end_date: Field.datetime({ label: 'End Date' }),
+ event_type: Field.select({
+ label: 'Type',
+ options: [
+ { label: 'Meeting', value: 'meeting', color: '#4169E1' },
+ { label: 'Webinar', value: 'webinar', color: '#00AA00' },
+ { label: 'Conference', value: 'conference', color: '#FFA500' },
+ ],
+ }),
+ location: Field.text({ label: 'Location' }),
+ },
+
+ views: {
+ list: {
+ type: 'calendar',
+ columns: ['title', 'location'], // Extra fields shown in tooltip
+
+ calendar: {
+ startDateField: 'start_date', // Required
+ endDateField: 'end_date', // Optional (single-day events if omitted)
+ titleField: 'title', // Event label
+ colorField: 'event_type', // Color events by type
+ },
+ },
+ },
+});
+```
+
+### Single-Day Events
+
+For tasks or activities without end dates:
+
+```typescript
+export const Task = ObjectSchema.create({
+ name: 'task',
+ label: 'Task',
+
+ fields: {
+ subject: Field.text({ label: 'Subject' }),
+ due_date: Field.date({ label: 'Due Date' }),
+ priority: Field.select({
+ options: [
+ { label: 'High', value: 'high', color: '#DC143C' },
+ { label: 'Normal', value: 'normal', color: '#4169E1' },
+ { label: 'Low', value: 'low', color: '#999999' },
+ ],
+ }),
+ },
+
+ views: {
+ list: {
+ type: 'calendar',
+ columns: ['subject'],
+
+ calendar: {
+ startDateField: 'due_date',
+ // No endDateField - shows as single-day events
+ titleField: 'subject',
+ colorField: 'priority',
+ },
+ },
+ },
+});
+```
+
+### Calendar Features
+
+- **Multiple Views**: Month, Week, Day, Agenda
+- **Color Coding**: By select field option colors
+- **Multi-Day Events**: Span multiple days if `endDateField` provided
+- **Drag & Drop**: Update dates by dragging events
+- **Filters**: Show subset of events
+
+---
+
+## 4. Gantt View
+
+Timeline/project management view for tasks with dependencies.
+
+### Configuration
+
+```typescript
+export const ProjectTask = ObjectSchema.create({
+ name: 'project_task',
+ label: 'Project Task',
+
+ fields: {
+ task_name: Field.text({ label: 'Task Name' }),
+ start_date: Field.date({ label: 'Start Date' }),
+ end_date: Field.date({ label: 'End Date' }),
+ progress: Field.percent({ label: 'Progress' }),
+ dependencies: Field.text({ label: 'Dependencies' }), // Comma-separated task IDs
+ assigned_to: Field.lookup('user', { label: 'Assigned To' }),
+ },
+
+ views: {
+ list: {
+ type: 'gantt',
+ columns: ['task_name', 'assigned_to'], // Shown in left panel
+
+ gantt: {
+ startDateField: 'start_date', // Required
+ endDateField: 'end_date', // Required
+ titleField: 'task_name', // Bar label
+ progressField: 'progress', // Optional (shows % complete)
+ dependenciesField: 'dependencies', // Optional (draws arrows)
+ },
+
+ sort: [
+ { field: 'start_date', order: 'asc' },
+ ],
+ },
+ },
+});
+```
+
+### Gantt Features
+
+- **Timeline Bars**: Visual representation of task duration
+- **Progress Indicator**: Shows completion percentage
+- **Dependencies**: Arrows between related tasks
+- **Critical Path**: Highlight blocking tasks
+- **Drag & Drop**: Adjust dates and dependencies
+- **Zoom Levels**: Day, Week, Month, Quarter, Year
+
+---
+
+## 5. Map View
+
+Geographic visualization for location-based data.
+
+### Configuration
+
+```typescript
+export const Store = ObjectSchema.create({
+ name: 'store',
+ label: 'Store',
+
+ fields: {
+ store_name: Field.text({ label: 'Store Name' }),
+ address: Field.address({ label: 'Address' }),
+ location: Field.location({ label: 'Coordinates' }),
+ store_type: Field.select({
+ options: [
+ { label: 'Flagship', value: 'flagship', color: '#FFD700' },
+ { label: 'Standard', value: 'standard', color: '#4169E1' },
+ { label: 'Outlet', value: 'outlet', color: '#999999' },
+ ],
+ }),
+ },
+
+ views: {
+ list: {
+ type: 'map',
+ columns: ['store_name', 'address'], // Info shown in popup
+
+ map: {
+ locationField: 'location', // GPS coordinates
+ titleField: 'store_name',
+ colorField: 'store_type', // Marker color
+ },
+ },
+ },
+});
+```
+
+---
+
+## Form Views
+
+Three layout types for record detail pages:
+
+1. **Simple** - Single page with sections
+2. **Tabbed** - Multiple tabs for grouped fields
+3. **Wizard** - Step-by-step multi-page form
+
+---
+
+## 1. Simple Form
+
+Single-page layout with collapsible sections.
+
+### Configuration
+
+```typescript
+export const Contact = ObjectSchema.create({
+ name: 'contact',
+ label: 'Contact',
+
+ fields: {
+ // ... field definitions
+ },
+
+ views: {
+ form: {
+ type: 'simple',
+ sections: [
+ {
+ label: 'Basic Information',
+ columns: 2, // 2-column layout
+ fields: ['first_name', 'last_name', 'email', 'phone'],
+ },
+ {
+ label: 'Address',
+ columns: 2,
+ collapsible: true,
+ collapsed: false,
+ fields: ['street', 'city', 'state', 'postal_code', 'country'],
+ },
+ {
+ label: 'Additional Details',
+ columns: 1, // Full-width fields
+ collapsible: true,
+ collapsed: true, // Collapsed by default
+ fields: ['notes', 'description'],
+ },
+ ],
+ },
+ },
+});
+```
+
+### Section Configuration
+
+```typescript
+{
+ label: 'Section Title', // Optional header
+ columns: 2, // 1, 2, 3, or 4 columns
+ collapsible: true, // Can be collapsed
+ collapsed: false, // Initial state
+ fields: ['field1', 'field2'], // Fields to include
+}
+```
+
+---
+
+## 2. Tabbed Form
+
+Multi-tab layout for complex objects with many fields.
+
+### Configuration
+
+```typescript
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: 'Account',
+
+ fields: {
+ // ... many fields
+ },
+
+ views: {
+ form: {
+ type: 'tabbed',
+ sections: [
+ {
+ label: 'Overview', // Tab 1
+ columns: 2,
+ fields: [
+ 'account_number',
+ 'name',
+ 'type',
+ 'industry',
+ 'annual_revenue',
+ 'website',
+ ],
+ },
+ {
+ label: 'Contact Information', // Tab 2
+ columns: 2,
+ fields: [
+ 'phone',
+ 'email',
+ 'billing_address',
+ 'shipping_address',
+ ],
+ },
+ {
+ label: 'Description', // Tab 3
+ columns: 1,
+ fields: ['description', 'notes'],
+ },
+ ],
+ },
+ },
+});
+```
+
+---
+
+## 3. Wizard Form
+
+Multi-step form for guided data entry.
+
+### Configuration
+
+```typescript
+export const Lead = ObjectSchema.create({
+ name: 'lead',
+ label: 'Lead',
+
+ fields: {
+ // ... field definitions
+ },
+
+ views: {
+ form: {
+ type: 'wizard',
+ sections: [
+ {
+ label: 'Step 1: Basic Info', // Wizard step 1
+ fields: ['first_name', 'last_name', 'company', 'title'],
+ },
+ {
+ label: 'Step 2: Contact Details', // Step 2
+ fields: ['email', 'phone', 'address'],
+ },
+ {
+ label: 'Step 3: Qualification', // Step 3
+ fields: ['lead_source', 'industry', 'annual_revenue', 'status'],
+ },
+ ],
+ },
+ },
+});
+```
+
+### Wizard Features
+
+- **Progress Indicator**: Shows current step
+- **Navigation**: Previous/Next buttons
+- **Validation**: Each step validated before proceeding
+- **Summary**: Review all data before submit
+
+---
+
+## Multiple Views
+
+Define multiple views for different use cases.
+
+### Example
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ // ... fields
+ },
+
+ views: {
+ // Default list view (Grid)
+ list: {
+ type: 'grid',
+ columns: ['name', 'account', 'amount', 'stage', 'close_date'],
+ sort: [{ field: 'close_date', order: 'asc' }],
+ },
+
+ // Default form view
+ form: {
+ type: 'tabbed',
+ sections: [
+ { label: 'Details', fields: ['name', 'account', 'amount'] },
+ { label: 'Timeline', fields: ['stage', 'close_date'] },
+ ],
+ },
+
+ // Additional list views
+ listViews: {
+ // Kanban pipeline
+ pipeline: {
+ name: 'pipeline',
+ label: 'Sales Pipeline',
+ type: 'kanban',
+ columns: ['name', 'amount', 'close_date'],
+ kanban: {
+ groupByField: 'stage',
+ summarizeField: 'amount',
+ },
+ },
+
+ // Calendar of close dates
+ timeline: {
+ name: 'timeline',
+ label: 'Timeline',
+ type: 'calendar',
+ columns: ['name', 'amount'],
+ calendar: {
+ startDateField: 'close_date',
+ titleField: 'name',
+ colorField: 'stage',
+ },
+ },
+
+ // My opportunities
+ my_opportunities: {
+ name: 'my_opportunities',
+ label: 'My Opportunities',
+ type: 'grid',
+ columns: ['name', 'account', 'amount', 'stage'],
+ filter: [
+ { field: 'owner', operator: '=', value: '$current_user' },
+ ],
+ },
+ },
+
+ // Additional form views
+ formViews: {
+ // Quick create form
+ quick_create: {
+ type: 'simple',
+ sections: [
+ {
+ label: 'Essential Fields',
+ columns: 2,
+ fields: ['name', 'account', 'amount', 'close_date', 'stage'],
+ },
+ ],
+ },
+ },
+ },
+});
+```
+
+---
+
+## Best Practices
+
+### List Views
+
+1. **Column Selection**: Show 4-7 columns for optimal readability
+2. **Default Sort**: Always define a default sort order
+3. **Filters**: Pre-filter common views (e.g., "My Records", "Active Only")
+4. **Searchable**: Enable search on key text fields
+5. **Named Views**: Create specific views for common use cases
+
+### Kanban
+
+1. **Group Field**: Use select fields with 3-7 options (too many = cluttered)
+2. **Card Fields**: Show 3-5 key fields on cards
+3. **Colors**: Define colors for select options
+4. **Summarize**: Add monetary totals for sales/revenue tracking
+
+### Calendar
+
+1. **Date Fields**: Use datetime for multi-day events, date for single-day
+2. **Color Coding**: Use select field with meaningful colors
+3. **Title Field**: Choose concise, descriptive field
+4. **Filters**: Allow filtering by type, owner, etc.
+
+### Gantt
+
+1. **Dependencies**: Use structured format (comma-separated IDs or JSON)
+2. **Progress**: Percentage field (0-100)
+3. **Sort**: Sort by start date for logical flow
+4. **Granularity**: Choose appropriate zoom level (day/week/month)
+
+### Forms
+
+1. **Sections**: Group related fields logically
+2. **Columns**: Use 2 columns for most sections, 1 for wide fields (textarea, rich text)
+3. **Collapsible**: Make optional sections collapsible
+4. **Tabs**: Use tabs when >15 fields
+5. **Wizard**: Use for complex multi-step processes
+
+---
+
+## Real-World Example
+
+Complete view configuration for CRM Opportunity:
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+ pluralLabel: 'Opportunities',
+
+ fields: {
+ name: Field.text({ label: 'Name' }),
+ account: Field.lookup('account', { label: 'Account' }),
+ amount: Field.currency({ label: 'Amount' }),
+ stage: Field.select({
+ label: 'Stage',
+ options: [
+ { label: 'Prospecting', value: 'prospecting', color: '#FFA500' },
+ { label: 'Qualification', value: 'qualification', color: '#FFD700' },
+ { label: 'Proposal', value: 'proposal', color: '#4169E1' },
+ { label: 'Closed Won', value: 'closed_won', color: '#00AA00' },
+ { label: 'Closed Lost', value: 'closed_lost', color: '#DC143C' },
+ ],
+ }),
+ probability: Field.percent({ label: 'Probability' }),
+ close_date: Field.date({ label: 'Close Date' }),
+ owner: Field.lookup('user', { label: 'Owner' }),
+ description: Field.textarea({ label: 'Description' }),
+ },
+
+ views: {
+ // Default grid
+ list: {
+ type: 'grid',
+ columns: ['name', 'account', 'amount', 'stage', 'close_date', 'owner'],
+ sort: [{ field: 'close_date', order: 'asc' }],
+ searchableFields: ['name', 'account'],
+ },
+
+ // Default form
+ form: {
+ type: 'simple',
+ sections: [
+ {
+ label: 'Opportunity Information',
+ columns: 2,
+ fields: ['name', 'account', 'amount', 'close_date'],
+ },
+ {
+ label: 'Stage & Forecast',
+ columns: 2,
+ fields: ['stage', 'probability', 'owner'],
+ },
+ {
+ label: 'Description',
+ columns: 1,
+ fields: ['description'],
+ },
+ ],
+ },
+
+ // Named views
+ listViews: {
+ pipeline: {
+ type: 'kanban',
+ columns: ['name', 'amount', 'close_date'],
+ kanban: {
+ groupByField: 'stage',
+ summarizeField: 'amount',
+ },
+ filter: [
+ { field: 'stage', operator: 'notIn', value: ['closed_won', 'closed_lost'] },
+ ],
+ },
+
+ closing_soon: {
+ type: 'grid',
+ columns: ['name', 'account', 'amount', 'close_date', 'probability'],
+ filter: [
+ { field: 'close_date', operator: '<=', value: '$30_days_from_now' },
+ { field: 'stage', operator: '!=', value: 'closed_won' },
+ { field: 'stage', operator: '!=', value: 'closed_lost' },
+ ],
+ sort: [{ field: 'close_date', order: 'asc' }],
+ },
+ },
+ },
+});
+```
+
+---
+
+## Next Steps
+
+- [Field Types Guide](/docs/guides/field-types)
+- [Workflows & Validation](/docs/guides/workflows-validation)
+- [Dashboard Configuration](/docs/guides/dashboards)
+- [CRM Example](/examples/crm) - See all view types in action
diff --git a/content/docs/guides/workflows-validation.mdx b/content/docs/guides/workflows-validation.mdx
new file mode 100644
index 0000000..8d1fbe3
--- /dev/null
+++ b/content/docs/guides/workflows-validation.mdx
@@ -0,0 +1,734 @@
+---
+title: Validation Rules & Workflows
+description: Complete guide to validation rules and workflow automation in ObjectStack
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+# Validation Rules & Workflows
+
+ObjectStack provides powerful **validation rules** and **workflow automation** to enforce business logic and automate repetitive tasks. This guide covers all validation types and workflow patterns with practical examples.
+
+## Validation Rules
+
+Validation rules ensure data quality by checking record values before save. They can be defined at the object level and execute automatically.
+
+### Types of Validation Rules
+
+ObjectStack supports **7 validation types**, each optimized for specific use cases:
+
+1. **Script Validation** - Generic formula-based validation
+2. **Uniqueness Validation** - Enforce unique constraints
+3. **State Machine Validation** - Control state transitions
+4. **Format Validation** - Regex or format checking
+5. **Cross-Field Validation** - Compare multiple fields
+6. **Async Validation** - Remote API validation
+7. **Custom Validator** - User-defined functions
+
+---
+
+## 1. Script Validation
+
+Generic formula-based validation for any business logic.
+
+### Configuration
+
+```typescript
+import { ObjectSchema, Field } from '@objectstack/spec';
+
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ amount: Field.currency({ label: 'Amount' }),
+ probability: Field.percent({ label: 'Probability' }),
+ close_date: Field.date({ label: 'Close Date' }),
+ },
+
+ validations: [
+ {
+ name: 'positive_amount',
+ type: 'script',
+ condition: 'amount < 0', // When TRUE, validation FAILS
+ message: 'Amount must be greater than or equal to 0',
+ severity: 'error',
+ active: true,
+ },
+ {
+ name: 'probability_range',
+ type: 'script',
+ condition: 'probability < 0 OR probability > 100',
+ message: 'Probability must be between 0 and 100',
+ severity: 'error',
+ },
+ {
+ name: 'future_close_date',
+ type: 'script',
+ condition: 'close_date < TODAY()',
+ message: 'Close date cannot be in the past',
+ severity: 'warning', // Warning instead of error
+ },
+ ],
+});
+```
+
+
+ **Important:** The `condition` is inverted logic - it defines when validation **FAILS**. If the condition evaluates to `TRUE`, the validation error is shown.
+
+
+### Expression Examples
+
+```typescript
+// Number comparisons
+condition: 'revenue < 1000'
+condition: 'quantity <= 0'
+condition: 'discount > 50'
+
+// String checks
+condition: 'LEN(name) < 3'
+condition: 'ISBLANK(description)'
+condition: 'NOT(CONTAINS(email, "@"))'
+
+// Date validations
+condition: 'end_date < start_date'
+condition: 'due_date < TODAY()'
+condition: 'DAYS_BETWEEN(start_date, end_date) > 365'
+
+// Complex logic
+condition: 'stage = "Closed Won" AND amount = 0'
+condition: '(priority = "High" OR priority = "Critical") AND NOT(ISBLANK(assigned_to))'
+```
+
+---
+
+## 2. Uniqueness Validation
+
+Optimized validation for enforcing unique constraints, better than script validation for uniqueness checks.
+
+### Configuration
+
+```typescript
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: 'Account',
+
+ fields: {
+ name: Field.text({ label: 'Account Name' }),
+ email: Field.email({ label: 'Email' }),
+ account_number: Field.text({ label: 'Account Number' }),
+ active: Field.boolean({ label: 'Active' }),
+ },
+
+ validations: [
+ // Single field uniqueness
+ {
+ name: 'unique_email',
+ type: 'unique',
+ fields: ['email'],
+ message: 'Email address already exists',
+ caseSensitive: false, // Ignore case
+ },
+
+ // Compound uniqueness (multiple fields)
+ {
+ name: 'unique_account_number',
+ type: 'unique',
+ fields: ['account_number'],
+ message: 'Account number must be unique',
+ caseSensitive: true,
+ },
+
+ // Scoped uniqueness (unique within subset)
+ {
+ name: 'unique_name_active',
+ type: 'unique',
+ fields: ['name'],
+ scope: 'active = true', // Only check uniqueness among active accounts
+ message: 'Active account with this name already exists',
+ },
+ ],
+});
+```
+
+### Use Cases
+
+- Email addresses
+- Username fields
+- Product SKUs
+- Invoice numbers
+- Unique combinations (e.g., name + region)
+
+---
+
+## 3. State Machine Validation
+
+Control allowed state transitions to prevent invalid workflow progressions.
+
+### Configuration
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ stage: Field.select({
+ label: 'Stage',
+ options: [
+ { label: 'Prospecting', value: 'prospecting' },
+ { label: 'Qualification', value: 'qualification' },
+ { label: 'Proposal', value: 'proposal' },
+ { label: 'Negotiation', value: 'negotiation' },
+ { label: 'Closed Won', value: 'closed_won' },
+ { label: 'Closed Lost', value: 'closed_lost' },
+ ],
+ }),
+ },
+
+ validations: [
+ {
+ name: 'stage_transition',
+ type: 'state_machine',
+ field: 'stage',
+ message: 'Invalid stage transition',
+ transitions: {
+ // From -> To (allowed states)
+ 'prospecting': ['qualification', 'closed_lost'],
+ 'qualification': ['prospecting', 'proposal', 'closed_lost'],
+ 'proposal': ['qualification', 'negotiation', 'closed_lost'],
+ 'negotiation': ['proposal', 'closed_won', 'closed_lost'],
+ 'closed_won': [], // No transitions allowed (terminal state)
+ 'closed_lost': [], // No transitions allowed (terminal state)
+ },
+ },
+ ],
+});
+```
+
+### Diagram
+
+```
+Prospecting → Qualification → Proposal → Negotiation → Closed Won
+ ↓ ↓ ↓ ↓
+ Closed Lost ← Closed Lost ← Closed Lost ← Closed Lost
+```
+
+---
+
+## 4. Format Validation
+
+Validate field formats using regex or predefined patterns.
+
+### Configuration
+
+```typescript
+export const Contact = ObjectSchema.create({
+ name: 'contact',
+ label: 'Contact',
+
+ fields: {
+ phone: Field.phone({ label: 'Phone' }),
+ website: Field.url({ label: 'Website' }),
+ postal_code: Field.text({ label: 'Postal Code' }),
+ json_data: Field.textarea({ label: 'JSON Data' }),
+ },
+
+ validations: [
+ // Regex validation
+ {
+ name: 'us_postal_code',
+ type: 'format',
+ field: 'postal_code',
+ regex: '^\\d{5}(-\\d{4})?$', // 12345 or 12345-6789
+ message: 'Invalid US postal code format',
+ },
+
+ // Predefined format
+ {
+ name: 'valid_phone',
+ type: 'format',
+ field: 'phone',
+ format: 'phone',
+ message: 'Invalid phone number format',
+ },
+
+ {
+ name: 'valid_json',
+ type: 'format',
+ field: 'json_data',
+ format: 'json',
+ message: 'Invalid JSON format',
+ },
+ ],
+});
+```
+
+### Available Formats
+
+- `email` - Email address
+- `url` - Website URL
+- `phone` - Phone number
+- `json` - Valid JSON
+
+---
+
+## 5. Cross-Field Validation
+
+Validate relationships between multiple fields.
+
+### Configuration
+
+```typescript
+export const Event = ObjectSchema.create({
+ name: 'event',
+ label: 'Event',
+
+ fields: {
+ start_date: Field.datetime({ label: 'Start Date' }),
+ end_date: Field.datetime({ label: 'End Date' }),
+ min_attendees: Field.number({ label: 'Min Attendees' }),
+ max_attendees: Field.number({ label: 'Max Attendees' }),
+ budget: Field.currency({ label: 'Budget' }),
+ actual_cost: Field.currency({ label: 'Actual Cost' }),
+ },
+
+ validations: [
+ {
+ name: 'end_after_start',
+ type: 'cross_field',
+ fields: ['start_date', 'end_date'],
+ condition: 'end_date <= start_date',
+ message: 'End date must be after start date',
+ },
+
+ {
+ name: 'max_greater_than_min',
+ type: 'cross_field',
+ fields: ['min_attendees', 'max_attendees'],
+ condition: 'max_attendees < min_attendees',
+ message: 'Maximum attendees must be greater than minimum',
+ },
+
+ {
+ name: 'budget_check',
+ type: 'cross_field',
+ fields: ['budget', 'actual_cost'],
+ condition: 'actual_cost > budget',
+ message: 'Actual cost exceeds budget',
+ severity: 'warning', // Allow save but warn
+ },
+ ],
+});
+```
+
+---
+
+## 6. Async Validation
+
+Validate data against external APIs or databases.
+
+### Configuration
+
+```typescript
+export const User = ObjectSchema.create({
+ name: 'user',
+ label: 'User',
+
+ fields: {
+ username: Field.text({ label: 'Username' }),
+ tax_id: Field.text({ label: 'Tax ID' }),
+ },
+
+ validations: [
+ {
+ name: 'check_username_availability',
+ type: 'async',
+ field: 'username',
+ validatorUrl: '/api/validate/username',
+ timeout: 5000,
+ debounce: 500, // Wait 500ms after typing stops
+ message: 'Username is already taken',
+ params: {
+ minLength: 3,
+ },
+ },
+
+ {
+ name: 'verify_tax_id',
+ type: 'async',
+ field: 'tax_id',
+ validatorFunction: 'validateTaxId', // Custom function
+ timeout: 10000,
+ message: 'Invalid tax ID',
+ },
+ ],
+});
+```
+
+---
+
+## 7. Custom Validator
+
+User-defined validation logic with code references.
+
+### Configuration
+
+```typescript
+export const Order = ObjectSchema.create({
+ name: 'order',
+ label: 'Order',
+
+ fields: {
+ items: Field.textarea({ label: 'Order Items (JSON)' }),
+ total: Field.currency({ label: 'Total' }),
+ },
+
+ validations: [
+ {
+ name: 'validate_order_total',
+ type: 'custom',
+ validatorFunction: 'validateOrderTotal',
+ message: 'Order total does not match line items',
+ params: {
+ includeTax: true,
+ includeShipping: true,
+ },
+ },
+ ],
+});
+```
+
+---
+
+## Workflow Automation
+
+Workflows automate actions when records are created, updated, or deleted.
+
+### Workflow Components
+
+1. **Trigger** - When to execute (on_create, on_update, on_delete, schedule)
+2. **Criteria** - Condition to check (optional)
+3. **Actions** - What to execute (field_update, email_alert, etc.)
+
+---
+
+## Workflow Examples
+
+### 1. Field Update on Create
+
+```typescript
+export const Lead = ObjectSchema.create({
+ name: 'lead',
+ label: 'Lead',
+
+ fields: {
+ status: Field.select({
+ options: ['New', 'Contacted', 'Qualified', 'Converted'],
+ }),
+ created_date: Field.datetime({ label: 'Created Date' }),
+ last_contacted: Field.datetime({ label: 'Last Contacted' }),
+ },
+
+ workflows: [
+ {
+ name: 'set_default_status',
+ objectName: 'lead',
+ triggerType: 'on_create',
+ actions: [
+ {
+ name: 'set_status_new',
+ type: 'field_update',
+ field: 'status',
+ value: 'New',
+ },
+ {
+ name: 'set_created_date',
+ type: 'field_update',
+ field: 'created_date',
+ value: 'NOW()',
+ },
+ ],
+ active: true,
+ },
+ ],
+});
+```
+
+---
+
+### 2. Conditional Workflow
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ stage: Field.select({ options: ['...'] }),
+ amount: Field.currency({ label: 'Amount' }),
+ owner: Field.lookup('user', { label: 'Owner' }),
+ approved: Field.boolean({ label: 'Approved' }),
+ },
+
+ workflows: [
+ {
+ name: 'require_approval_large_deals',
+ objectName: 'opportunity',
+ triggerType: 'on_update',
+ criteria: 'amount > 100000 AND stage = "Closed Won"', // Only for big deals
+ actions: [
+ {
+ name: 'set_approval_required',
+ type: 'field_update',
+ field: 'approved',
+ value: 'false',
+ },
+ {
+ name: 'notify_manager',
+ type: 'email_alert',
+ template: 'approval_required_email',
+ recipients: ['sales_manager@company.com'],
+ },
+ ],
+ active: true,
+ },
+ ],
+});
+```
+
+---
+
+### 3. Email Alert Workflow
+
+```typescript
+export const Case = ObjectSchema.create({
+ name: 'case',
+ label: 'Case',
+
+ fields: {
+ priority: Field.select({ options: ['Low', 'Medium', 'High', 'Critical'] }),
+ status: Field.select({ options: ['Open', 'In Progress', 'Resolved'] }),
+ contact: Field.lookup('contact', { label: 'Contact' }),
+ },
+
+ workflows: [
+ {
+ name: 'escalate_critical_cases',
+ objectName: 'case',
+ triggerType: 'on_create_or_update',
+ criteria: 'priority = "Critical" AND status = "Open"',
+ actions: [
+ {
+ name: 'notify_support_team',
+ type: 'email_alert',
+ template: 'critical_case_alert',
+ recipients: ['support_team@company.com', 'manager@company.com'],
+ },
+ ],
+ active: true,
+ },
+ ],
+});
+```
+
+---
+
+### 4. Update Timestamp Workflow
+
+```typescript
+export const Account = ObjectSchema.create({
+ name: 'account',
+ label: 'Account',
+
+ fields: {
+ last_activity_date: Field.datetime({ label: 'Last Activity' }),
+ last_modified_date: Field.datetime({ label: 'Last Modified' }),
+ },
+
+ workflows: [
+ {
+ name: 'update_last_activity',
+ objectName: 'account',
+ triggerType: 'on_update',
+ actions: [
+ {
+ name: 'set_last_activity',
+ type: 'field_update',
+ field: 'last_activity_date',
+ value: 'NOW()',
+ },
+ ],
+ active: true,
+ },
+ ],
+});
+```
+
+---
+
+## Best Practices
+
+### Validation Rules
+
+1. **Use Specific Types**: Use `unique` instead of `script` for uniqueness, `state_machine` instead of complex conditions
+2. **Clear Messages**: Provide actionable error messages that guide users
+3. **Severity Levels**: Use `warning` for soft validations, `error` for hard stops
+4. **Performance**: Avoid complex formulas in validations, use indexes for uniqueness checks
+5. **Testing**: Test all edge cases and state transitions
+
+### Workflows
+
+1. **Criteria First**: Use criteria to limit workflow execution, not blanket triggers
+2. **Avoid Loops**: Be careful with `on_update` workflows that update the same record
+3. **Batch-Safe**: Ensure workflows can handle bulk operations
+4. **Error Handling**: Workflows should not block saves on non-critical failures
+5. **Audit Trail**: Use field updates to maintain audit logs (last_modified_by, etc.)
+
+---
+
+## Formula Functions Reference
+
+Common functions used in validation conditions and workflow criteria:
+
+### String Functions
+- `CONCAT(str1, str2, ...)` - Concatenate strings
+- `LEN(str)` - String length
+- `ISBLANK(str)` - Check if empty
+- `CONTAINS(str, substring)` - Check if contains
+- `UPPER(str)`, `LOWER(str)` - Case conversion
+
+### Date Functions
+- `TODAY()` - Current date
+- `NOW()` - Current datetime
+- `DAYS_BETWEEN(date1, date2)` - Days between dates
+- `ADDDAYS(date, num)` - Add days to date
+
+### Logic Functions
+- `AND(cond1, cond2, ...)` - Logical AND
+- `OR(cond1, cond2, ...)` - Logical OR
+- `NOT(cond)` - Logical NOT
+- `IF(condition, true_value, false_value)` - Conditional
+
+### Number Functions
+- `ABS(num)` - Absolute value
+- `ROUND(num, decimals)` - Round number
+- `MAX(num1, num2, ...)` - Maximum
+- `MIN(num1, num2, ...)` - Minimum
+
+---
+
+## Real-World Example: CRM Opportunity
+
+Complete example combining validations and workflows:
+
+```typescript
+export const Opportunity = ObjectSchema.create({
+ name: 'opportunity',
+ label: 'Opportunity',
+
+ fields: {
+ name: Field.text({ label: 'Name', required: true }),
+ account: Field.lookup('account', { label: 'Account', required: true }),
+ amount: Field.currency({ label: 'Amount' }),
+ close_date: Field.date({ label: 'Close Date' }),
+ probability: Field.percent({ label: 'Probability' }),
+ stage: Field.select({
+ options: [
+ { label: 'Prospecting', value: 'prospecting' },
+ { label: 'Qualification', value: 'qualification' },
+ { label: 'Proposal', value: 'proposal' },
+ { label: 'Negotiation', value: 'negotiation' },
+ { label: 'Closed Won', value: 'closed_won' },
+ { label: 'Closed Lost', value: 'closed_lost' },
+ ],
+ }),
+ approved: Field.boolean({ label: 'Approved' }),
+ last_stage_change: Field.datetime({ label: 'Last Stage Change' }),
+ },
+
+ validations: [
+ // Basic validations
+ {
+ name: 'positive_amount',
+ type: 'script',
+ condition: 'amount < 0',
+ message: 'Amount must be positive',
+ },
+
+ // State machine
+ {
+ name: 'stage_progression',
+ type: 'state_machine',
+ field: 'stage',
+ message: 'Invalid stage transition',
+ transitions: {
+ 'prospecting': ['qualification', 'closed_lost'],
+ 'qualification': ['prospecting', 'proposal', 'closed_lost'],
+ 'proposal': ['qualification', 'negotiation', 'closed_lost'],
+ 'negotiation': ['proposal', 'closed_won', 'closed_lost'],
+ 'closed_won': [],
+ 'closed_lost': [],
+ },
+ },
+
+ // Cross-field validation
+ {
+ name: 'probability_stage_match',
+ type: 'cross_field',
+ fields: ['stage', 'probability'],
+ condition: 'stage = "Closed Won" AND probability < 100',
+ message: 'Closed Won opportunities must have 100% probability',
+ },
+ ],
+
+ workflows: [
+ // Update timestamp on stage change
+ {
+ name: 'track_stage_changes',
+ objectName: 'opportunity',
+ triggerType: 'on_update',
+ criteria: 'ISCHANGED(stage)',
+ actions: [
+ {
+ name: 'update_timestamp',
+ type: 'field_update',
+ field: 'last_stage_change',
+ value: 'NOW()',
+ },
+ ],
+ },
+
+ // Require approval for large deals
+ {
+ name: 'large_deal_approval',
+ objectName: 'opportunity',
+ triggerType: 'on_update',
+ criteria: 'amount > 500000 AND stage = "Negotiation"',
+ actions: [
+ {
+ name: 'request_approval',
+ type: 'field_update',
+ field: 'approved',
+ value: 'false',
+ },
+ {
+ name: 'notify_exec_team',
+ type: 'email_alert',
+ template: 'large_deal_approval',
+ recipients: ['ceo@company.com', 'cfo@company.com'],
+ },
+ ],
+ },
+ ],
+});
+```
+
+---
+
+## Next Steps
+
+- [Field Types Guide](/docs/guides/field-types)
+- [Object Schema Reference](/docs/references/data/core/Object)
+- [Formula Functions](/docs/references/data/formulas)
+- [CRM Example](/examples/crm) - See validations and workflows in action
diff --git a/content/docs/index.cn.mdx b/content/docs/index.cn.mdx
index b3f1c82..e76466e 100644
--- a/content/docs/index.cn.mdx
+++ b/content/docs/index.cn.mdx
@@ -1,11 +1,11 @@
---
-title: 欢迎来到 ObjectStack
-description: 后 SaaS 时代的元数据驱动协议
+title: 欢迎使用 ObjectStack
+description: 后 SaaS 时代的元数据驱动协议。
---
import { Book, Compass, FileText, Layers } from 'lucide-react';
-**ObjectStack** 不仅仅是一个框架;它是构建企业软件的**协议**。
+**ObjectStack** 不仅仅是一个框架;它是一个用于构建企业软件的**协议**。
它将*业务意图*(用 JSON/YAML 定义)与*技术执行*(由内核处理)解耦。
本文档是 ObjectStack 协议的权威参考。
@@ -17,13 +17,13 @@ import { Book, Compass, FileText, Layers } from 'lucide-react';
icon={}
title="快速开始"
href="/docs/guides/getting-started"
- description="5 分钟内构建你的第一个对象。学习 SDK 的基础知识。"
+ description="5 分钟内构建你的第一个对象。通过实际示例学习基础知识。"
/>
}
title="概念"
href="/docs/concepts/manifesto"
- description="理解「意图优于实现」的理念和「本地优先」架构。"
+ description="理解"意图优于实现"和"本地优先"架构的理念。"
/>
}
@@ -35,22 +35,37 @@ import { Book, Compass, FileText, Layers } from 'lucide-react';
icon={}
title="协议参考"
href="/docs/references/data/core/Object"
- description="字典。每个 Schema、字段类型和配置选项的全面参考。"
+ description="字典。每个模式、字段类型和配置选项的全面参考。"
/>
-## "三位一体"架构
+## 快速链接
-ObjectStack 建立在三个协同工作的支柱之上:
+### 基础指南
+- **[字段类型](/docs/guides/field-types)** - 30+ 种字段类型及示例(文本、数字、选择、查找、公式等)
+- **[视图配置](/docs/guides/view-configuration)** - 网格、看板、日历、甘特图和表单布局
+- **[工作流与验证](/docs/guides/workflows-validation)** - 业务规则和自动化
+- **[项目结构](/docs/guides/project-structure)** - 组织代码的最佳实践
-| 支柱 | 协议 | 职责 |
+### 示例
+- **[CRM 示例](/examples/crm)** - 全功能应用,包含 6 个对象、工作流、视图、仪表板
+- **[Todo 示例](/examples/todo)** - 快速入门最小化示例
+
+## "五位一体"架构
+
+ObjectStack 建立在五个协同工作的核心模块之上:
+
+| 模块 | 协议 | 职责 |
| :--- | :--- | :--- |
-| **数据层** | **[ObjectQL](/docs/specifications/data/architecture)** | 定义数据的形状(`Object`)以及如何访问它(`AST`)。不依赖于 SQL/NoSQL。 |
+| **数据层** | **[ObjectQL](/docs/specifications/data/architecture)** | 定义数据的形状(`Object`、`Field`)以及如何访问它(`Query AST`)。与 SQL/NoSQL 无关。 |
+| **UI 层** | **[ObjectUI](/docs/specifications/ui/sdui-protocol)** | 投影层。将用户界面定义为抽象的 JSON 布局(视图、仪表板、操作)。 |
| **控制层** | **[ObjectOS](/docs/specifications/server/kernel-architecture)** | 内核。处理身份、安全、同步和自动化。 |
-| **视图层** | **[ObjectUI](/docs/specifications/ui/sdui-protocol)** | 投影。将用户界面定义为抽象的 JSON 布局,实现服务器驱动 UI。 |
+| **AI 层** | **AI 协议** | AI 代理定义、工具、知识库和模型配置。 |
+| **API 层** | **API 协议** | 标准化的 REST/GraphQL 契约,带请求/响应封装。 |
-## 这是为谁准备的?
+## 适用对象
-* **平台架构师:** 想要构建可扩展的内部开发者平台(IDP)的人。
-* **协议实现者:** 想要为 ObjectQL 编写新驱动程序(例如,用于 FoundationDB)或为 ObjectUI 编写新渲染器(例如,用于 Flutter)的人。
-* **AI 代理开发者:** 需要一种确定性的、结构化的通用语言来让 AI 生成软件的人。
+* **平台架构师:** 想要构建可扩展的内部开发者平台(IDP)。
+* **协议实现者:** 想要为 ObjectQL 编写新的驱动(例如,用于 FoundationDB)或为 ObjectUI 编写新的渲染器(例如,用于 Flutter)。
+* **AI 代理开发者:** 需要一种确定性、结构化的通用语言来让 AI 生成软件。
+* **低代码构建者:** 想要一个强大的元数据驱动平台来快速应用开发。
diff --git a/content/docs/index.mdx b/content/docs/index.mdx
index b7a3ccb..39f37b1 100644
--- a/content/docs/index.mdx
+++ b/content/docs/index.mdx
@@ -17,7 +17,7 @@ This documentation is the authoritative reference for the ObjectStack Protocol.
icon={}
title="Getting Started"
href="/docs/guides/getting-started"
- description="Build your first Object in 5 minutes. Learn the basics of the SDK."
+ description="Build your first Object in 5 minutes. Learn the basics with practical examples."
/>
}
@@ -39,18 +39,33 @@ This documentation is the authoritative reference for the ObjectStack Protocol.
/>
+## Quick Links
+
+### Essential Guides
+- **[Field Types](/docs/guides/field-types)** - 30+ field types with examples (text, number, select, lookup, formula, etc.)
+- **[View Configuration](/docs/guides/view-configuration)** - Grid, Kanban, Calendar, Gantt, and Form layouts
+- **[Workflows & Validation](/docs/guides/workflows-validation)** - Business rules and automation
+- **[Project Structure](/docs/guides/project-structure)** - Best practices for organizing your code
+
+### Examples
+- **[CRM Example](/examples/crm)** - Full-featured application with 6 objects, workflows, views, dashboards
+- **[Todo Example](/examples/todo)** - Quick-start minimal example
+
## The "Trinity" Architecture
-ObjectStack is built on three pillars that work in unison:
+ObjectStack is built on five core modules that work in unison:
-| Pillar | Protocol | Responsibility |
+| Module | Protocol | Responsibility |
| :--- | :--- | :--- |
-| **Data Layer** | **[ObjectQL](/docs/specifications/data/architecture)** | Defines the shape of data (`Object`) and how to access it (`AST`). Agnostic to SQL/NoSQL. |
+| **Data Layer** | **[ObjectQL](/docs/specifications/data/architecture)** | Defines the shape of data (`Object`, `Field`) and how to access it (`Query AST`). Agnostic to SQL/NoSQL. |
+| **UI Layer** | **[ObjectUI](/docs/specifications/ui/sdui-protocol)** | The Projection. Defines User Interfaces as abstract JSON layouts (Views, Dashboards, Actions). |
| **Control Layer** | **[ObjectOS](/docs/specifications/server/kernel-architecture)** | The Kernel. Handles Identity, Security, Sync, and Automation. |
-| **View Layer** | **[ObjectUI](/docs/specifications/ui/sdui-protocol)** | The Projection. Defines the User Interface as abstract JSON layouts, enabling Server-Driven UI. |
+| **AI Layer** | **AI Protocol** | AI agent definitions, tools, knowledge bases, and model configurations. |
+| **API Layer** | **API Protocol** | Standardized REST/GraphQL contracts with request/response envelopes. |
## For whom is this?
* **Platform Architects:** Who want to build internal developer platforms (IDP) that scale.
* **Protocol Implementers:** Who want to write a new Driver for ObjectQL (e.g., for FoundationDB) or a new Renderer for ObjectUI (e.g., for Flutter).
* **AI Agent Developers:** Who need a deterministic, structured generic language for AI to generate software.
+* **Low-Code Builders:** Who want a powerful metadata-driven platform for rapid application development.
diff --git a/examples/todo/README.md b/examples/todo/README.md
index 0e13bac..ad11a6f 100644
--- a/examples/todo/README.md
+++ b/examples/todo/README.md
@@ -1,16 +1,77 @@
-# ObjectStack CRM Example
+# ObjectStack Todo Example
-This is a reference implementation of a simple CRM schema using the ObjectStack Protocol.
+A minimal example demonstrating the ObjectStack Protocol with a simple Task management application.
-## Structure
+## 🎯 Purpose
-* `src/domains/crm/` - Contains the Object definitions (`Account`, `Contact`, `Opportunity`).
-* `objectstack.config.ts` - The application manifest that bundles the objects into an app.
+This example serves as a **quick-start reference** for learning ObjectStack basics. It demonstrates:
+- Simple object definition with essential field types
+- Basic configuration using `objectstack.config.ts`
+- Minimal setup to get started quickly
-## Usage
+For a **comprehensive example** with advanced features (workflows, validations, multiple views, dashboards), see the **[CRM Example](../crm/)**.
-This package is part of the `examples` workspace. To build it and verify types:
+## 📂 Structure
+
+```
+examples/todo/
+├── src/
+│ ├── domains/
+│ │ └── todo/
+│ │ └── task.object.ts # Task object definition
+│ └── client-test.ts # Client SDK usage example
+├── objectstack.config.ts # Application manifest
+└── README.md # This file
+```
+
+## 📋 Features Demonstrated
+
+### Object Definition
+- **Task Object** (`todo_task`) with essential and advanced field types
+
+### Field Types Covered
+- ✅ **Text** (`subject`) - Task title (required field)
+- ✅ **Date** (`due_date`) - Due date tracking
+- ✅ **Boolean** (`is_completed`) - Completion status with default value
+- ✅ **Rating** (`priority`) - 3-star priority rating system
+- ✅ **Color** (`category_color`) - Color picker with HEX format and preset colors
+- ✅ **Code** (`code_snippet`) - JavaScript code editor with line numbers
+- ✅ **Rich Text** (`notes`) - Formatted text with full editor capabilities
+
+### Configuration Features
+- Object capabilities: `apiEnabled`, `trackHistory`
+- Custom icon (`check-square`)
+- Name field configuration
+- Commented action example showing future extensibility
+
+## 💡 Usage
+
+This package is part of the `examples` workspace. To build and verify:
```bash
-pnpm build
+# Install dependencies (from monorepo root)
+pnpm install
+
+# Build the example
+pnpm --filter @objectstack/example-todo build
+
+# Run type checking
+pnpm --filter @objectstack/example-todo typecheck
```
+
+## 📖 Learning Path
+
+1. **Start Here** - Simple task object, basic configuration
+2. **Next Step** - [CRM Example](../crm/) - Advanced features, workflows, validations, UI components
+3. **Then** - [Official Documentation](../../content/docs/) - Complete protocol reference
+
+## 🔗 Related Resources
+
+- [Getting Started Guide](../../content/docs/guides/getting-started.mdx)
+- [Object Schema Reference](../../packages/spec/src/data/object.zod.ts)
+- [Field Types Reference](../../packages/spec/src/data/field.zod.ts)
+- [CRM Example](../crm/README.md) - Full-featured reference implementation
+
+## 📝 License
+
+MIT