data-primals-engine 1.6.2 → 1.6.5
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 +56 -911
- package/client/package-lock.json +64 -50
- package/client/package.json +6 -0
- package/client/src/App.scss +29 -0
- package/client/src/Dashboard.jsx +1 -1
- package/client/src/WorkflowEditor.jsx +101 -0
- package/client/src/WorkflowEditor.scss +29 -4
- package/client/src/_variables.scss +3 -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 +7 -5
- package/src/client.js +6 -4
- package/src/core.js +31 -12
- package/src/defaultModels +1628 -0
- package/src/defaultModels.js +14 -0
- package/src/filter.js +110 -42
- package/src/modules/data/data.history.js +5 -1
- package/src/modules/data/data.js +2 -1
- package/src/modules/data/data.operations.js +116 -72
- package/src/modules/data/data.relations.js +1 -1
- package/src/modules/mongodb.js +2 -1
- package/src/modules/swagger.js +25 -5
- package/src/modules/user.js +138 -76
- package/src/modules/workflow.js +187 -177
- package/src/providers.js +1 -1
- package/swagger-en.yml +2308 -472
- package/swagger-fr.yml +487 -3
- package/test/core.test.js +341 -0
- package/test/data.history.integration.test.js +140 -16
- package/test/data.integration.test.js +137 -2
- package/test/user.test.js +201 -280
- package/test/workflow.integration.test.js +8 -0
|
@@ -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**
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Data Management: Create, Read, Update, and Delete Entries
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` provides a powerful and flexible API for performing standard CRUD (Create, Read, Update, Delete) operations on all defined data models. These generic endpoints allow you to interact with your data programmatically.
|
|
4
|
+
|
|
5
|
+
## Authentication
|
|
6
|
+
|
|
7
|
+
All data management operations require authentication. You must provide a valid `_user` query parameter (your username) and a `Bearer` token in the `Authorization` header for most operations.
|
|
8
|
+
|
|
9
|
+
## API Endpoints Overview
|
|
10
|
+
|
|
11
|
+
The following endpoints are available for generic data management:
|
|
12
|
+
|
|
13
|
+
### 1. Create Data: `POST /api/data`
|
|
14
|
+
|
|
15
|
+
This endpoint allows you to create one or more new documents within a specified model.
|
|
16
|
+
|
|
17
|
+
- **Method**: `POST`
|
|
18
|
+
- **Summary**: Create one or more documents
|
|
19
|
+
- **Description**: Creates one or more new documents in a specified model.
|
|
20
|
+
- **Security**: `BearerAuth`
|
|
21
|
+
- **Parameters**:
|
|
22
|
+
- `_user` (query, required): Your username for authentication.
|
|
23
|
+
- `model` (body, required): The name of the model in which to create the documents (e.g., 'user', 'product').
|
|
24
|
+
- `data` (body, required): The data to insert. Can be a single object or an array of objects. Using the `$find` operator is recommended for relational data.
|
|
25
|
+
- `lang` (query, optional, default: 'en'): Language used for error messages.
|
|
26
|
+
- **Example Request Body**:
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"model": "product",
|
|
30
|
+
"data": {
|
|
31
|
+
"name": "New Product",
|
|
32
|
+
"price": 99.99,
|
|
33
|
+
"currency": "60d0fe4f5311236168a109cb"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
- **Responses**: `201` (Document(s) successfully created), `400` (Invalid data), `401` (Unauthorized).
|
|
38
|
+
|
|
39
|
+
### 2. Search Data: `POST /api/data/search`
|
|
40
|
+
|
|
41
|
+
This endpoint allows you to search and retrieve documents from a specified model. It supports powerful filtering, sorting, pagination, and relation population.
|
|
42
|
+
|
|
43
|
+
- **Method**: `POST`
|
|
44
|
+
- **Summary**: Search among data
|
|
45
|
+
- **Description**: Search across all data of the specified model.
|
|
46
|
+
- **Security**: `BearerAuth`
|
|
47
|
+
- **Parameters**:
|
|
48
|
+
- `_user` (query, required): Your username for authentication.
|
|
49
|
+
- `model` (body, required): The name of the data model (e.g., 'user', 'product').
|
|
50
|
+
- `filter` (body, optional): MongoDB filter JSON object for the search.
|
|
51
|
+
- `sort` (query, optional): Sort parameter by field (e.g., `fieldName:ASC;fieldName2:DESC`).
|
|
52
|
+
- `limit` (query, optional, default: 1000): Maximum number of documents to return.
|
|
53
|
+
- `offset` (query, optional, default: 0): Number of documents to skip (for pagination).
|
|
54
|
+
- `depth` (query, optional, default: 1): Population depth for 'relation' type fields.
|
|
55
|
+
- `lang` (query, optional, default: 'en'): Language used for error messages.
|
|
56
|
+
- **Example Request Body (Filter)**:
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"model": "product",
|
|
60
|
+
"filter": {
|
|
61
|
+
"price": { "$gt": 50 },
|
|
62
|
+
"category": "60d0fe4f5311236168a109cc"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
- **Responses**: `200` (Success with returned data), `401` (Unauthorized).
|
|
67
|
+
|
|
68
|
+
### 3. Update Data: `PUT /api/data/{id}` or `PUT /api/data` (Bulk)
|
|
69
|
+
|
|
70
|
+
You can update a single document by its ID or perform bulk updates using a filter.
|
|
71
|
+
|
|
72
|
+
- **Method**: `PUT`
|
|
73
|
+
- **Summary**: Update a document (by ID) or Bulk update documents
|
|
74
|
+
- **Description**: Updates an existing document using its ID, or multiple documents using a filter.
|
|
75
|
+
- **Security**: `BearerAuth`
|
|
76
|
+
- **Parameters**:
|
|
77
|
+
- `_user` (query, required): Your username for authentication.
|
|
78
|
+
- `id` (path, required for single update): The unique identifier (`_id`) of the document to update.
|
|
79
|
+
- `model` (body, required): The name of the data model.
|
|
80
|
+
- `data` (body, required): The data to edit. For bulk updates, this object will contain the fields to update.
|
|
81
|
+
- `filter` (body, optional, for bulk update): MongoDB filter JSON object to select documents for bulk update.
|
|
82
|
+
- `lang` (query, optional, default: 'en'): Language used for error messages.
|
|
83
|
+
- **Example Request Body (Single Update)**:
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"model": "product",
|
|
87
|
+
"data": {
|
|
88
|
+
"price": 120.00
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
- **Responses**: `200` (Document successfully updated), `400` (Invalid data), `401` (Unauthorized), `404` (Document not found).
|
|
93
|
+
|
|
94
|
+
### 4. Delete Data: `DELETE /api/data`
|
|
95
|
+
|
|
96
|
+
This endpoint allows you to permanently delete one or more documents.
|
|
97
|
+
|
|
98
|
+
- **Method**: `DELETE`
|
|
99
|
+
- **Summary**: Delete one or more document(s)
|
|
100
|
+
- **Description**: Permanently deletes a document using its ID, or multiple documents using a filter.
|
|
101
|
+
- **Security**: `BearerAuth`
|
|
102
|
+
- **Parameters**:
|
|
103
|
+
- `_user` (query, required): Your username for authentication.
|
|
104
|
+
- `ids` (body, optional): An array of identifiers of the documents to delete.
|
|
105
|
+
- `filter` (body, optional): The MongoDB JSON filter to apply for bulk deletion.
|
|
106
|
+
- `lang` (query, optional, default: 'en'): Language used for error messages.
|
|
107
|
+
- **Example Request Body (Bulk Delete)**:
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"model": "product",
|
|
111
|
+
"filter": {
|
|
112
|
+
"status": "draft"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
- **Responses**: `200` (Document successfully deleted), `401` (Unauthorized), `404` (Document not found).
|
|
117
|
+
|
|
118
|
+
These generic CRUD endpoints provide a flexible and powerful way to interact with all your data models within the `data-primals-engine`.
|
|
119
|
+
|
|
120
|
+
**Next: Dashboards, KPIs, and Charts**
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Data Models: Structuring Your Information
|
|
2
|
+
|
|
3
|
+
Data Models are the fundamental building blocks in `data-primals-engine`, defining how your application's data is structured and stored. They are essentially blueprints for collections of documents, enabling you to organize and manage diverse types of information.
|
|
4
|
+
|
|
5
|
+
## What is a Data Model?
|
|
6
|
+
|
|
7
|
+
In `data-primals-engine`, a data model is a flexible definition of a data entity. Unlike traditional relational databases, models here are schema-less (thanks to MongoDB), meaning you can evolve their structure over time without rigid migration processes. Each model corresponds to a collection in your MongoDB database.
|
|
8
|
+
|
|
9
|
+
## Defining a Model
|
|
10
|
+
|
|
11
|
+
Models can be defined either through the platform's user interface or by providing a JSON schema. Key attributes of a model include:
|
|
12
|
+
|
|
13
|
+
- **`name`** (string, unique): The technical name of the model (e.g., `product`, `user`, `order`). This is used for API interactions and internal references.
|
|
14
|
+
- **`description`** (string): A brief explanation of the model's purpose.
|
|
15
|
+
- **`icon`** (string): An icon (e.g., a Font Awesome class) to visually represent the model in the UI.
|
|
16
|
+
- **`tags`** (array of strings): Keywords for categorization and filtering.
|
|
17
|
+
- **`locked`** (boolean): Indicates if the model is a system model and cannot be modified or deleted via the standard UI (e.g., `user`, `permission`).
|
|
18
|
+
- **`fields`** (array of objects): The core of the model, defining its attributes.
|
|
19
|
+
|
|
20
|
+
## Fields: The Attributes of a Model
|
|
21
|
+
|
|
22
|
+
Each field within a model defines a specific piece of data. Fields have various properties to control their type, behavior, and validation:
|
|
23
|
+
|
|
24
|
+
- **`name`** (string, unique within model): The name of the attribute (e.g., `title`, `price`, `email`).
|
|
25
|
+
- **`type`** (string, required): The data type of the field. Common types include:
|
|
26
|
+
- `string`, `string_t` (translatable string)
|
|
27
|
+
- `number`
|
|
28
|
+
- `boolean`
|
|
29
|
+
- `datetime`, `date`
|
|
30
|
+
- `email`, `url`, `phone`, `password`
|
|
31
|
+
- `richtext`, `richtext_t` (translatable rich text)
|
|
32
|
+
- `enum` (predefined list of values)
|
|
33
|
+
- `file` (for file uploads)
|
|
34
|
+
- `relation` (to link to another model)
|
|
35
|
+
- `array` (for lists of values or sub-documents)
|
|
36
|
+
- `code` (for storing code snippets, e.g., JSON, JavaScript)
|
|
37
|
+
- **`required`** (boolean): If `true`, the field must have a value.
|
|
38
|
+
- **`unique`** (boolean): If `true`, the field's value must be unique across all documents in the collection.
|
|
39
|
+
- **`default`**: A default value for the field.
|
|
40
|
+
- **`min`, `max`**: Minimum and maximum values for `number` fields, or length for `string` fields.
|
|
41
|
+
- **`relation`** (string, for `relation` type): The name of the model this field relates to.
|
|
42
|
+
- **`multiple`** (boolean, for `relation` type): If `true`, the field can relate to multiple documents in the target model.
|
|
43
|
+
- **`hint`** (string): A helpful description displayed in the UI.
|
|
44
|
+
|
|
45
|
+
## Example: The `product` Model
|
|
46
|
+
|
|
47
|
+
The `product` model, defined in `defaultModels.js`, illustrates how fields are used to structure information about a product:
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
product: {
|
|
51
|
+
name: 'product',
|
|
52
|
+
"icon": "FaShoppingBag",
|
|
53
|
+
"description": "",
|
|
54
|
+
"tags": ["ecommerce", "products"],
|
|
55
|
+
fields: [
|
|
56
|
+
{ name: 'name', type: 'string_t', required: true },
|
|
57
|
+
{ name: 'image', type: 'array', itemsType: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
|
|
58
|
+
{ name: 'description', type: 'richtext_t' },
|
|
59
|
+
{ name: 'price', type: 'number', required: true },
|
|
60
|
+
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
61
|
+
{ name: 'billingFrequency', type: 'enum', items: ['none', 'monthly', 'yearly'] },
|
|
62
|
+
{ name: 'slug', type: 'string', required: true, unique: true },
|
|
63
|
+
{ name: 'brand', type: 'relation', relation: 'brand' },
|
|
64
|
+
{ name: 'category', type: 'relation', relation: 'taxonomy' },
|
|
65
|
+
{ name: 'seoTitle', type: 'string_t' },
|
|
66
|
+
{ name: 'seoDescription', type: 'string_t' }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This example shows how a `product` can have a translatable `name`, multiple `image` files, a `price` with a `currency` relation, and be linked to a `brand` and `category` (taxonomy).
|
|
72
|
+
|
|
73
|
+
By defining models and their fields, you create a robust and adaptable data foundation for your `data-primals-engine` application.
|
|
74
|
+
|
|
75
|
+
**Next: Data Management**
|
package/doc/index.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# data-primals-engine Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the `data-primals-engine` documentation! This guide will help you understand the core concepts, features, and how to effectively use the platform to build powerful data-driven applications.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- Core Concepts: Data Modeling Fundamentals
|
|
8
|
+
- Data Models: Structuring Your Information
|
|
9
|
+
- Data Management: Create, Read, Update, and Delete Entries
|
|
10
|
+
- Custom API Endpoints: Create Dynamic HTTP Routes
|
|
11
|
+
- Dashboards, KPIs, and Charts: Track Your Key Metrics
|
|
12
|
+
- Users: Manage Access to the Platform
|
|
13
|
+
- Roles and Permissions: Define Who Can See and Do What
|
|
14
|
+
- Automation with Workflows: Create Automated Processes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Roles and Permissions: Define Who Can See and Do What
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` implements a robust Role-Based Access Control (RBAC) system to manage user authorizations. This system relies on two core models: `role` and `permission`, allowing for granular control over what users can access and perform within the platform.
|
|
4
|
+
|
|
5
|
+
## Permissions
|
|
6
|
+
|
|
7
|
+
A **Permission** defines a specific action or access right within the system. Permissions can be very broad (e.g., "admin.full_access") or highly specific (e.g., "product.edit").
|
|
8
|
+
|
|
9
|
+
### Key Fields of the `permission` Model:
|
|
10
|
+
|
|
11
|
+
- **`name`** (string, required): A unique identifier for the permission (e.g., `model.create`, `product.read`, `user.delete`).
|
|
12
|
+
- **`description`** (richtext, optional): A detailed explanation of what the permission grants.
|
|
13
|
+
- **`filter`** (code - JSON, optional): A JSON filter that restricts the scope of this permission. This is a powerful feature for implementing granular access control. For example, a `product.edit` permission could have a filter `{ "owner": "{_user}" }` to allow a user to only edit products they own. The target model is typically deduced from the permission name (e.g., `product.edit` implies the `product` model).
|
|
14
|
+
|
|
15
|
+
## Roles
|
|
16
|
+
|
|
17
|
+
A **Role** is a collection of permissions. Instead of assigning individual permissions to each user, you assign roles, which simplifies management. A user can have multiple roles.
|
|
18
|
+
|
|
19
|
+
### Key Fields of the `role` Model:
|
|
20
|
+
|
|
21
|
+
- **`name`** (string, required, unique): The name of the role (e.g., `Administrator`, `Editor`, `Viewer`).
|
|
22
|
+
- **`permissions`** (multiple relation to `permission` model): A list of `permission` documents associated with this role. Any user assigned this role will inherit all its permissions.
|
|
23
|
+
|
|
24
|
+
## How RBAC Works
|
|
25
|
+
|
|
26
|
+
1. **Define Permissions**: Create specific `permission` documents for every action or resource you want to control. Use the `filter` field for fine-grained control.
|
|
27
|
+
2. **Create Roles**: Group relevant permissions into `role` documents.
|
|
28
|
+
3. **Assign Roles to Users**: Assign one or more `role` documents to each `user` document.
|
|
29
|
+
|
|
30
|
+
When a user attempts an action (e.g., accessing an API endpoint or modifying a data entry), the system checks if the user's assigned roles grant them the necessary permissions. If a permission has a `filter`, that filter is applied to the data access query, ensuring the user only interacts with allowed subsets of data.
|
|
31
|
+
|
|
32
|
+
### User Permissions (Exceptions)
|
|
33
|
+
|
|
34
|
+
The `userPermission` model allows for exceptions to the standard role-based permissions. This model can grant or revoke specific permissions for an individual user, either permanently or temporarily.
|
|
35
|
+
|
|
36
|
+
- **`user`** (relation to `user` model): The user for whom the exception applies.
|
|
37
|
+
- **`permission`** (relation to `permission` model): The specific permission being granted or revoked.
|
|
38
|
+
- **`isGranted`** (boolean, required): `true` to grant the permission, `false` to explicitly revoke it.
|
|
39
|
+
- **`expiresAt`** (datetime, optional): If set, the exception is temporary.
|
|
40
|
+
|
|
41
|
+
This comprehensive RBAC system ensures that your `data-primals-engine` application remains secure and that users only have access to the functionalities and data they are authorized to use.
|
|
42
|
+
|
|
43
|
+
**Next: Automation with Workflows**
|
package/doc/users.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Users: Manage Access to the Platform
|
|
2
|
+
|
|
3
|
+
The `data-primals-engine` includes a robust user management system, allowing you to control access to your data and functionalities. The core of this system is the `user` model, which stores all necessary information about platform users.
|
|
4
|
+
|
|
5
|
+
## The `user` Model
|
|
6
|
+
|
|
7
|
+
The `user` model is a fundamental, system-locked model that defines the attributes of each user account.
|
|
8
|
+
|
|
9
|
+
### Key Fields of the `user` Model:
|
|
10
|
+
|
|
11
|
+
- **`username`** (string, required, unique): The unique identifier for the user, used for login.
|
|
12
|
+
- **`password`** (password): The user's hashed password.
|
|
13
|
+
- **`gender`** (enum): Optional field for gender, with options like `male`, `female`, `other`, `prefer_not_to_say`.
|
|
14
|
+
- **`contact`** (relation to `contact` model): Links to a `contact` document, which can store detailed personal information like `firstName`, `lastName`, `email`, and `phone`.
|
|
15
|
+
- **`roles`** (multiple relation to `role` model): Assigns one or more roles to the user, determining their permissions within the system.
|
|
16
|
+
- **`lang`** (relation to `lang` model): Specifies the preferred language for the user interface and content.
|
|
17
|
+
- **`profilePicture`** (file): Allows users to upload a profile image (supports JPEG and PNG).
|
|
18
|
+
- **`tokens`** (multiple relation to `token` model): Stores authentication tokens associated with the user.
|
|
19
|
+
|
|
20
|
+
### User Authentication
|
|
21
|
+
|
|
22
|
+
The engine provides mechanisms for user authentication, typically involving username/password credentials to issue JWT (JSON Web Tokens). These tokens are then used to secure API requests, ensuring that only authorized users can access or modify data.
|
|
23
|
+
|
|
24
|
+
### User-Specific Data
|
|
25
|
+
|
|
26
|
+
Each document created within the `data-primals-engine` is associated with a user via the `_user` field. This ensures data isolation and allows for granular access control, where users primarily interact with data they own or have been granted access to.
|
|
27
|
+
|
|
28
|
+
Effective user management is crucial for maintaining security and organizing access within your `data-primals-engine` application.
|
|
29
|
+
|
|
30
|
+
**Next: Roles and Permissions**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-primals-engine",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.5",
|
|
4
4
|
"description": "data-primals-engine is a package responsible from handling large amount of data using MongoDB in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation. It also has integrated AI assistant.",
|
|
5
5
|
"main": "src/engine.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
"tar-fs": ">=3.1.1",
|
|
36
36
|
"vite": ">=7.0.8",
|
|
37
37
|
"node-forge": ">=1.3.2",
|
|
38
|
-
"js-yaml": ">=4.1.1"
|
|
38
|
+
"js-yaml": ">=4.1.1",
|
|
39
|
+
"mdast-util-to-hast": ">=13.2.1",
|
|
40
|
+
"jws": ">=3.2.3"
|
|
39
41
|
},
|
|
40
42
|
"overrides": {
|
|
41
43
|
"react-syntax-highlighter": {
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
"archiver": "^7.0.1",
|
|
66
68
|
"aws-sdk": "^2.1692.0",
|
|
67
69
|
"bcrypt": "^6.0.0",
|
|
68
|
-
"body-parser": "
|
|
70
|
+
"body-parser": ">=2.2.1",
|
|
69
71
|
"chalk": "^5.4.1",
|
|
70
72
|
"check-disk-space": "^3.4.0",
|
|
71
73
|
"compression": "^1.8.1",
|
|
@@ -86,7 +88,7 @@
|
|
|
86
88
|
"mongodb": "^6.18.0",
|
|
87
89
|
"node-cache": "^5.1.2",
|
|
88
90
|
"node-schedule": "^2.1.1",
|
|
89
|
-
"nodemailer": "^7.0.
|
|
91
|
+
"nodemailer": "^7.0.11",
|
|
90
92
|
"openai": "^6.9.1",
|
|
91
93
|
"passport": "^0.7.0",
|
|
92
94
|
"passport-saml-encrypted": "^0.1.13",
|
|
@@ -108,7 +110,7 @@
|
|
|
108
110
|
"yaml": "^2.8.1"
|
|
109
111
|
},
|
|
110
112
|
"peerDependencies": {
|
|
111
|
-
"express": "^5.1
|
|
113
|
+
"express": "^5.2.1",
|
|
112
114
|
"passport-azure-ad": "^4.3.5",
|
|
113
115
|
"passport-google-oauth20": "^2.0.0",
|
|
114
116
|
"react": "18.3.1",
|
package/src/client.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
// data-primals-engine/client
|
|
2
|
-
// Ce fichier sert de point d'entrée pour les modules qui peuvent être utilisés en toute sécurité côté client (navigateur).
|
|
3
|
-
|
|
4
|
-
export { Event } from './events.js';
|
|
1
|
+
// data-primals-engine/client
|
|
2
|
+
// Ce fichier sert de point d'entrée pour les modules qui peuvent être utilisés en toute sécurité côté client (navigateur).
|
|
3
|
+
|
|
4
|
+
export { Event } from './events.js';
|
|
5
|
+
export { GameObject, Logger, BenchmarkTool } from './gameObject.js';
|
|
6
|
+
export { Config } from './config.js';
|
package/src/core.js
CHANGED
|
@@ -40,7 +40,10 @@ export const isUnsecureKey = (key) => {
|
|
|
40
40
|
export const parseSafeJSON = (json) => JSON.parse(json, (key, value) => isUnsecureKey(key) ? undefined : value);
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
export const isDate = dt =>
|
|
43
|
+
export const isDate = dt => {
|
|
44
|
+
if (dt === null || typeof dt === 'undefined') return false;
|
|
45
|
+
return String(new Date(dt)) !== 'Invalid Date';
|
|
46
|
+
};
|
|
44
47
|
|
|
45
48
|
export const safeAssignObject = (obj, key, value) => {
|
|
46
49
|
if( !isUnsecureKey(key)){
|
|
@@ -157,11 +160,11 @@ export function isPathRelativeTo(dir, parent) {
|
|
|
157
160
|
* @param value string value
|
|
158
161
|
*/
|
|
159
162
|
export function isGUID(value) {
|
|
160
|
-
return typeof(value) === 'string' && value.match(/^[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$/);
|
|
163
|
+
return !!(typeof(value) === 'string' && value.match(/^[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$/));
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
export function isPlainObject(obj) {
|
|
164
|
-
return typeof obj === 'object' && obj !== null;
|
|
167
|
+
return typeof obj === 'object' && obj !== null && !Array.isArray(obj) && !(obj instanceof Date);
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
export function escapeRegExp(string) {
|
|
@@ -210,7 +213,11 @@ function splitmix32(a) {
|
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
|
|
213
|
-
export const getRand = () =>
|
|
216
|
+
export const getRand = () => {
|
|
217
|
+
const result = splitmix32(seed);
|
|
218
|
+
seed++; // Simple increment to change the state for the next call
|
|
219
|
+
return result;
|
|
220
|
+
};
|
|
214
221
|
|
|
215
222
|
const MAX_RANGE_SIZE = 2n ** 64n
|
|
216
223
|
const buffer = new BigUint64Array(512)
|
|
@@ -371,14 +378,26 @@ export const event_off = (name, callback) => {
|
|
|
371
378
|
};
|
|
372
379
|
|
|
373
380
|
|
|
374
|
-
export function slugify(str,replacer='-',
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
str = str.
|
|
380
|
-
|
|
381
|
-
|
|
381
|
+
export function slugify(str,replacer='-', removeNonAscii=false) {
|
|
382
|
+
|
|
383
|
+
if (!str) return '';
|
|
384
|
+
|
|
385
|
+
// 1. Convert to string, lowercase, and trim whitespace.
|
|
386
|
+
str = str.toString().toLowerCase().trim();
|
|
387
|
+
|
|
388
|
+
// 2. Normalize Unicode characters (e.g., è -> e). This is now always done.
|
|
389
|
+
str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
390
|
+
|
|
391
|
+
// 3. Remove any remaining non-ASCII characters if the flag is set.
|
|
392
|
+
if (removeNonAscii) {
|
|
393
|
+
str = str.replace(/[^a-z0-9\s-]/g, '');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// 4. Replace spaces with the replacer and clean up consecutive/trailing replacers.
|
|
397
|
+
return str
|
|
398
|
+
.replace(/\s+/g, replacer) // Replace spaces with the replacer.
|
|
399
|
+
.replace(new RegExp(`[^a-z0-9${replacer}]`, 'g'), '') // Remove any character that is not a letter, a number, or the replacer itself.
|
|
400
|
+
.replace(new RegExp(`${replacer}+`, 'g'), replacer); // Replace multiple replacers with a single one.
|
|
382
401
|
}
|
|
383
402
|
|
|
384
403
|
// resource : https://stackoverflow.com/questions/190852/how-can-i-get-file-extensions-with-javascript
|