Skip to content

Commit 64c90be

Browse files
authored
Merge pull request #28 from objectql/copilot/update-formula-rules-documentation
2 parents a1d776e + 8333e1a commit 64c90be

4 files changed

Lines changed: 980 additions & 3 deletions

File tree

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,19 @@ const resultsSql = await app.datasource('runtime').find(query);
135135

136136
Both queries return the same results, but the underlying native query is optimized for MongoDB or PostgreSQL.
137137

138-
### 3. Validation
138+
### 3. Formulas & Validation
139139

140-
Define validation rules declaratively in your object metadata:
140+
ObjectQL supports powerful formulas and validation rules. Define calculated fields and business rules declaratively:
141141

142142
```typescript
143143
import { ObjectConfig, Validator } from '@objectql/core';
144144
import { ValidationContext } from '@objectql/types';
145145

146-
// Define object with validation rules
146+
// Define object with formulas and validation rules
147147
const projectObject: ObjectConfig = {
148148
name: 'project',
149149
fields: {
150+
// Regular field
150151
name: {
151152
type: 'text',
152153
required: true,
@@ -156,6 +157,12 @@ const projectObject: ObjectConfig = {
156157
pattern: '^[a-zA-Z0-9\\s]+$'
157158
}
158159
},
160+
// Calculated field (formula)
161+
profit: {
162+
type: 'formula',
163+
expression: 'revenue - cost',
164+
data_type: 'currency'
165+
},
159166
email: {
160167
type: 'email',
161168
validation: {
@@ -224,9 +231,12 @@ if (!result.valid) {
224231
- **Field-level**: required, email, URL, min/max, length, pattern
225232
- **Cross-field**: compare fields with operators (=, !=, >, >=, <, <=, in, contains, etc.)
226233
- **State machine**: enforce valid state transitions
234+
- **Formulas**: JavaScript-style expressions for calculated fields
227235
- **Severity levels**: error, warning, info
228236
- **I18n**: multi-language error messages with fallback
229237

238+
**Learn more:** [Formulas & Rules Syntax Guide](./docs/guide/formulas-and-rules.md)
239+
230240
## 🎨 Web Console
231241

232242
ObjectQL includes a beautiful web-based admin console for database management.

docs/.vitepress/config.mts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export default defineConfig({
8484
items: [
8585
{ text: 'Data Modeling', link: '/guide/data-modeling' },
8686
{ text: 'Querying Data', link: '/guide/querying' },
87+
{ text: 'Formulas & Rules Syntax', link: '/guide/formulas-and-rules' },
88+
{ text: '↳ Quick Reference', link: '/guide/formulas-and-rules-quick-ref' },
8789
{ text: 'Business Logic (Hooks)', link: '/guide/logic-hooks' },
8890
{ text: 'Custom Actions (RPC)', link: '/guide/logic-actions' },
8991
]
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# Formulas & Rules Quick Reference
2+
3+
**Quick syntax reference for ObjectQL formulas and validation rules.**
4+
5+
For complete documentation, see:
6+
- 📖 [English Guide](./formulas-and-rules.md)
7+
8+
## Formula Syntax Quick Reference
9+
10+
### Basic Formula
11+
12+
```yaml
13+
calculated_field:
14+
type: formula
15+
expression: "field1 + field2"
16+
data_type: number
17+
```
18+
19+
### Common Patterns
20+
21+
```yaml
22+
# Arithmetic
23+
profit:
24+
type: formula
25+
expression: "revenue - cost"
26+
data_type: currency
27+
28+
# String concatenation
29+
full_name:
30+
type: formula
31+
expression: "first_name + ' ' + last_name"
32+
data_type: text
33+
34+
# Conditional
35+
status_label:
36+
type: formula
37+
expression: "score > 80 ? 'High' : 'Low'"
38+
data_type: text
39+
40+
# Date math
41+
days_old:
42+
type: formula
43+
expression: "$today - created_date"
44+
data_type: number
45+
46+
# Lookup reference
47+
owner_email:
48+
type: formula
49+
expression: "project.owner.email"
50+
data_type: text
51+
```
52+
53+
### Special Variables
54+
55+
| Variable | Example |
56+
|----------|---------|
57+
| `$today` | Current date |
58+
| `$now` | Current timestamp |
59+
| `$current_user.id` | Current user ID |
60+
| `$current_user.name` | Current user name |
61+
62+
## Validation Rules Quick Reference
63+
64+
### Field Validation
65+
66+
```yaml
67+
# In object.yml
68+
fields:
69+
email:
70+
type: email
71+
required: true
72+
validation:
73+
format: email
74+
message: "Please enter a valid email"
75+
76+
age:
77+
type: number
78+
validation:
79+
min: 0
80+
max: 150
81+
```
82+
83+
### Cross-Field Validation
84+
85+
```yaml
86+
# In project.validation.yml
87+
rules:
88+
- name: valid_date_range
89+
type: cross_field
90+
rule:
91+
field: end_date
92+
operator: ">="
93+
compare_to: start_date
94+
message: "End date must be after start date"
95+
```
96+
97+
### Conditional Validation
98+
99+
```yaml
100+
rules:
101+
- name: description_required_for_high_budget
102+
type: conditional
103+
condition:
104+
field: budget
105+
operator: ">"
106+
value: 10000
107+
rule:
108+
field: description
109+
operator: "not_empty"
110+
message: "Description required for budgets over $10,000"
111+
```
112+
113+
### State Machine
114+
115+
```yaml
116+
rules:
117+
- name: status_transition
118+
type: state_machine
119+
field: status
120+
transitions:
121+
draft:
122+
allowed_next: [submitted, cancelled]
123+
submitted:
124+
allowed_next: [approved, rejected]
125+
approved:
126+
allowed_next: []
127+
is_terminal: true
128+
```
129+
130+
## Operators Quick Reference
131+
132+
### Comparison
133+
134+
| Operator | Example |
135+
|----------|---------|
136+
| `=` | `field: status, operator: "=", value: "active"` |
137+
| `!=` | `field: status, operator: "!=", value: null` |
138+
| `>` | `field: amount, operator: ">", value: 1000` |
139+
| `>=` | `field: end_date, operator: ">=", compare_to: start_date` |
140+
| `<` | `field: age, operator: "<", value: 18` |
141+
| `<=` | `field: discount, operator: "<=", value: 1` |
142+
| `in` | `field: status, operator: "in", value: ["active", "pending"]` |
143+
| `not_in` | `field: status, operator: "not_in", value: ["deleted"]` |
144+
| `contains` | `field: tags, operator: "contains", value: "urgent"` |
145+
| `not_empty` | `field: description, operator: "not_empty"` |
146+
147+
### Logical
148+
149+
```yaml
150+
# AND - all must be true
151+
condition:
152+
all_of:
153+
- field: status
154+
operator: "="
155+
value: active
156+
- field: amount
157+
operator: ">"
158+
value: 1000
159+
160+
# OR - any must be true
161+
condition:
162+
any_of:
163+
- field: priority
164+
operator: "="
165+
value: high
166+
- field: amount
167+
operator: ">"
168+
value: 10000
169+
170+
# NOT - must be false
171+
condition:
172+
none_of:
173+
- field: status
174+
operator: "="
175+
value: deleted
176+
```
177+
178+
## Permission Rules Quick Reference
179+
180+
```yaml
181+
# In project.permission.yml
182+
rules:
183+
- name: owner_full_access
184+
condition:
185+
field: owner_id
186+
operator: "="
187+
value: $current_user.id
188+
permissions:
189+
read: true
190+
create: true
191+
update: true
192+
delete: true
193+
```
194+
195+
## Common Use Cases
196+
197+
### Budget Validation
198+
199+
```yaml
200+
rules:
201+
- name: budget_approval_required
202+
type: conditional
203+
condition:
204+
field: budget
205+
operator: ">"
206+
value: 50000
207+
rule:
208+
field: approved_by
209+
operator: "not_empty"
210+
message: "Budget over $50K requires approval"
211+
```
212+
213+
### Date Range Validation
214+
215+
```yaml
216+
rules:
217+
- name: valid_date_range
218+
type: cross_field
219+
rule:
220+
field: end_date
221+
operator: ">="
222+
compare_to: start_date
223+
message: "End date must be after start date"
224+
```
225+
226+
### Status Workflow
227+
228+
```yaml
229+
rules:
230+
- name: order_workflow
231+
type: state_machine
232+
field: status
233+
transitions:
234+
draft:
235+
allowed_next: [submitted, cancelled]
236+
submitted:
237+
allowed_next: [approved, rejected]
238+
approved:
239+
allowed_next: [processing, cancelled]
240+
processing:
241+
allowed_next: [shipped, cancelled]
242+
shipped:
243+
allowed_next: [delivered]
244+
delivered:
245+
allowed_next: [] # terminal
246+
```
247+
248+
### Calculated Metrics
249+
250+
```yaml
251+
# Profit margin
252+
profit_margin:
253+
type: formula
254+
expression: "(revenue - cost) / revenue * 100"
255+
data_type: percent
256+
257+
# Days since creation
258+
age_days:
259+
type: formula
260+
expression: "$today - created_date"
261+
data_type: number
262+
263+
# Full address
264+
full_address:
265+
type: formula
266+
expression: "street + ', ' + city + ', ' + state + ' ' + zip"
267+
data_type: text
268+
```
269+
270+
## Related Docs
271+
272+
- 📖 [Complete Formulas & Rules Guide](./formulas-and-rules.md)
273+
- 📖 [Object Definitions](../spec/object.md)
274+
- 📖 [Validation Spec](../spec/validation.md)
275+
- 📖 [Permission Spec](../spec/permission.md)

0 commit comments

Comments
 (0)