data-primals-engine 1.4.3 → 1.5.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 +878 -867
- package/client/package-lock.json +49 -0
- package/client/package.json +1 -0
- package/client/src/App.jsx +1 -1
- package/client/src/App.scss +13 -3
- package/client/src/AssistantChat.scss +3 -2
- package/client/src/DashboardView.jsx +569 -569
- package/client/src/DataEditor.jsx +2 -2
- package/client/src/DataLayout.jsx +1 -8
- package/client/src/DataTable.jsx +26 -4
- package/client/src/Field.jsx +1825 -1788
- package/client/src/FlexDataRenderer.jsx +2 -0
- package/client/src/FlexTreeUtils.js +1 -1
- package/client/src/KPIDialog.jsx +11 -1
- package/client/src/ModelCreator.jsx +1 -2
- package/client/src/ModelCreatorField.jsx +23 -27
- package/client/src/ModelList.jsx +1 -1
- package/client/src/constants.js +1 -1
- package/client/src/hooks/useTutorials.jsx +62 -65
- package/client/src/translations.js +2 -0
- package/package.json +2 -1
- package/perf/README.md +147 -0
- package/perf/artillery-hooks.js +37 -0
- package/perf/perf-shot-hardwork.yml +84 -0
- package/perf/perf-shot-search.yml +45 -0
- package/perf/setup.yml +26 -0
- package/server.js +1 -1
- package/src/constants.js +2 -27
- package/src/core.js +15 -1
- package/src/data.js +1 -1
- package/src/defaultModels.js +1544 -1540
- package/src/email.js +5 -2
- package/src/engine.js +5 -3
- package/src/filter.js +5 -3
- package/src/modules/assistant/assistant.js +3 -1
- package/src/modules/bucket.js +12 -15
- package/src/modules/data/data.backup.js +11 -8
- package/src/modules/data/data.js +6 -3
- package/src/modules/data/data.operations.js +3231 -2999
- package/src/modules/data/data.routes.js +1821 -1785
- package/src/modules/data/data.scheduling.js +2 -1
- package/src/modules/data/data.validation.js +4 -1
- package/src/modules/file.js +4 -2
- package/src/modules/user.js +4 -1
- package/src/modules/workflow.js +9 -10
- package/src/openai.jobs.js +2 -0
- package/src/packs.js +22 -5
- package/src/providers.js +22 -7
- package/test/data.integration.test.js +1060 -981
- package/test/import_export.integration.test.js +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
config:
|
|
2
|
+
# L'URL de base de votre API
|
|
3
|
+
processor: "./artillery-hooks.js" # Indique à Artillery d'utiliser notre fichier de hooks
|
|
4
|
+
target: "http://localhost:7633"
|
|
5
|
+
# Configuration des phases de test
|
|
6
|
+
phases:
|
|
7
|
+
# Phase 1: Montée en charge progressive pendant 30 secondes
|
|
8
|
+
- duration: 60
|
|
9
|
+
arrivalRate: 1 # 5 nouveaux utilisateurs virtuels par seconde
|
|
10
|
+
rampTo: 1 # pour atteindre 20 nouveaux utilisateurs virtuels par seconde à la fin de la phase
|
|
11
|
+
name: "Ramp-up"
|
|
12
|
+
# Phase 2: Maintien de la charge maximale pendant 60 secondes
|
|
13
|
+
# Paramètres par défaut pour toutes les requêtes HTTP
|
|
14
|
+
defaults:
|
|
15
|
+
headers:
|
|
16
|
+
# Utilisation du token statique de l'utilisateur 'demo'
|
|
17
|
+
Authorization: "Bearer demotoken"
|
|
18
|
+
Content-Type: 'application/json'
|
|
19
|
+
beforeRequest: "metricsByEndpoint_beforeRequest" # Groups metrics by endpoint
|
|
20
|
+
afterResponse: "metricsByEndpoint_afterResponse" # Logs errors
|
|
21
|
+
scenarios:
|
|
22
|
+
- name: "Parcours Utilisateur Complet"
|
|
23
|
+
flow:
|
|
24
|
+
# Sets unique variables for EACH scenario run
|
|
25
|
+
- function: "setScenarioVariables"
|
|
26
|
+
- log: "--- Démarrage du scénario utilisateur 'developer' ---"
|
|
27
|
+
- post:
|
|
28
|
+
url: "/api/demo/initialize?_user={{demoUser}}"
|
|
29
|
+
json:
|
|
30
|
+
profile: "developer"
|
|
31
|
+
packs:
|
|
32
|
+
- "Multilingual starter pack"
|
|
33
|
+
- "Website Starter Pack"
|
|
34
|
+
- log: "--- Searching in translation table by lang relation ---"
|
|
35
|
+
- post:
|
|
36
|
+
url: "/api/data/search?_user={{demoUser}}"
|
|
37
|
+
json:
|
|
38
|
+
model: "translation"
|
|
39
|
+
filter: { "lang": { "$find": { "code": "en" } } }
|
|
40
|
+
limit: 250
|
|
41
|
+
- log: "--- Étape 2: Ajout d'une nouvelle donnée et capture de son ID ---"
|
|
42
|
+
- post:
|
|
43
|
+
url: "/api/data?_user={{demoUser}}"
|
|
44
|
+
json:
|
|
45
|
+
model: "translation"
|
|
46
|
+
data:
|
|
47
|
+
key: "perf.test.greeting.{{ $uuid }}"
|
|
48
|
+
value: "Hello from performance test!"
|
|
49
|
+
lang: { "$find": { "code": "en" } } # Syntaxe $find corrigée
|
|
50
|
+
capture:
|
|
51
|
+
- json: "$.insertedIds[0]"
|
|
52
|
+
as: "insertedId"
|
|
53
|
+
- log: "--- Étape 3: Import de données (nécessite un modèle et un fichier) ---"
|
|
54
|
+
# 3a. Création d'un modèle pour l'import (tolère l'erreur si le modèle existe déjà)
|
|
55
|
+
- post:
|
|
56
|
+
url: "/api/model?_user={{demoUser}}"
|
|
57
|
+
json:
|
|
58
|
+
name: "perf_import_items_{{ vuId }}" # Unique model name to avoid race conditions
|
|
59
|
+
description: "import model for perf test"
|
|
60
|
+
fields:
|
|
61
|
+
- { name: "name", type: "string" }
|
|
62
|
+
- { name: "value", type: "number" }
|
|
63
|
+
expect:
|
|
64
|
+
- statusCode: 201 # Succès de la création
|
|
65
|
+
- statusCode: 400 # Tolère l'erreur "le modèle existe déjà" pour rendre le test ré-exécutable
|
|
66
|
+
- log: "--- Étape 4: Installation d'un pack de données ---"
|
|
67
|
+
- post:
|
|
68
|
+
url: "/api/packs/install?_user={{demoUser}}&lang=en"
|
|
69
|
+
json:
|
|
70
|
+
packData:
|
|
71
|
+
name: "Perf Test Pack {{ $uuid }}"
|
|
72
|
+
description: "A pack for performance testing."
|
|
73
|
+
models: [{ name: "perf_pack_model_{{ vuId }}", description: "", fields: [{ name: "pack_field", type: "string" }] }] # Unique model name
|
|
74
|
+
data: { all: { "perf_pack_model_{{ vuId }}": [{ "pack_field": "Hello from a pack!" }] } }
|
|
75
|
+
- log: "--- Étape 5: Suppression des données ---"
|
|
76
|
+
- delete:
|
|
77
|
+
url: "/api/model?name=perf_import_items_{{ vuId }}&_user={{demoUser}}" # Delete the unique model
|
|
78
|
+
- delete:
|
|
79
|
+
url: "/api/model?name=perf_pack_model_{{ vuId }}&_user={{demoUser}}" # Delete the unique model
|
|
80
|
+
- delete:
|
|
81
|
+
url: "/api/data/{{ insertedId }}?_user={{demoUser}}"
|
|
82
|
+
json:
|
|
83
|
+
model: "translation"
|
|
84
|
+
ifTrue: "{{ insertedId !== undefined }}" # Ne s'exécute que si l'ID a été capturé
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
config:
|
|
2
|
+
# L'URL de base de votre API
|
|
3
|
+
target: "http://localhost:7633"
|
|
4
|
+
# Configuration des phases de test
|
|
5
|
+
phases:
|
|
6
|
+
# Phase 1: Montée en charge progressive pendant 60 secondes
|
|
7
|
+
- duration: 10
|
|
8
|
+
arrivalRate: 5 # 5 nouveaux utilisateurs virtuels par seconde
|
|
9
|
+
rampTo: 50 # pour atteindre 50 nouveaux utilisateurs par seconde à la fin de la phase
|
|
10
|
+
name: "Ramp-up"
|
|
11
|
+
# Phase 2: Maintien de la charge maximale pendant 120 secondes
|
|
12
|
+
- duration: 120
|
|
13
|
+
arrivalRate: 10 # 50 nouveaux utilisateurs virtuels par seconde
|
|
14
|
+
name: "Sustained load"
|
|
15
|
+
# Paramètres par défaut pour toutes les requêtes HTTP
|
|
16
|
+
defaults:
|
|
17
|
+
headers:
|
|
18
|
+
# Utilisation du token statique de l'utilisateur 'demo'
|
|
19
|
+
Authorization: "Bearer demotoken"
|
|
20
|
+
Content-Type: 'application/json'
|
|
21
|
+
|
|
22
|
+
scenarios:
|
|
23
|
+
- name: "Stress Test - Recherche de données"
|
|
24
|
+
flow: # Envoi d'une requête POST à l'endpoint de recherche
|
|
25
|
+
- post:
|
|
26
|
+
url: "/api/data/search?_user=demo"
|
|
27
|
+
# Le corps de la requête en JSON
|
|
28
|
+
json:
|
|
29
|
+
# Le nom du modèle sur lequel effectuer la recherche
|
|
30
|
+
model: "translation"
|
|
31
|
+
filter: { "lang": { "$find": { "code": "en" } } }
|
|
32
|
+
limit: 250
|
|
33
|
+
- name: "Stress Test - Insertion de données"
|
|
34
|
+
flow: # Envoi d'une requête POST à l'endpoint de recherche
|
|
35
|
+
- post:
|
|
36
|
+
url: "/api/data?_user=demo"
|
|
37
|
+
# Le corps de la requête en JSON
|
|
38
|
+
json:
|
|
39
|
+
# Le nom du modèle sur lequel effectuer la recherche
|
|
40
|
+
model: "translation"
|
|
41
|
+
# Le filtre de recherche (ici, vide pour récupérer tous les documents)
|
|
42
|
+
data: {
|
|
43
|
+
"key": "{{$randomNumber(1,10000)}}",
|
|
44
|
+
"value": "{{$randomNumber(1,10000)}}",
|
|
45
|
+
}
|
package/perf/setup.yml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
config:
|
|
2
|
+
target: "http://localhost:7633"
|
|
3
|
+
phases:
|
|
4
|
+
# Exécute ce scénario une seule fois avec un seul utilisateur virtuel
|
|
5
|
+
- duration: 1
|
|
6
|
+
arrivalCount: 1
|
|
7
|
+
defaults:
|
|
8
|
+
headers:
|
|
9
|
+
# Utilise le token statique de l'utilisateur 'demo' pour l'installation
|
|
10
|
+
Authorization: "Bearer demotoken"
|
|
11
|
+
Content-Type: 'application/json'
|
|
12
|
+
|
|
13
|
+
scenarios:
|
|
14
|
+
- name: "Installation unique des packs de données"
|
|
15
|
+
flow:
|
|
16
|
+
- log: "Installation du 'Website Starter Pack'..."
|
|
17
|
+
- post:
|
|
18
|
+
url: "/api/packs/install?_user=demo"
|
|
19
|
+
json:
|
|
20
|
+
packName: "Website Starter Pack"
|
|
21
|
+
- log: "Installation du 'Multilingual starter pack'..."
|
|
22
|
+
- post:
|
|
23
|
+
url: "/api/packs/install?_user=demo"
|
|
24
|
+
json:
|
|
25
|
+
packName: "Multilingual starter pack"
|
|
26
|
+
- log: "Installation terminée."
|
package/server.js
CHANGED
|
@@ -29,7 +29,7 @@ if (process.argv.length === 3) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
const realPort = process.env.PORT || port;
|
|
32
|
+
const realPort = Config.Get('port', process.env.PORT || port);
|
|
33
33
|
engine.start(realPort, async (r) => {
|
|
34
34
|
const logger = engine.getComponent(Logger);
|
|
35
35
|
console.log("Server started on port " + realPort);
|
package/src/constants.js
CHANGED
|
@@ -30,26 +30,6 @@ export const port = 7633;
|
|
|
30
30
|
*/
|
|
31
31
|
export const cookiesSecret = 'hoaivuymzovyoznllmafivpzaovphlejvalwjvelfhqochakfesv';
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Available languages of the system
|
|
35
|
-
* You need to translate the i18n file, or translations ones.
|
|
36
|
-
* @type {string[]}
|
|
37
|
-
*/
|
|
38
|
-
export const availableLangs = [
|
|
39
|
-
"en",
|
|
40
|
-
"fa",
|
|
41
|
-
"ar",
|
|
42
|
-
"fr",
|
|
43
|
-
"it",
|
|
44
|
-
"es",
|
|
45
|
-
"pt",
|
|
46
|
-
"de",
|
|
47
|
-
"el",
|
|
48
|
-
"ru",
|
|
49
|
-
"cs",
|
|
50
|
-
"sv"
|
|
51
|
-
];
|
|
52
|
-
|
|
53
33
|
/**
|
|
54
34
|
* AWS default configuration (overrided by AWS_* environment variables)
|
|
55
35
|
* @type {{bucketName: string, region: string}}
|
|
@@ -72,8 +52,6 @@ export const emailDefaultConfig = {
|
|
|
72
52
|
pass: 'password'
|
|
73
53
|
}
|
|
74
54
|
|
|
75
|
-
export const useAI = true;
|
|
76
|
-
|
|
77
55
|
/**
|
|
78
56
|
* Maximum number of models per user
|
|
79
57
|
* @type {number}
|
|
@@ -216,11 +194,8 @@ export const maxPrivateFileSize = 20 * megabytes; // Taille max par fichier priv
|
|
|
216
194
|
*/
|
|
217
195
|
export const maxTotalPrivateFilesSize = 250 * megabytes;
|
|
218
196
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
* @type {number}
|
|
222
|
-
*/
|
|
223
|
-
export const timeoutVM = 5000;
|
|
197
|
+
export const maxPackData = 5000;
|
|
198
|
+
export const maxPackPreviewData = maxPackData / 10;
|
|
224
199
|
|
|
225
200
|
/**
|
|
226
201
|
* Default maximum number of data per request
|
package/src/core.js
CHANGED
|
@@ -435,4 +435,18 @@ export const stringToHslColor = (str) => {
|
|
|
435
435
|
const s = 70; // Saturation (fixe pour des couleurs vives mais pas criardes)
|
|
436
436
|
const l = 55; // Luminosité (fixe pour une bonne lisibilité)
|
|
437
437
|
return `hsl(${h}, ${s}%, ${l}%)`;
|
|
438
|
-
};
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
export function countKeys(t) {
|
|
441
|
+
switch (t?.constructor) {
|
|
442
|
+
case Object: // 1
|
|
443
|
+
return Object
|
|
444
|
+
.values(t)
|
|
445
|
+
.reduce((r, v) => r + 1 + countKeys(v), 0)
|
|
446
|
+
case Array: // 2
|
|
447
|
+
return t
|
|
448
|
+
.reduce((r, v) => r + countKeys(v), 0)
|
|
449
|
+
default: // 3
|
|
450
|
+
return 0
|
|
451
|
+
}
|
|
452
|
+
}
|