Skip to content

Commit 9725173

Browse files
committed
Revise AI, data modeling, actions, and hooks guides
Updated documentation for AI integration, data modeling, custom actions, and lifecycle hooks in ObjectQL. Improvements include clearer examples, streamlined explanations, and enhanced guidance on schema, relationships, validation, and business logic implementation.
1 parent 6c52f2f commit 9725173

4 files changed

Lines changed: 239 additions & 488 deletions

File tree

docs/guide/ai.md

Lines changed: 54 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,84 @@
11
# Building AI-Native Apps
22

3-
ObjectQL is designed from the ground up to be the ideal data layer for AI agents and LLM-powered applications. Unlike traditional ORMs that rely on string-based SQL generation (prone to hallucination and injection), ObjectQL uses a **strict JSON Protocol**.
3+
ObjectQL is engineered to be the ideal data layer for AI Agents and LLMs. By providing a **Structure-First** protocol (JSON AST) instead of raw strings (SQL), it drastically reduces hallucinations and injection risks.
44

5-
## Why ObjectQL for AI?
5+
## 1. Why ObjectQL for AI?
66

7-
| Feature | SQL / Traditional ORM | ObjectQL (JSON AST) |
7+
| Feature | SQL / Traditional ORM | ObjectQL |
88
| :--- | :--- | :--- |
9-
| **Output Format** | Unstructured Strings | **Structured JSON** |
10-
| **Hallucinations** | High (Syntax errors, non-existent tables) | **Low** (constrained by schema) |
11-
| **Safety** | Injection vulnerable (requires sanitization) | **Injection Proof** (by design) |
12-
| **Context Window** | Heavy (DDL dumps) | **Lightweight** (JSON Schema) |
9+
| **Output** | Unstructured String | **Strict JSON** |
10+
| **Safety** | Injection Vulnerable | **Injection Safe** |
11+
| **Context** | Heavy DDL dumps | **Lightweight Scoped Schema** |
1312

14-
### The "JSON Advantage"
13+
LLMs excel at generating JSON. ObjectQL lets the LLM speak its native language.
1514

16-
LLMs are exceptionally good at generating JSON. By asking the LLM to output a JSON object instead of a SQL query, you drastically reduce error rates.
15+
## 2. Semantic Search (RAG)
1716

18-
**User Prompt:** "Find high priority tasks for John."
17+
ObjectQL has first-class support for Vector Search. You don't need a separate vector database (like Pinecone) or generic ORM hacks.
1918

20-
**LLM Output (ObjectQL Query):**
21-
```json
22-
{
23-
"entity": "tasks",
24-
"filters": [
25-
["priority", "=", "High"],
26-
"and",
27-
["assignee", "=", "John"]
28-
]
29-
}
30-
```
31-
32-
## Quick Start
19+
### Configuration
3320

34-
### 1. Install Dependencies
21+
Enable search in your `*.object.yml`.
3522

36-
You'll need the core package. We assume you are using OpenAI or a similar provider.
23+
```yaml
24+
# knowledge.object.yml
25+
name: knowledge
26+
fields:
27+
title: { type: text }
28+
content: { type: textarea }
3729

38-
```bash
39-
npm install @objectql/core openai
30+
# Enable AI capabilities
31+
ai:
32+
search:
33+
enabled: true
34+
fields: [title, content] # Fields to embed
35+
model: text-embedding-3-small
4036
```
4137
42-
### 2. The Pattern: RAG for Schema
38+
### Usage
4339
44-
To let the AI generate correct queries, you must first provide it with the relevant *Context* (your Schema), but only the parts it needs.
40+
When enabled, the driver manages the embeddings automatically. You can then search using natural language.
4541
4642
```typescript
47-
// 1. Get Schema Context (Simplified)
48-
const schemaContext = {
49-
entities: {
50-
todo: {
51-
description: "Task items",
52-
fields: ["title", "status", "priority"]
53-
}
54-
}
55-
};
56-
57-
// 2. Prompt the AI
58-
const prompt = `
59-
You are a database assistant.
60-
Context: ${JSON.stringify(schemaContext)}
61-
62-
User Request: "Show me all high priority tasks."
63-
64-
Output: strictly valid ObjectQL JSON.
65-
`;
66-
67-
// 3. Call LLM (Pseudo-code)
68-
const response = await openai.chat.completions.create({
69-
messages: [{ role: "user", content: prompt }]
70-
});
71-
const query = JSON.parse(response.choices[0].message.content);
72-
```
73-
74-
## AI Patterns
43+
// Search for "How to reset password"
44+
const results = await objectql.search('knowledge', 'How to reset password');
7545

76-
### Pattern A: Natural Language Search (NL2Q)
77-
Directly converting user questions into database queries.
46+
// returns: [{ id: 1, title: 'Reset Config', _score: 0.89 }, ...]
47+
```
7848
79-
* **Best for:** Reporting, Dashboards, Search bars.
80-
* **Tip:** Use the `description` field in your ObjectQL definitions to give the AI hints about what an object represents.
49+
## 3. Explicit Vector Columns
8150
82-
### Pattern B: Intelligent Form Generation
83-
Since ObjectQL schemas are just JSON, AI can easily generate new object definitions on the fly.
51+
For advanced use cases (e.g., Image Search or Multi-modal embeddings), you can define raw vector columns.
8452
85-
```typescript
86-
// AI Output for "Create a Customer schema"
87-
const newSchema = {
88-
name: "customer",
89-
fields: {
90-
name: { type: "text" },
91-
email: { type: "email" },
92-
status: { type: "select", options: ["active", "lead"] }
93-
}
94-
};
95-
96-
// Apply it immediately
97-
await app.metadata.registerObject(newSchema);
53+
```yaml
54+
fields:
55+
image_url:
56+
type: url
57+
58+
clip_embedding:
59+
type: vector
60+
dimension: 512
61+
index: true # Create IVFFlat/HNSW index
9862
```
9963
100-
## Safety Guidelines (Critical)
101-
102-
Allowing an AI to generate database queries introduces risks. You must follow these principles:
64+
## 4. LLM to Query (Text-to-SQL alternative)
10365
104-
### 1. Never Trust AI Output
105-
Always validate the structure and content of the generated JSON *before* execution.
106-
107-
```typescript
108-
import { z } from 'zod';
66+
Instead of asking an LLM to write SQL, ask it to write ObjectQL JSON.
10967
110-
// Define a safe schema for the query
111-
const QuerySchema = z.object({
112-
entity: z.string(),
113-
filters: z.array(z.any()).optional()
114-
});
68+
**Prompt Pattern:**
11569
116-
const rawQuery = JSON.parse(aiOutput);
70+
```text
71+
You are a data assistant.
72+
Schema:
73+
- Object: Task (fields: title, status, priority)
11774

118-
// 1. Structural Validation
119-
const safeQuery = QuerySchema.parse(rawQuery);
75+
User: "Find my high priority tasks"
12076

121-
// 2. Permission Check (Kernel Level)
122-
// Even if the query is valid, ObjectQL's internal security layer
123-
// will still enforce RLS (Row Level Security).
124-
const result = await db.find(safeQuery);
77+
Output JSON in ObjectQL format:
78+
{
79+
"entity": "task",
80+
"filters": [["priority", "=", "High"]]
81+
}
12582
```
12683

127-
### 2. Least Privilege
128-
The database user used by the AI agent should have **read-only** permissions where possible, or be scoped strictly to the objects it needs to modify.
129-
130-
### 3. Complexity Limits
131-
AI models can sometimes generate deeply nested or inefficient queries. Implement a "Complexity Cost" check before executing:
132-
- Limit the number of joins (lookups).
133-
- Limit the result set size.
84+
This output can be safely executed by the ObjectQL engine without fear of `DROP TABLE` injections.

docs/guide/data-modeling.md

Lines changed: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,99 @@
11
# Data Modeling Guide
22

3-
Modeling your business data is the first step in building an ObjectQL application. This guide introduces the core concepts.
3+
Data modeling in ObjectQL is **Metadata-First**. You define your application's schema using `*.object.yml` files (or JSON), and ObjectQL handles validation, database mapping, and type generation.
44

5-
## 1. Objects
5+
## 1. The Object Definition
66

7-
An **Object** is like a database table. It represents a business entity, such as a Customer, Order, or Product.
7+
Each file represents one business entity. By convention, name the file `[object_name].object.yml`.
88

99
```yaml
10-
# customer.object.yml
11-
name: customer
12-
label: Customer
13-
icon: user
14-
description: Stores customer information.
10+
# objects/product.object.yml
11+
name: product
12+
label: Product
13+
description: "Catalog items for sale"
14+
icon: standard:product
15+
1516
fields:
1617
name:
1718
type: text
18-
label: Full Name
1919
required: true
20+
label: Product Name
21+
22+
price:
23+
type: currency
24+
scale: 2
25+
label: Price
26+
27+
category:
28+
type: select
29+
options:
30+
- electronics
31+
- furniture
32+
- clothing
2033
```
2134
22-
## 2. Fields
35+
## 2. Fields & Relationships
2336
24-
Fields store the data attributes for an object. ObjectQL provides a rich set of field types.
37+
ObjectQL supports rich field types that automate UI rendering and validation.
2538
26-
### 2.1 Basic Types
27-
* **Text & Area**: `text`, `textarea`, `markdown`, `html`
39+
### Core Types
40+
* **Text**: `text`, `textarea`, `markdown`, `html`
2841
* **Numbers**: `number`, `currency`, `percent`
29-
* **Switch**: `boolean` (checkbox)
30-
* **Date**: `date`, `datetime`, `time`
31-
* **System**: `password`, `auto_number`
32-
33-
### 2.2 Format Types
34-
These types provide automatic validation and formatted display.
35-
* **Email** (`email`): Validates email addresses.
36-
* **Phone** (`phone`): Stores phone numbers.
37-
* **URL** (`url`): Validates web links.
42+
* **Flags**: `boolean`
43+
* **Media**: `image`, `file`, `avatar`
3844

39-
### 2.3 Media & Files
40-
* **File** (`file`): Upload generic documents.
41-
* **Image** (`image`): Upload pictures with preview support.
42-
* **Avatar** (`avatar`): User profile pictures.
45+
### Relationships
46+
* **Lookup**: A loose foreign key. Can be optional.
47+
```yaml
48+
created_by: { type: lookup, reference_to: user }
49+
```
50+
* **Master-Detail**: A strong parent-child bond. Deleting the parent cascades to the child.
51+
```yaml
52+
order_id: { type: master_detail, reference_to: order }
53+
```
4354

44-
*Note: You can allow multiple files/images by setting `multiple: true`.*
55+
### Specialized Types
56+
* **Vector**: Stores embeddings (arrays of floats) for AI search.
57+
```yaml
58+
embedding: { type: vector, dimension: 1536, index: true }
59+
```
4560

46-
### 2.4 Location
47-
* **Location** (`location`): Stores Latitude and Longitude. Useful for maps.
61+
## 3. Indexes & Constraints
4862

49-
### 2.5 Calculations
50-
* **Formula**: Calculate values automatically based on other fields.
51-
* Example: `Total` = `Price` * `Quantity`
52-
* **Summary**: Aggregate data from child records (e.g., Total Order Amount for a Customer).
63+
Optimize query performance and ensure data integrity.
5364

54-
## 3. Relationships
65+
### Field-Level Shortcuts
66+
Use these for simple, single-column definitions.
5567

56-
Linking objects together is powerful.
68+
```yaml
69+
fields:
70+
sku:
71+
type: text
72+
unique: true # Enforce uniqueness
73+
74+
status:
75+
type: select
76+
index: true # Speed up filters
77+
```
5778

58-
* **Lookup**: A simple link to another object. (e.g., An Order looks up a Customer).
59-
* **Master-Detail**: A strong parent-child relationship. If the parent is deleted, children are deleted.
79+
### Composite Indexes
80+
Define these at the root of your object file for multi-column optimizations (e.g., sorting by Date within a Category).
6081

6182
```yaml
62-
# order.object.yml
63-
fields:
64-
customer:
65-
type: lookup
66-
reference_to: customer
67-
label: Customer
83+
indexes:
84+
category_date_idx:
85+
fields: [category, created_at]
86+
87+
unique_product_variant:
88+
fields: [product_id, color, size]
89+
unique: true
6890
```
6991

70-
## 4. Attributes
92+
## 4. Internationalization (i18n)
7193

72-
You can enforce rules on your data using attributes:
94+
ObjectQL adopts a "clean schema, external translation" philosophy.
7395

74-
* `required`: Cannot be empty.
75-
* `unique`: Must be unique in the whole table.
76-
* `min`, `max`: Range validation for numbers.
77-
* `defaultValue`: Automatic initial value.
78-
* `hidden`: Hide from standard UI.
79-
* `readonly`: Prevent editing in UI.
96+
* **Schema**: Keep `*.object.yml` clean and technical (usually English keys/labels).
97+
* **Metadata Translations**: Store UI labels in `i18n/[lang]/[object].json`.
98+
* **Data Translations**: If you need to translate record content (like a Product Name), we recommend modeling it explicitly (e.g., a `ProductTranslation` table) rather than complicating the core column types.
8099

0 commit comments

Comments
 (0)