data-primals-engine 1.6.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -900
- package/client/index.js +3 -0
- package/client/package-lock.json +7563 -8811
- package/client/package.json +11 -1
- package/client/src/App.scss +29 -0
- package/client/src/AssistantChat.jsx +369 -362
- package/client/src/DataEditor.jsx +383 -383
- package/client/src/DataLayout.jsx +54 -20
- package/client/src/ModelList.jsx +280 -280
- package/client/src/ViewSwitcher.scss +0 -31
- package/client/src/_variables.scss +3 -0
- package/client/src/constants.js +81 -100
- package/client/src/contexts/CommandContext.jsx +274 -259
- package/client/vite.config.js +30 -30
- package/doc/AI-assistance.md +93 -0
- package/doc/Advanced-workflows.md +90 -0
- package/doc/Event-system.md +79 -0
- package/doc/Packs-gallery.md +73 -0
- package/doc/automation-workflows.md +102 -0
- package/doc/core-concepts.md +33 -0
- package/doc/custom-api-endpoints.md +40 -0
- package/doc/dashboards-kpis-charts.md +49 -0
- package/doc/data-management.md +120 -0
- package/doc/data-models.md +75 -0
- package/doc/index.md +14 -0
- package/doc/roles-permissions.md +43 -0
- package/doc/users.md +30 -0
- package/package.json +20 -10
- package/src/client.js +6 -4
- package/src/constants.js +1 -1
- package/src/core.js +31 -12
- package/src/defaultModels.js +1 -1
- package/src/engine.js +342 -335
- package/src/filter.js +72 -173
- package/src/migrate.js +1 -1
- package/src/modules/assistant/assistant.js +30 -20
- package/src/modules/data/data.backup.js +4 -4
- package/src/modules/data/data.js +8 -7
- package/src/modules/data/data.operations.js +186 -133
- package/src/modules/data/data.relations.js +3 -2
- package/src/modules/data/data.scheduling.js +1 -1
- package/src/modules/mongodb.js +17 -8
- package/src/modules/swagger.js +25 -5
- package/src/modules/user.js +108 -79
- package/src/modules/workflow.js +138 -3
- package/src/packs.js +5697 -5697
- package/src/profiles.js +19 -0
- package/swagger-en.yml +3391 -1550
- package/swagger-fr.yml +3385 -2896
- package/test/assistant.test.js +2 -2
- package/test/core.test.js +341 -0
- package/test/data.backup.integration.test.js +3 -1
- package/test/data.history.integration.test.js +0 -1
- package/test/data.integration.test.js +137 -2
- package/test/user.test.js +33 -29
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# AI Assistance: Leverage Artificial Intelligence
|
|
2
|
+
|
|
3
|
+
`data-primals-engine` includes a powerful, built-in AI assistant named **Prior**. This assistant is designed to understand natural language queries, allowing you to interact with your data, generate insights, and perform actions without writing complex code or API requests.
|
|
4
|
+
|
|
5
|
+
## Enabling the AI Assistant
|
|
6
|
+
|
|
7
|
+
To use the AI assistant, you must first provide API keys for one or more supported AI providers. The engine natively supports providers like **OpenAI, Google (Gemini), DeepSeek, and Anthropic**.
|
|
8
|
+
|
|
9
|
+
You can configure your keys in two ways:
|
|
10
|
+
|
|
11
|
+
1. **Environment Variables**: Set the appropriate variable in your `.env` file. This is the recommended approach for production.
|
|
12
|
+
```env
|
|
13
|
+
# Choose one or more providers
|
|
14
|
+
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
|
|
15
|
+
GOOGLE_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxx
|
|
16
|
+
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. **`env` Model**: For user-specific keys, you can store them in the `env` model within the application. The assistant will automatically look for a key belonging to the current user.
|
|
20
|
+
|
|
21
|
+
Once a key is configured, the AI assistant chat interface becomes available in the UI.
|
|
22
|
+
|
|
23
|
+
## Core Capabilities
|
|
24
|
+
|
|
25
|
+
The assistant, "Prior," can perform a wide range of actions based on your natural language commands.
|
|
26
|
+
|
|
27
|
+
### 1. Data Querying and Visualization
|
|
28
|
+
|
|
29
|
+
You can ask the assistant to find, filter, and display your data. It can present the results in various formats.
|
|
30
|
+
|
|
31
|
+
- **Simple Search**:
|
|
32
|
+
> "Show me the latest 5 orders from French customers."
|
|
33
|
+
|
|
34
|
+
- **Chart Generation**: Create charts on the fly.
|
|
35
|
+
> "Create a bar chart of user sign-ups per month for the last year."
|
|
36
|
+
|
|
37
|
+
- **Custom HTML Views**: Generate sophisticated, styled views of your data using Handlebars templates.
|
|
38
|
+
> "Build a dashboard of my active projects with their status and due dates, using a modern dark theme."
|
|
39
|
+
|
|
40
|
+
### 2. Data Modification (with Confirmation)
|
|
41
|
+
|
|
42
|
+
The assistant can create, update, or delete data, but it will **always ask for your confirmation** before executing a modifying action. This provides a critical safety layer.
|
|
43
|
+
|
|
44
|
+
- **Create Data**:
|
|
45
|
+
> "Create a new task to 'Follow up with Client X' due tomorrow."
|
|
46
|
+
|
|
47
|
+
- **Update Data**:
|
|
48
|
+
> "Update the status of all tickets in the 'Support' category to 'resolved'."
|
|
49
|
+
|
|
50
|
+
- **Delete Data**:
|
|
51
|
+
> "Delete all draft products created before last month."
|
|
52
|
+
|
|
53
|
+
When you issue such a command, the assistant will respond with a summary of the action it intends to perform and a "Confirm" button. The action is only executed after you click it.
|
|
54
|
+
|
|
55
|
+
### 3. Answering Questions
|
|
56
|
+
|
|
57
|
+
The assistant can answer questions about the data it has access to.
|
|
58
|
+
|
|
59
|
+
> "What was our total revenue in the last quarter?"
|
|
60
|
+
|
|
61
|
+
## How It Works: The Reasoning Loop
|
|
62
|
+
|
|
63
|
+
When you send a message, the assistant follows a strict reasoning process:
|
|
64
|
+
|
|
65
|
+
1. **Analyze Intent**: It first analyzes your request to understand what you want to do.
|
|
66
|
+
2. **Search Models (Internal Step)**: Its first action is always to call the `search_models` tool internally. This gives it the exact structure, field names, and types for the relevant data models. This step is crucial for preventing errors and "hallucinations."
|
|
67
|
+
3. **Formulate Action**: Based on your intent and the model structures it found, it formulates a final action, such as `search`, `generateChart`, or a `post` request.
|
|
68
|
+
4. **Execute or Confirm**:
|
|
69
|
+
- If it's a read-only action (like `search` or `generateChart`), it executes it and displays the result.
|
|
70
|
+
- If it's a write action (like `post` or `delete`), it presents the action to you for confirmation.
|
|
71
|
+
|
|
72
|
+
## AI in Workflows: The `GenerateAIContent` Action
|
|
73
|
+
|
|
74
|
+
Beyond the chat interface, you can leverage AI directly within your automation **Workflows**. The `GenerateAIContent` action allows you to call an AI model as a step in a workflow.
|
|
75
|
+
|
|
76
|
+
This is perfect for tasks like:
|
|
77
|
+
- Summarizing a new support ticket.
|
|
78
|
+
- Generating a product description when a new product is added.
|
|
79
|
+
- Classifying incoming data based on its content.
|
|
80
|
+
- Translating text.
|
|
81
|
+
|
|
82
|
+
**Example `workflowAction`:**
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"name": "Summarize Ticket",
|
|
86
|
+
"type": "GenerateAIContent",
|
|
87
|
+
"aiProvider": "OpenAI",
|
|
88
|
+
"aiModel": "gpt-4-turbo",
|
|
89
|
+
"prompt": "Summarize the following support ticket in one sentence: {triggerData.description}"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This integration of AI both as an interactive assistant and as an automation component makes `data-primals-engine` a powerful platform for building intelligent applications.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Advanced Workflows: Custom Logic with Scripts
|
|
2
|
+
|
|
3
|
+
While the standard workflow actions in `data-primals-engine` cover many common use cases, the `ExecuteScript` action provides ultimate flexibility by allowing you to run custom server-side JavaScript code as part of any workflow. This enables complex data transformations, conditional logic, and dynamic interactions that go beyond pre-defined actions.
|
|
4
|
+
|
|
5
|
+
## The `ExecuteScript` Action
|
|
6
|
+
|
|
7
|
+
The `ExecuteScript` action type within a `workflowAction` document lets you write and execute a JavaScript snippet in a secure, sandboxed environment.
|
|
8
|
+
|
|
9
|
+
### Key Features:
|
|
10
|
+
|
|
11
|
+
- **Full JavaScript Support**: Write modern JavaScript (async/await) to implement your logic.
|
|
12
|
+
- **Access to Workflow Context**: Your script can read from and write to the `contextData` object, allowing you to pass data between workflow steps.
|
|
13
|
+
- **Database Interaction**: Use a sandboxed `db` object to perform CRUD operations.
|
|
14
|
+
- **Error Handling**: Throwing an error in your script will fail the current workflow step and can trigger the `onFailureStep`.
|
|
15
|
+
|
|
16
|
+
### Action Configuration
|
|
17
|
+
|
|
18
|
+
When creating a `workflowAction` of type `ExecuteScript`, the most important field is `script`:
|
|
19
|
+
|
|
20
|
+
- **`script`** (code - JavaScript): The JavaScript code to be executed.
|
|
21
|
+
|
|
22
|
+
**Example `workflowAction` document:**
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"name": "Calculate Order Discount",
|
|
26
|
+
"type": "ExecuteScript",
|
|
27
|
+
"script": "const orderTotal = contextData.triggerData.totalAmount;\nif (orderTotal > 100) {\n contextData.discountAmount = orderTotal * 0.1;\n contextData.needsManagerApproval = false;\n} else if (orderTotal > 500) {\n contextData.discountAmount = orderTotal * 0.2;\n contextData.needsManagerApproval = true;\n}\nreturn contextData;"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## The Execution Environment
|
|
32
|
+
|
|
33
|
+
Your script runs in an `async` function and has access to several globally-injected objects:
|
|
34
|
+
|
|
35
|
+
- **`contextData`** (object): This is the heart of your workflow's state. It contains:
|
|
36
|
+
- `triggerData`: The data from the event that initiated the workflow (e.g., the newly created document in a `DataAdded` trigger).
|
|
37
|
+
- Any data added by previous steps.
|
|
38
|
+
- Your script can read from and write to `contextData`. The returned object from your script will become the new `contextData` for subsequent steps.
|
|
39
|
+
|
|
40
|
+
- **`db`** (object): A secure API to interact with the database. All methods are `async` and must be `await`-ed. They automatically respect the permissions of the user who triggered the workflow.
|
|
41
|
+
- `await db.create(modelName, dataObject)`
|
|
42
|
+
- `await db.find(modelName, filter)`
|
|
43
|
+
- `await db.findOne(modelName, filter)`
|
|
44
|
+
- `await db.update(modelName, filter, updateObject)`
|
|
45
|
+
- `await db.delete(modelName, filter)`
|
|
46
|
+
|
|
47
|
+
- **`logger`** (object): A safe logging utility to help with debugging.
|
|
48
|
+
- `logger.info(...)`
|
|
49
|
+
- `logger.warn(...)`
|
|
50
|
+
- `logger.error(...)`
|
|
51
|
+
|
|
52
|
+
- **`env`** (object): Provides access to user-defined variables stored in the `env` model.
|
|
53
|
+
- `await env.get(variableName)`
|
|
54
|
+
- `await env.getAll()`
|
|
55
|
+
|
|
56
|
+
## Example: Conditional Logic and Data Creation
|
|
57
|
+
|
|
58
|
+
Imagine a workflow triggered when a `ticket` is created. If the ticket priority is "high", we want to create a new `task` for a manager.
|
|
59
|
+
|
|
60
|
+
1. **Trigger**: `onEvent: DataAdded`, `targetModel: ticket`.
|
|
61
|
+
2. **Step 1**: "Check Priority and Create Task"
|
|
62
|
+
- **Action**: `ExecuteScript`
|
|
63
|
+
- **Script**:
|
|
64
|
+
```javascript
|
|
65
|
+
// Check if the priority is high
|
|
66
|
+
if (contextData.triggerData.priority !== 'high') {
|
|
67
|
+
logger.info('Ticket priority is not high, skipping task creation.');
|
|
68
|
+
return contextData; // Exit script
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Find the manager's user ID (assuming a 'manager' role exists)
|
|
72
|
+
const manager = await db.findOne('user', { role: { $find: { name: 'manager' } } });
|
|
73
|
+
|
|
74
|
+
if (manager) {
|
|
75
|
+
// Create a new task and assign it to the manager
|
|
76
|
+
await db.create('task', {
|
|
77
|
+
title: `High-priority ticket: ${contextData.triggerData.subject}`,
|
|
78
|
+
assignedTo: manager._id,
|
|
79
|
+
relatedTicket: contextData.triggerData._id,
|
|
80
|
+
status: 'todo'
|
|
81
|
+
});
|
|
82
|
+
logger.info(`Task created for manager ${manager.username}.`);
|
|
83
|
+
} else {
|
|
84
|
+
logger.warn('No manager found to assign the task to.');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return contextData; // Always return the context
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
By leveraging the `ExecuteScript` action, you can build sophisticated, stateful, and dynamic workflows that precisely match your application's business rules.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Event System: Extending Core Functionality
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` is built on a powerful event-driven architecture. The `Event` system allows you to hook into core operations, enabling you to extend and customize the engine's behavior without modifying its source code. This is the primary mechanism for creating custom modules and advanced middleware.
|
|
4
|
+
|
|
5
|
+
## Listening to Events
|
|
6
|
+
|
|
7
|
+
You can register a callback function that will be executed whenever a specific event is triggered. This is done using the `Event.Listen()` method.
|
|
8
|
+
|
|
9
|
+
### Syntax
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
Event.Listen(eventName, callback, scope, type);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- **`eventName`** (string): The name of the event to listen to (e.g., `"OnDataAdded"`).
|
|
16
|
+
- **`callback`** (function): The function to execute when the event fires. The arguments it receives depend on the event.
|
|
17
|
+
- **`scope`** (string): Must be `"event"`.
|
|
18
|
+
- **`type`** (string): Determines the callback signature.
|
|
19
|
+
- `"user"`: The callback receives arguments relevant to a user action (e.g., `(data)`).
|
|
20
|
+
- `"system"`: The callback receives the full `engine` instance as its first argument, followed by other arguments (e.g., `(engine, data)`).
|
|
21
|
+
|
|
22
|
+
### Example: Logging New Data
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
import { Event } from 'data-primals-engine';
|
|
26
|
+
|
|
27
|
+
Event.Listen(
|
|
28
|
+
"OnDataAdded",
|
|
29
|
+
(engine, insertedDocs) => {
|
|
30
|
+
const logger = engine.getComponent('Logger');
|
|
31
|
+
logger.info(`New documents were added:`, insertedDocs);
|
|
32
|
+
},
|
|
33
|
+
"event",
|
|
34
|
+
"system"
|
|
35
|
+
);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Triggering Custom Events
|
|
39
|
+
|
|
40
|
+
You can also define and trigger your own custom events. This is useful for making your own modules extensible.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
import { Event } from 'data-primals-engine';
|
|
44
|
+
|
|
45
|
+
async function myCustomFunction(data) {
|
|
46
|
+
// ... some logic ...
|
|
47
|
+
|
|
48
|
+
// Trigger a custom event and pass data to listeners
|
|
49
|
+
const results = await Event.Trigger("OnMyCustomEvent", "event", "user", data);
|
|
50
|
+
|
|
51
|
+
// ... do something with results from listeners ...
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
When multiple listeners are registered for an event, their return values are merged:
|
|
56
|
+
- **strings** are concatenated.
|
|
57
|
+
- **numbers** are added.
|
|
58
|
+
- **booleans** are logical AND-ed.
|
|
59
|
+
- **arrays** are concatenated.
|
|
60
|
+
- **objects** are merged (spread operator).
|
|
61
|
+
|
|
62
|
+
## Core Events Table
|
|
63
|
+
|
|
64
|
+
Here is a list of the most important events you can listen to:
|
|
65
|
+
|
|
66
|
+
| Event | Description | Scope | Triggered by | Arguments (Payload) |
|
|
67
|
+
|:-------------------|:-----------------------------------------------------------------|:-------|:-----------------------------|:-----------------------------------------------------------------------------------|
|
|
68
|
+
| `OnServerStart` | Triggered once the HTTP server is started and listening. | System | `engine.start()` | `engine` |
|
|
69
|
+
| `OnDatabaseLoaded` | Triggered once the lient is ready | System | | `engine` |
|
|
70
|
+
| `OnModelsLoaded` | Triggered after the initial models are loaded at startup. | System | `setupInitialModels()` | `engine`, `dbModels` |
|
|
71
|
+
| `OnModelEdited` | Triggered after a model definition has been modified. | System | `editModel()` | `newModel` |
|
|
72
|
+
| `OnDataAdded` | Triggered after new data has been inserted. | System | `insertData()` | `engine`, `insertedDocs` |
|
|
73
|
+
| `OnDataEdited` | Triggered after data has been edited. | System | `editData()` / `patchData()` | `engine`, `{modelName, before, after}` |
|
|
74
|
+
| `OnDataDeleted` | Triggered just after data is actually deleted. | System | `deleteData()` | `engine`, `{model, filter}` |
|
|
75
|
+
| `OnDataSearched` | Triggered after a data search. | System | `searchData()` | `engine`, `{data, count}` |
|
|
76
|
+
| `OnDataInsert` | Triggered just before data insertion. Allows modifying the data. | System | internal | `data` |
|
|
77
|
+
| `OnDataValidate` | Triggered to override validation checks. | System | internal | `value`, `field`, `data` |
|
|
78
|
+
| `OnChatAction` | Triggered when an AI assistant decides on an action. | User | `handleChatRequest` | `action`, `params`, `parsedResponse`, `command`, `llmOptions`, `user`, `reqParams` |
|
|
79
|
+
| `OnSystemPrompt` | Triggered to override the AI assistant's system prompt. | User | `handleChatRequest` | `user` |
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Packs Gallery: Discover and Install Ready-to-Use Configurations
|
|
2
|
+
|
|
3
|
+
**Packs** are pre-built configurations that allow you to quickly set up your `data-primals-engine` application with ready-to-use models, data, workflows, and more. They are designed to bootstrap common use cases like a CRM, an e-commerce backoffice, or a project management tool, saving you significant development time.
|
|
4
|
+
|
|
5
|
+
The **Pack Gallery** is the centralized place within the UI where you can discover, preview, and install these packs.
|
|
6
|
+
|
|
7
|
+
## What is a Pack?
|
|
8
|
+
|
|
9
|
+
A pack is a JSON object that can contain:
|
|
10
|
+
|
|
11
|
+
- **`models`**: A list of model definitions (schemas) to be created.
|
|
12
|
+
- **`data`**: Sample or initial data for the models in the pack. Data can be generic or language-specific.
|
|
13
|
+
- **`workflows`**: Pre-configured automation workflows, including triggers, steps, and actions.
|
|
14
|
+
- **`dashboards`** and **`kpis`**: Ready-to-use dashboards and KPIs for monitoring.
|
|
15
|
+
|
|
16
|
+
## Installing a Pack
|
|
17
|
+
|
|
18
|
+
You can install a pack in two ways: by its ID from the gallery or by providing a custom JSON structure directly.
|
|
19
|
+
|
|
20
|
+
### 1. Installing from the Gallery
|
|
21
|
+
|
|
22
|
+
Each pack in the gallery has a unique ID. You can use the `installPack` function with this ID to install it.
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
import { installPack } from 'data-primals-engine';
|
|
26
|
+
|
|
27
|
+
// Assuming 'currentUser' is your authenticated user object
|
|
28
|
+
const packId = "61d1f1a9e3f1a9e3f1a9e3f1"; // Example ID for an e-commerce pack
|
|
29
|
+
const installationSummary = await installPack(packId, currentUser, "en");
|
|
30
|
+
|
|
31
|
+
console.log(installationSummary);
|
|
32
|
+
// Returns a summary of created models, inserted data, etc.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Installing a Custom Pack
|
|
36
|
+
|
|
37
|
+
You can also define a pack on-the-fly and install it. This is useful for migrating configurations between environments or for programmatic setup.
|
|
38
|
+
|
|
39
|
+
The `installPack` function accepts an array containing the pack's JSON definition.
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
import { installPack } from 'data-primals-engine';
|
|
43
|
+
|
|
44
|
+
const myCustomPack = [
|
|
45
|
+
{
|
|
46
|
+
"name": "Simple Blog Pack",
|
|
47
|
+
"description": "A basic setup for a blog with posts and categories.",
|
|
48
|
+
"tags": ["blog", "cms"],
|
|
49
|
+
"models": [
|
|
50
|
+
{
|
|
51
|
+
"name": "post",
|
|
52
|
+
"fields": [
|
|
53
|
+
{ "name": "title", "type": "string_t", "required": true },
|
|
54
|
+
{ "name": "content", "type": "richtext_t" },
|
|
55
|
+
{ "name": "status", "type": "enum", "items": ["draft", "published"] }
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"data": {
|
|
60
|
+
"all": { // Data for all languages
|
|
61
|
+
"post": [
|
|
62
|
+
{ "title": { "key": "first_post_title", "value": "My First Post" }, "status": "draft" }
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const summary = await installPack(myCustomPack, currentUser, "en");
|
|
70
|
+
console.log(summary);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
By using packs, you can dramatically accelerate your project setup and ensure consistency across different instances of your application.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Automation with Workflows: Create Automated Processes
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` features a powerful **Workflow** system that enables you to define and automate complex business processes. Workflows are sequences of steps and actions that can be triggered by various events or on a schedule, allowing for sophisticated automation directly within your backend.
|
|
4
|
+
|
|
5
|
+
## Core Workflow Models
|
|
6
|
+
|
|
7
|
+
The workflow system is composed of several interconnected data models:
|
|
8
|
+
|
|
9
|
+
### 1. `workflow`
|
|
10
|
+
|
|
11
|
+
The `workflow` model is the top-level definition of an automated process. It outlines the overall flow and its starting point.
|
|
12
|
+
|
|
13
|
+
- **`name`** (string, required): A unique, descriptive name for the workflow (e.g., "Order Validation", "Low Stock Notification").
|
|
14
|
+
- **`description`** (richtext, optional): A detailed explanation of the workflow's purpose.
|
|
15
|
+
- **`startStep`** (relation to `workflowStep`, optional): The first step to execute when the workflow is initiated.
|
|
16
|
+
|
|
17
|
+
### 2. `workflowTrigger`
|
|
18
|
+
|
|
19
|
+
A `workflowTrigger` defines an event or schedule that initiates a workflow.
|
|
20
|
+
|
|
21
|
+
- **`workflow`** (relation to `workflow`, required): The workflow that this trigger belongs to.
|
|
22
|
+
- **`name`** (string, required, unique): A descriptive name for the trigger (e.g., "New Order Created", "Stock < 5", "Monday 9 AM Report").
|
|
23
|
+
- **`type`** (enum, required): How the workflow is initiated:
|
|
24
|
+
- `manual`: Triggered by a data event.
|
|
25
|
+
- `scheduled`: Triggered by a cron schedule.
|
|
26
|
+
- **`onEvent`** (enum, for `manual` type): The data event that triggers the workflow: `DataAdded`, `DataEdited`, `DataDeleted`, `ModelAdded`, `ModelEdited`, `ModelDeleted`.
|
|
27
|
+
- **`targetModel`** (string, for `manual` type): The name of the model targeted by the `onEvent`.
|
|
28
|
+
- **`dataFilter`** (code - JSON, optional, for `manual` type): Optional MongoDB filter conditions checked against the `triggerData` before executing the workflow.
|
|
29
|
+
- **`cronExpression`** (string, for `scheduled` type): A cron expression (e.g., `'0 9 * * 1'` for Monday 9 AM) to schedule the workflow.
|
|
30
|
+
- **`isActive`** (boolean): Whether the trigger is currently active.
|
|
31
|
+
- **`env`** (code - JSON, optional): Environment variables (JSON key/value pairs) specific to this trigger.
|
|
32
|
+
|
|
33
|
+
### 3. `workflowStep`
|
|
34
|
+
|
|
35
|
+
A `workflowStep` represents a single stage within a workflow process. It can contain conditions, actions, and define the next steps based on success or failure.
|
|
36
|
+
|
|
37
|
+
- **`workflow`** (relation to `workflow`, required): The workflow this step belongs to.
|
|
38
|
+
- **`name`** (string, optional): A descriptive name for the step (e.g., "Check Inventory", "Send Confirmation Email").
|
|
39
|
+
- **`conditions`** (code - JSON, optional): Optional conditions (MongoDB filter syntax) that must be met before the step's actions are executed. These can reference `contextData`.
|
|
40
|
+
- **`actions`** (multiple relation to `workflowAction`, required): The main operations performed by this step.
|
|
41
|
+
- **`onSuccessStep`** (relation to `workflowStep`, optional): The next step to execute if this step's conditions are met and actions succeed.
|
|
42
|
+
- **`onFailureStep`** (relation to `workflowStep`, optional): The next step if conditions fail or any action within this step fails.
|
|
43
|
+
- **`isTerminal`** (boolean, default: `false`): Indicates if this step marks the end of a workflow path.
|
|
44
|
+
|
|
45
|
+
### 4. `workflowAction`
|
|
46
|
+
|
|
47
|
+
A `workflowAction` defines a specific operation to be performed by a `workflowStep`. This is where the actual work of the workflow happens.
|
|
48
|
+
|
|
49
|
+
- **`name`** (string, required): Name of the action (e.g., "Update Order Status", "Send Email", "Call Payment API").
|
|
50
|
+
- **`type`** (enum, required): The type of operation to perform:
|
|
51
|
+
- `UpdateData`: Modify existing data in a `targetModel`.
|
|
52
|
+
- `CreateData`: Add new data to a `targetModel`.
|
|
53
|
+
- `DeleteData`: Remove data from a `targetModel`.
|
|
54
|
+
- `ExecuteScript`: Run custom JavaScript code.
|
|
55
|
+
- `HttpRequest`: Make an HTTP request to an external service.
|
|
56
|
+
- `SendEmail`: Send an email.
|
|
57
|
+
- `Wait`: Pause the workflow for a specified duration.
|
|
58
|
+
- `GenerateAIContent`: Generate content using an AI model (e.g., OpenAI, Google Gemini).
|
|
59
|
+
- `ExecuteServiceFunction`: Call a function from a registered internal service (e.g., 'stripe').
|
|
60
|
+
- **`targetModel`** (string, for data operations): The model to target.
|
|
61
|
+
- **`targetSelector`** (code - JSON, for `UpdateData`/`DeleteData`): Expression to filter the target document(s).
|
|
62
|
+
- **`fieldsToUpdate`** (code - JSON, for `UpdateData`): Key-value pairs of fields to update.
|
|
63
|
+
- **`dataToCreate`** (code - JSON, for `CreateData`): Object template for the new document.
|
|
64
|
+
- **`script`** (code - JavaScript, for `ExecuteScript`): The JavaScript code to execute.
|
|
65
|
+
- **`url`, `method`, `headers`, `body`** (for `HttpRequest`): Details for the HTTP request.
|
|
66
|
+
- **`emailRecipients`, `emailSubject`, `emailContent`** (for `SendEmail`): Email details.
|
|
67
|
+
- **`duration`, `durationUnit`** (for `Wait`): How long to pause.
|
|
68
|
+
- **`aiProvider`, `aiModel`, `prompt`** (for `GenerateAIContent`): AI model and prompt details.
|
|
69
|
+
- **`serviceName`, `functionName`, `args`** (for `ExecuteServiceFunction`): Service call details.
|
|
70
|
+
|
|
71
|
+
## Workflow Execution (`workflowRun`)
|
|
72
|
+
|
|
73
|
+
Each time a workflow is triggered, a `workflowRun` document is created to track its execution.
|
|
74
|
+
|
|
75
|
+
- **`workflow`** (relation to `workflow`): The workflow definition that was executed.
|
|
76
|
+
- **`contextData`** (code - JSON): A snapshot of the data or event that triggered this run, and any data generated during execution.
|
|
77
|
+
- **`status`** (enum): The current status (`pending`, `running`, `completed`, `failed`, `waiting`, `cancelled`).
|
|
78
|
+
- **`history`** (array of objects): Detailed execution history of each step and action.
|
|
79
|
+
- **`startedAt`, `completedAt`**: Timestamps for the run.
|
|
80
|
+
- **`error`**: Error message if the workflow run failed.
|
|
81
|
+
|
|
82
|
+
## Example Workflow Scenario
|
|
83
|
+
|
|
84
|
+
Consider a workflow to "Send a Welcome Email to New Users":
|
|
85
|
+
|
|
86
|
+
1. **`workflow`**: "New User Onboarding"
|
|
87
|
+
2. **`workflowTrigger`**:
|
|
88
|
+
- `name`: "On New User Added"
|
|
89
|
+
- `type`: `manual`
|
|
90
|
+
- `onEvent`: `DataAdded`
|
|
91
|
+
- `targetModel`: `user`
|
|
92
|
+
3. **`workflowStep`**: "Send Welcome Email"
|
|
93
|
+
- `workflow`: "New User Onboarding"
|
|
94
|
+
- `actions`: [ID of "Send Welcome Email Action"]
|
|
95
|
+
- `onSuccessStep`: (optional) "Create Onboarding Task"
|
|
96
|
+
4. **`workflowAction`**: "Send Welcome Email Action"
|
|
97
|
+
- `type`: `SendEmail`
|
|
98
|
+
- `emailRecipients`: `{triggerData.contact.email}`
|
|
99
|
+
- `emailSubject`: "Welcome to Our Platform, {triggerData.contact.firstName}!"
|
|
100
|
+
- `emailContent`: "Hello {triggerData.contact.firstName}, welcome aboard..."
|
|
101
|
+
|
|
102
|
+
This powerful system allows you to automate virtually any process, from simple notifications to complex data transformations and integrations with external services.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Core Concepts: Data Modeling Fundamentals
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` is built around a flexible and powerful data modeling system that allows you to define and manage your application's data structures without complex migrations. This section introduces the fundamental concepts of data modeling within the engine.
|
|
4
|
+
|
|
5
|
+
## Dynamic and Schema-less Nature
|
|
6
|
+
|
|
7
|
+
At its core, `data-primals-engine` leverages **MongoDB**, a NoSQL database. This provides inherent flexibility, allowing for a schema-less approach. You can define and update your data models either through a user interface or by providing JSON definitions, and the system adapts dynamically without requiring traditional database migrations. This significantly accelerates development and iteration cycles.
|
|
8
|
+
|
|
9
|
+
## Models
|
|
10
|
+
|
|
11
|
+
A **Model** is the blueprint for a collection of data. It defines the structure and characteristics of the documents you store. For example, a `User` model would define what properties a user object has (e.g., `username`, `email`, `roles`).
|
|
12
|
+
|
|
13
|
+
Models are defined by a `name`, an optional `description`, an `icon`, and a list of `fields`. The engine comes with a set of default models for common entities like `user`, `product`, `workflow`, and more.
|
|
14
|
+
|
|
15
|
+
## Fields
|
|
16
|
+
|
|
17
|
+
**Fields** are the individual attributes that make up a model. Each field has a `name`, a `type`, and various optional properties that define its behavior and constraints.
|
|
18
|
+
|
|
19
|
+
Common field types include:
|
|
20
|
+
- `string`: For text data.
|
|
21
|
+
- `number`: For numerical data.
|
|
22
|
+
- `boolean`: For true/false values.
|
|
23
|
+
- `datetime`: For date and time values.
|
|
24
|
+
- `relation`: To establish relationships between different models (e.g., a `product` model having a `category` field that relates to a `taxonomy` model).
|
|
25
|
+
- `enum`: For fields with a predefined set of allowed values.
|
|
26
|
+
- `file`: For handling file uploads (e.g., `profilePicture` in the `user` model).
|
|
27
|
+
- `code`: For storing code snippets (e.g., `script` in an `endpoint` model).
|
|
28
|
+
|
|
29
|
+
Fields can also have properties like `required`, `unique`, `min`, `max`, `default` values, and `hint` for user guidance.
|
|
30
|
+
|
|
31
|
+
This dynamic and field-based approach to data modeling provides the flexibility needed for rapidly building complex data-driven applications.
|
|
32
|
+
|
|
33
|
+
**Next: Data Models**
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Custom API Endpoints: Create Dynamic HTTP Routes
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` allows you to extend its API by defining **Custom API Endpoints**. These endpoints are dynamic HTTP routes that execute server-side JavaScript code directly from the backend, providing immense flexibility for custom logic and integrations.
|
|
4
|
+
|
|
5
|
+
## The `endpoint` Model
|
|
6
|
+
|
|
7
|
+
Custom API Endpoints are managed through the built-in `endpoint` data model. Each document in this model represents a unique API route.
|
|
8
|
+
|
|
9
|
+
### Key Fields of the `endpoint` Model:
|
|
10
|
+
|
|
11
|
+
- **`name`** (string, required): A human-readable name for the endpoint.
|
|
12
|
+
- **`path`** (string, required, unique): The URL path segment that comes after `/api/actions/`. For example, if `path` is `send-welcome-email`, the full endpoint URL would be `/api/actions/send-welcome-email`.
|
|
13
|
+
- **`method`** (enum, required): The HTTP method (GET, POST, PUT, PATCH, DELETE) that this endpoint responds to.
|
|
14
|
+
- **`code`** (code, required): The JavaScript script that will be executed when this endpoint is called. This script has access to various utilities and the request context.
|
|
15
|
+
- **`isActive`** (boolean, default: `true`): If checked, the endpoint is active and can be called.
|
|
16
|
+
- **`isPublic`** (boolean, default: `false`): If checked, this endpoint will be accessible without authentication. Use with caution.
|
|
17
|
+
|
|
18
|
+
### Script Execution Environment
|
|
19
|
+
|
|
20
|
+
The JavaScript `code` field provides a powerful environment for your custom logic:
|
|
21
|
+
|
|
22
|
+
- **`db`**: An object providing methods for interacting with the database (e.g., `db.find`, `db.create`, `db.update`, `db.delete`).
|
|
23
|
+
- **`logger`**: A logging utility (e.g., `logger.info`, `logger.error`).
|
|
24
|
+
- **`env`**: Access to environment variables defined in the `env` model.
|
|
25
|
+
- **`request`**: The incoming HTTP request object, containing `body`, `query`, `params`, and `headers`.
|
|
26
|
+
- **`user`**: The authenticated user object (if `isPublic` is false).
|
|
27
|
+
|
|
28
|
+
The script's return value will be sent as the JSON response to the client.
|
|
29
|
+
|
|
30
|
+
### Example `endpoint` Definition (from `defaultModels.js`):
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
// The default code for a new endpoint
|
|
34
|
+
logger.info('Custom endpoint executed with body:', request.body);
|
|
35
|
+
return { success: true, message: 'Endpoint executed!', received: request.body };
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This feature allows developers to build highly customized backend logic directly within the `data-primals-engine`, making it a versatile tool for various application needs.
|
|
39
|
+
|
|
40
|
+
**Next: Data Models**
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Dashboards, KPIs, and Charts: Track Your Key Metrics
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` provides robust features for visualizing and tracking your application's performance and key metrics through customizable Dashboards and Key Performance Indicators (KPIs).
|
|
4
|
+
|
|
5
|
+
## Dashboards
|
|
6
|
+
|
|
7
|
+
A **Dashboard** serves as a personalized overview, allowing users to arrange and display various KPIs and charts relevant to their needs.
|
|
8
|
+
|
|
9
|
+
### Key Fields of the `dashboard` Model:
|
|
10
|
+
|
|
11
|
+
- **`name`** (string, required): The customizable display name of the dashboard.
|
|
12
|
+
- **`description`** (string, optional): Provides additional context for the dashboard.
|
|
13
|
+
- **`layout`** (code - JSON, required): A JSON structure describing the organization of KPIs and charts. This defines how elements are arranged (e.g., in columns).
|
|
14
|
+
- **Example Layout**: `"{ \"type\": \"columns\", \"columns\": [ [\"kpi_id_1\"], [\"kpi_id_2\", \"kpi_id_3\"] ] }"`
|
|
15
|
+
- **`settings`** (code - JSON, optional): JSON settings for the dashboard, such as a `defaultTimeRange` (e.g., 'last_7_days') or a `refreshInterval` in seconds.
|
|
16
|
+
- **`isDefault`** (boolean, default: `false`): If `true`, this dashboard is displayed by default for the user.
|
|
17
|
+
|
|
18
|
+
## Key Performance Indicators (KPIs)
|
|
19
|
+
|
|
20
|
+
**KPIs** are quantifiable measures used to evaluate the success of an organization, employee, etc., in meeting objectives. In `data-primals-engine`, KPIs are highly configurable to extract meaningful insights from your data.
|
|
21
|
+
|
|
22
|
+
### Key Fields of the `kpi` Model:
|
|
23
|
+
|
|
24
|
+
- **`name`** (string, required): The display name of the KPI (e.g., "Total Revenue", "Active Users").
|
|
25
|
+
- **`description`** (string, optional): Additional information about the KPI.
|
|
26
|
+
- **`targetModel`** (string, required): The name of the data model on which to calculate the KPI (e.g., `order`, `user`).
|
|
27
|
+
- **`aggregationType`** (enum, required): The type of calculation to perform:
|
|
28
|
+
- `count`: Count the number of documents.
|
|
29
|
+
- `sum`: Sum a numeric field.
|
|
30
|
+
- `avg`: Calculate the average of a numeric field.
|
|
31
|
+
- `min`: Find the minimum value of a numeric field.
|
|
32
|
+
- `max`: Find the maximum value of a numeric field.
|
|
33
|
+
- **`aggregationField`** (string, optional): The name of the numeric field to apply the aggregation to (e.g., `totalAmount`). Not required for `count` type.
|
|
34
|
+
- **`matchFormula`** (code - JSON, optional): A MongoDB `$match` JSON filter to apply before aggregation (e.g., `{ "status": "delivered" }`). This allows you to filter the data used for the KPI calculation.
|
|
35
|
+
- **`showTotal`** (boolean): Whether to display a grand total alongside the KPI.
|
|
36
|
+
- **`showPercentTotal`** (boolean): Whether to display the KPI value as a percentage of a total.
|
|
37
|
+
- **`totalMatchFormula`** (code - JSON, optional): A MongoDB `$match` JSON filter for calculating the total when `showPercentTotal` is enabled.
|
|
38
|
+
- **`unit`** (string, optional): The unit to display with the KPI value (e.g., "€", "$", "users").
|
|
39
|
+
- **`icon`** (string, optional): An icon name (e.g., `FaUsers`, `FaShoppingCart`) to visually represent the KPI.
|
|
40
|
+
- **`order`** (number, optional): The display order of the KPI on a dashboard.
|
|
41
|
+
- **`color`** (string, optional): A color associated with the KPI for visual distinction.
|
|
42
|
+
|
|
43
|
+
## Charts
|
|
44
|
+
|
|
45
|
+
While the `kpi` model focuses on single aggregated values, the engine also supports the integration of charts to visualize data trends and distributions over time or across categories. These are typically rendered based on underlying KPI data or direct queries, offering a richer analytical experience.
|
|
46
|
+
|
|
47
|
+
By combining Dashboards, configurable KPIs, and charting capabilities, `data-primals-engine` empowers users to effectively monitor and understand their key business metrics.
|
|
48
|
+
|
|
49
|
+
**Next: Users**
|