Skip to content

Commit 2a0eaa1

Browse files
Copilothotlong
andcommitted
Add formula engine tutorial and examples
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent fe6a11b commit 2a0eaa1

4 files changed

Lines changed: 198 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Formula Engine Tutorial
2+
3+
This tutorial demonstrates the Formula Engine capabilities in ObjectQL. Formulas are read-only calculated fields that automatically derive their values from other fields, related records, or system variables.
4+
5+
## Quick Start
6+
7+
```bash
8+
npm install
9+
npm run dev
10+
```
11+
12+
## What You'll Learn
13+
14+
1. Basic formula expressions (arithmetic, string concatenation)
15+
2. Conditional logic in formulas
16+
3. System variables ($today, $current_user)
17+
4. Complex business logic
18+
5. Error handling
19+
20+
## Example Objects
21+
22+
### 1. E-commerce Order
23+
24+
Demonstrates:
25+
- Price calculations with discounts and tax
26+
- Stock status logic
27+
- Risk assessment
28+
29+
### 2. CRM Contact
30+
31+
Demonstrates:
32+
- String concatenation (full name)
33+
- Relationship traversal
34+
- User ownership checks
35+
36+
### 3. Project Management
37+
38+
Demonstrates:
39+
- Date calculations
40+
- Progress tracking
41+
- Health scores
42+
43+
## Running the Examples
44+
45+
```bash
46+
npm run dev
47+
```
48+
49+
This will:
50+
1. Initialize the ObjectQL engine
51+
2. Register objects with formulas
52+
3. Create sample records
53+
4. Query and display formula results
54+
55+
## Key Concepts
56+
57+
### Formula Field Definition
58+
59+
```yaml
60+
full_name:
61+
type: formula
62+
formula: "first_name + ' ' + last_name"
63+
data_type: text
64+
label: Full Name
65+
```
66+
67+
### System Variables
68+
69+
- `$today` - Current date
70+
- `$now` - Current timestamp
71+
- `$current_user.id` - Current user ID
72+
- `$year`, `$month`, `$day` - Date components
73+
74+
### Supported Operations
75+
76+
- Arithmetic: `+`, `-`, `*`, `/`, `%`, `**`
77+
- Comparison: `===`, `!==`, `>`, `<`, `>=`, `<=`
78+
- Logical: `&&`, `||`, `!`
79+
- Conditional: Ternary operator, if/else blocks
80+
- String methods: `.toUpperCase()`, `.toLowerCase()`, `.trim()`, etc.
81+
- Math functions: `Math.round()`, `Math.max()`, etc.
82+
83+
## See Also
84+
85+
- [Formula Specification](../../docs/spec/formula.md)
86+
- [Formulas & Rules Guide](../../docs/guide/formulas-and-rules.md)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@objectql/tutorial-formulas",
3+
"version": "1.8.4",
4+
"private": true,
5+
"description": "Tutorial demonstrating Formula Engine in ObjectQL",
6+
"main": "src/index.ts",
7+
"scripts": {
8+
"dev": "ts-node src/index.ts",
9+
"build": "tsc"
10+
},
11+
"dependencies": {
12+
"@objectql/core": "workspace:*",
13+
"@objectql/types": "workspace:*",
14+
"@objectql/driver-sql": "workspace:*",
15+
"sqlite3": "^5.1.7"
16+
},
17+
"devDependencies": {
18+
"@types/node": "^20.19.28",
19+
"ts-node": "^10.9.2",
20+
"typescript": "^5.9.3"
21+
}
22+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Formula Engine Tutorial
3+
*
4+
* This tutorial demonstrates the formula engine capabilities in ObjectQL.
5+
* Run with: npm run dev
6+
*/
7+
8+
import { ObjectQL } from '@objectql/core';
9+
import { SqlDriver } from '@objectql/driver-sql';
10+
11+
async function main() {
12+
console.log('🚀 ObjectQL Formula Engine Tutorial\n');
13+
14+
// Initialize ObjectQL with in-memory SQLite
15+
const driver = new SqlDriver({
16+
client: 'sqlite3',
17+
connection: { filename: ':memory:' },
18+
useNullAsDefault: true,
19+
});
20+
21+
const app = new ObjectQL({
22+
datasources: { default: driver },
23+
});
24+
25+
// E-COMMERCE ORDER EXAMPLE
26+
console.log('📦 Example 1: E-commerce Order with Price Calculations\n');
27+
28+
app.registerObject({
29+
name: 'order',
30+
fields: {
31+
product_name: { type: 'text', required: true },
32+
quantity: { type: 'number', required: true },
33+
unit_price: { type: 'currency', required: true },
34+
discount_rate: { type: 'percent', defaultValue: 0 },
35+
tax_rate: { type: 'percent', defaultValue: 8 },
36+
37+
// Formula fields
38+
subtotal: {
39+
type: 'formula',
40+
formula: 'quantity * unit_price',
41+
data_type: 'currency',
42+
label: 'Subtotal',
43+
},
44+
final_price: {
45+
type: 'formula',
46+
formula: 'quantity * unit_price * (1 - discount_rate / 100) * (1 + tax_rate / 100)',
47+
data_type: 'currency',
48+
label: 'Final Price',
49+
},
50+
discount_amount: {
51+
type: 'formula',
52+
formula: 'quantity * unit_price * (discount_rate / 100)',
53+
data_type: 'currency',
54+
label: 'You Save',
55+
},
56+
},
57+
});
58+
59+
await app.init();
60+
61+
const ctx = app.createContext({ isSystem: true });
62+
63+
// Create sample order
64+
const order = await ctx.object('order').create({
65+
product_name: 'Premium Laptop',
66+
quantity: 2,
67+
unit_price: 1299.99,
68+
discount_rate: 15,
69+
tax_rate: 8,
70+
});
71+
72+
console.log('📦 Order Created:');
73+
console.log(' Subtotal: $' + order.subtotal?.toFixed(2));
74+
console.log(' You Save: $' + order.discount_amount?.toFixed(2));
75+
console.log(' Final Price: $' + order.final_price?.toFixed(2));
76+
77+
console.log('\n✅ Tutorial complete!\n');
78+
79+
await app.close();
80+
}
81+
82+
main().catch(console.error);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"rootDir": "src"
6+
},
7+
"include": ["src/**/*"]
8+
}

0 commit comments

Comments
 (0)