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
package/src/defaultModels.js
CHANGED
|
@@ -1,1540 +1,1544 @@
|
|
|
1
|
-
// Définition des structures de modèles
|
|
2
|
-
export const defaultModels = {
|
|
3
|
-
permission: {
|
|
4
|
-
"name": "permission",
|
|
5
|
-
"icon": "FaKey",
|
|
6
|
-
"description": "",
|
|
7
|
-
"fields": [
|
|
8
|
-
{
|
|
9
|
-
"name": "name",
|
|
10
|
-
"type": "string_t",
|
|
11
|
-
color: '#757BCC'
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "description",
|
|
15
|
-
"type": "richtext"
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
role: {
|
|
20
|
-
name: 'role',
|
|
21
|
-
"icon": "FaUserTag",
|
|
22
|
-
"description": "",
|
|
23
|
-
fields: [
|
|
24
|
-
{ name: 'name', type: 'string_t', required: true, unique: true, color: '#363636' },
|
|
25
|
-
{ name: 'permissions', type: 'relation', multiple: true, relation: 'permission' }
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
user: {
|
|
29
|
-
name: 'user',
|
|
30
|
-
"description": "",
|
|
31
|
-
"icon": "FaUser",
|
|
32
|
-
locked: true,
|
|
33
|
-
fields: [
|
|
34
|
-
{ name: 'username', type: 'string', required: true, unique: true, color: '#3C7D08' },
|
|
35
|
-
{ name: 'password', type: 'password' },
|
|
36
|
-
{
|
|
37
|
-
"name": "gender",
|
|
38
|
-
"type": "enum",
|
|
39
|
-
"items": ["male", "female", "other", "prefer_not_to_say"]
|
|
40
|
-
},
|
|
41
|
-
{ name: 'contact', type: 'relation', relation: 'contact' },
|
|
42
|
-
{ name: 'roles', type: 'relation', multiple: true, relation: 'role' },
|
|
43
|
-
{ name: 'lang', type: 'relation', relation: 'lang', color: '#4CACCD' },
|
|
44
|
-
{
|
|
45
|
-
"name": "profilePicture",
|
|
46
|
-
"type": "file",
|
|
47
|
-
"mimeTypes": ["image/jpeg", "image/png"]
|
|
48
|
-
},
|
|
49
|
-
{ name: 'tokens', type: 'relation', multiple: true, relation: 'token' }
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
userPermission: {
|
|
53
|
-
"icon": "FaUserCheck",
|
|
54
|
-
"name": "userPermission",
|
|
55
|
-
"description": "Gère les exceptions aux permissions des rôles pour un utilisateur (ajouts ou retraits, permanents ou temporaires).",
|
|
56
|
-
"fields": [
|
|
57
|
-
{
|
|
58
|
-
"name": "user",
|
|
59
|
-
"type": "relation",
|
|
60
|
-
"relation": "user",
|
|
61
|
-
"required": true,
|
|
62
|
-
"index": true
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"name": "permission",
|
|
66
|
-
"type": "relation",
|
|
67
|
-
"relation": "permission",
|
|
68
|
-
"required": true,
|
|
69
|
-
"index": true
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"name": "isGranted",
|
|
73
|
-
"type": "boolean",
|
|
74
|
-
"required": true,
|
|
75
|
-
"hint": "True pour accorder la permission, False pour la révoquer explicitement."
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"name": "expiresAt",
|
|
79
|
-
"type": "datetime",
|
|
80
|
-
"required": false,
|
|
81
|
-
"index": true,
|
|
82
|
-
"hint": "Si défini, l'exception (l'octroi ou la révocation) est temporaire."
|
|
83
|
-
}
|
|
84
|
-
]
|
|
85
|
-
},
|
|
86
|
-
token: {
|
|
87
|
-
name: 'token',
|
|
88
|
-
"icon": "FaKey",
|
|
89
|
-
"description": "",
|
|
90
|
-
fields: [
|
|
91
|
-
{ name: 'name', type: 'string' },
|
|
92
|
-
{ name: 'value', type: 'password' },
|
|
93
|
-
{ name: 'lastRefresh', type: 'datetime' }
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
translation: {
|
|
97
|
-
name: 'translation',
|
|
98
|
-
"icon": "FaLanguage",
|
|
99
|
-
locked: true,
|
|
100
|
-
"description": "",
|
|
101
|
-
fields: [
|
|
102
|
-
{ name: 'lang', type: 'relation', 'relation': 'lang', required: true, color: '#4CACCD' },
|
|
103
|
-
{ name: 'key', type: 'string', maxlength: 200, required: true },
|
|
104
|
-
{ name: 'value', type: 'string' }
|
|
105
|
-
]
|
|
106
|
-
},
|
|
107
|
-
lang: {
|
|
108
|
-
name: 'lang',
|
|
109
|
-
"icon": "FaGlobe",
|
|
110
|
-
locked: true,
|
|
111
|
-
"description": "",
|
|
112
|
-
fields: [
|
|
113
|
-
{ name: 'name', unique: true, type: 'string_t', maxlength: 200, color: '#4CACCD' },
|
|
114
|
-
{ name: 'code', type: 'string', maxlength: 5 }
|
|
115
|
-
]
|
|
116
|
-
},
|
|
117
|
-
currency: {
|
|
118
|
-
name: 'currency',
|
|
119
|
-
"icon": "FaMoneyBill",
|
|
120
|
-
"description": "",
|
|
121
|
-
locked: true,
|
|
122
|
-
fields: [
|
|
123
|
-
{ name: 'symbol', type: 'string', required: true, color: '#E0E0E0', maxlength: 20, asMain: true },
|
|
124
|
-
{ name: 'code', type: 'string', required: true, unique: true, maxlength: 3, asMain: true },
|
|
125
|
-
{ name: 'name', type: 'string_t', required: true, color: '#AE6FA3' },
|
|
126
|
-
{ name: 'exchangeRate', type: 'number', required: false },
|
|
127
|
-
{ name: 'default', type: 'boolean', default: false }
|
|
128
|
-
]
|
|
129
|
-
},
|
|
130
|
-
channel: {
|
|
131
|
-
name: 'channel',
|
|
132
|
-
"icon": "FaComments",
|
|
133
|
-
"description": "",
|
|
134
|
-
fields: [
|
|
135
|
-
{ name: 'name', type: 'string_t', required: true, unique: true }, // Nom du canal (ex: "email", "SMS")
|
|
136
|
-
{ name: 'description', type: 'string_t' },
|
|
137
|
-
{ name: 'type', type: 'enum', items: ['web', 'mobile', 'email', 'sms', 'push'], required: true } // Type de canal
|
|
138
|
-
]
|
|
139
|
-
},
|
|
140
|
-
message: {
|
|
141
|
-
name: 'message',
|
|
142
|
-
"icon": "FaEnvelope",
|
|
143
|
-
"description": "",
|
|
144
|
-
locked: true,
|
|
145
|
-
fields: [
|
|
146
|
-
{ name: 'sender', type: 'relation', relation: 'user' }, // Utilisateur émetteur (si applicable, sinon système)
|
|
147
|
-
{ name: 'recipient', type: 'relation', relation: 'user' }, // Utilisateur destinataire
|
|
148
|
-
{ name: 'lang', type: 'relation', relation: 'lang' }, // Utilisateur destinataire
|
|
149
|
-
{ name: 'subject', type: 'string' }, // Sujet de la notification (ex: titre de l'email)
|
|
150
|
-
{ name: 'content', type: 'richtext', required: true }, // Contenu du message (localisable)
|
|
151
|
-
{ name: 'channels', type: 'relation', multiple: true, relation: 'channel' }, // Canaux de diffusion (email, SMS, forum, etc.)
|
|
152
|
-
{ name: 'status', type: 'enum', items: ['pending', 'sent', 'read', 'failed'] },
|
|
153
|
-
{ name: 'sentAt', type: 'datetime' },
|
|
154
|
-
{ name: 'readAt', type: 'datetime' },
|
|
155
|
-
{ name: 'type', type: 'string' }, // Type de notification (ex: "commande.miseAJour", "messageForum")
|
|
156
|
-
{ name: 'priority', type: 'enum', items: ['low', 'medium', 'high']}
|
|
157
|
-
]
|
|
158
|
-
},
|
|
159
|
-
alert: {
|
|
160
|
-
name: "alert",
|
|
161
|
-
"icon": "FaBell",
|
|
162
|
-
description: "Définit les règles pour les alertes et les insights automatiques.",
|
|
163
|
-
fields: [
|
|
164
|
-
{ name: "name", type: "string", required: true, asMain: true },
|
|
165
|
-
{ name: "targetModel", type: "model", required: true },
|
|
166
|
-
{ name: "description", type: "string_t", multiline: true },
|
|
167
|
-
{
|
|
168
|
-
name: "triggerCondition",
|
|
169
|
-
type: "code",
|
|
170
|
-
language: "json",
|
|
171
|
-
conditionBuilder: true,
|
|
172
|
-
targetModel: '$targetModel',
|
|
173
|
-
required: true,
|
|
174
|
-
hint: "La condition qui, si elle est remplie, déclenchera l'alerte."
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
name: "frequency",
|
|
178
|
-
type: "cronSchedule",
|
|
179
|
-
required: true,
|
|
180
|
-
cronMask: [false, true, true, true, true, true],
|
|
181
|
-
hint: "À quelle fréquence vérifier si la condition est remplie."
|
|
182
|
-
},
|
|
183
|
-
{ name: "isActive", type: "boolean", default: true },
|
|
184
|
-
{
|
|
185
|
-
name: "sendEmail",
|
|
186
|
-
type: "boolean",
|
|
187
|
-
default: false,
|
|
188
|
-
hint: "Cochez pour envoyer également une notification par e-mail."
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
name: "lastNotifiedAt",
|
|
192
|
-
type: "datetime",
|
|
193
|
-
required: false, // Important: ce champ est géré par le système
|
|
194
|
-
hint: "Timestamp de la dernière notification envoyée pour cette alerte."
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
name: "message",
|
|
198
|
-
type: "richtext_t",
|
|
199
|
-
required: false,
|
|
200
|
-
hint: "Message personnalisé pour l'e-mail. Si vide, un message par défaut sera utilisé. Vous pouvez utiliser les variables {count}, {alert.name}....",
|
|
201
|
-
condition: { $eq: ["$sendEmail", true] }
|
|
202
|
-
}
|
|
203
|
-
]
|
|
204
|
-
},
|
|
205
|
-
env: {
|
|
206
|
-
name: "env",
|
|
207
|
-
"icon": "FaCog",
|
|
208
|
-
description: "Définit les variables d'environnement qui seront accessibles dans vos scripts et webhooks.",
|
|
209
|
-
fields: [
|
|
210
|
-
{ name: "name", type: "string", required: true, unique: true, asMain: true },
|
|
211
|
-
{ name: "value", type: "string", anonymized: true, hiddenable: true }
|
|
212
|
-
]
|
|
213
|
-
},
|
|
214
|
-
webpage: {
|
|
215
|
-
name: 'webpage',
|
|
216
|
-
"icon": "FaFileAlt",
|
|
217
|
-
locked: true,
|
|
218
|
-
"description": "",
|
|
219
|
-
fields: [
|
|
220
|
-
{ name: 'title', type: 'string_t', required: true, color: '#659DE6' },
|
|
221
|
-
{ name: 'path', type: 'string', required: true, unique: true, color: '#DEDEDE' },
|
|
222
|
-
{ name: 'html', type: 'richtext' },
|
|
223
|
-
{ name: 'published', type: 'boolean', default: false },
|
|
224
|
-
{ name: 'inSitemap', type: 'boolean', default: true },
|
|
225
|
-
{ name: 'description', type: 'string' },
|
|
226
|
-
{ name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true },
|
|
227
|
-
{ name: 'image', type: 'url' },
|
|
228
|
-
{ name: 'category', type: 'relation', relation: 'taxonomy' }
|
|
229
|
-
]
|
|
230
|
-
},
|
|
231
|
-
content: {
|
|
232
|
-
name: 'content',
|
|
233
|
-
"icon": "FaFileAlt",
|
|
234
|
-
"description": "",
|
|
235
|
-
fields: [
|
|
236
|
-
{ name: 'lang', type: 'relation', relation: 'lang' },
|
|
237
|
-
{ name: 'title', type: 'string_t', required: true },
|
|
238
|
-
{ name: 'slug', type: 'string' },
|
|
239
|
-
{ name: 'html', type: 'richtext_t' },
|
|
240
|
-
{ name: 'image', type: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
|
|
241
|
-
{ name: 'published', type: 'boolean' },
|
|
242
|
-
{ name: 'publishedAt', type: 'datetime' },
|
|
243
|
-
{ name: 'author', type: 'relation', relation: 'user' },
|
|
244
|
-
{ name: 'category', type: 'relation', relation: 'taxonomy', "relationFilter": {
|
|
245
|
-
"path": [
|
|
246
|
-
"type"
|
|
247
|
-
],
|
|
248
|
-
"op": "$eq",
|
|
249
|
-
"value": "category"
|
|
250
|
-
} },
|
|
251
|
-
{ name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true, "relationFilter": {
|
|
252
|
-
"path": [
|
|
253
|
-
"type"
|
|
254
|
-
],
|
|
255
|
-
"op": "$eq",
|
|
256
|
-
"value": "keyword"
|
|
257
|
-
} },
|
|
258
|
-
{ name: 'order', type: 'number', step: 1, default: 0 },
|
|
259
|
-
{ name: 'inSitemap', type: 'boolean', default: false }
|
|
260
|
-
]
|
|
261
|
-
},
|
|
262
|
-
resource: {
|
|
263
|
-
name: 'resource',
|
|
264
|
-
"icon": "FaBoxOpen",
|
|
265
|
-
"description": "",
|
|
266
|
-
fields: [
|
|
267
|
-
{ name: "source", type: "url"},
|
|
268
|
-
{ name: "file", type: "file"}
|
|
269
|
-
]
|
|
270
|
-
},
|
|
271
|
-
taxonomy: {
|
|
272
|
-
name: 'taxonomy',
|
|
273
|
-
"icon": "FaTags",
|
|
274
|
-
"description": "",
|
|
275
|
-
fields: [
|
|
276
|
-
{ name: 'name', type: 'string_t', required: true, color: '#71A314' },
|
|
277
|
-
{ name: 'parent', type: 'relation', relation: 'taxonomy', color: '#233607' }, // Relation vers la taxonomie parente
|
|
278
|
-
{ name: 'type', type: 'enum', items: ['keyword', 'category'], color: '#BFBFBF' },
|
|
279
|
-
{ name: 'identifier', type: 'string' },
|
|
280
|
-
{ name: 'order', type: 'number', step: 1, default: 0 },
|
|
281
|
-
{ name: 'description', type: 'richtext' }
|
|
282
|
-
]
|
|
283
|
-
},
|
|
284
|
-
contact: {
|
|
285
|
-
locked: true,
|
|
286
|
-
name: 'contact',
|
|
287
|
-
"icon": "FaAddressBook",
|
|
288
|
-
"description": "",
|
|
289
|
-
fields: [
|
|
290
|
-
{ name: 'legalName', type: 'string', asMain: true, color: '#D9D9D9' },
|
|
291
|
-
{ name: 'firstName', type: 'string', asMain: true},
|
|
292
|
-
{ name: 'lastName', type: 'string', asMain: true },
|
|
293
|
-
{ name: 'email', type: 'email', color: '#F4ECE2' },
|
|
294
|
-
{ name: 'phone', type: 'phone', color: '#B4A693' },
|
|
295
|
-
{ name: 'location', type: 'relation', relation: 'location' }
|
|
296
|
-
]
|
|
297
|
-
},
|
|
298
|
-
|
|
299
|
-
location: {
|
|
300
|
-
"name": "location",
|
|
301
|
-
"icon": "FaMapMarkerAlt",
|
|
302
|
-
locked: true,
|
|
303
|
-
"description": "",
|
|
304
|
-
"fields": [
|
|
305
|
-
{
|
|
306
|
-
"name": "address_1",
|
|
307
|
-
"type": "string",
|
|
308
|
-
asMain: true,
|
|
309
|
-
color: '#D6D6D6'
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
"name": "address_2",
|
|
313
|
-
"type": "string"
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"name": "address_3",
|
|
317
|
-
"type": "string"
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
"name": "address_4",
|
|
321
|
-
"type": "string"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
"name": "city",
|
|
325
|
-
"type": "string",
|
|
326
|
-
asMain: true,
|
|
327
|
-
color: '#E63345'
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
"name": "postalCode",
|
|
331
|
-
"type": "string",
|
|
332
|
-
asMain: true,
|
|
333
|
-
color: '#8B1D1D'
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
"name": "region",
|
|
337
|
-
"type": "string"
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
"name": "country",
|
|
341
|
-
"type": "string",
|
|
342
|
-
color: "#4F80BF",
|
|
343
|
-
asMain: true
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
"name": "latitude",
|
|
347
|
-
"type": "number",
|
|
348
|
-
"unit": "°"
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
"name": "longitude",
|
|
352
|
-
"type": "number",
|
|
353
|
-
"unit": "°"
|
|
354
|
-
}
|
|
355
|
-
]
|
|
356
|
-
},
|
|
357
|
-
|
|
358
|
-
brand: {
|
|
359
|
-
name: 'brand',
|
|
360
|
-
"icon": "FaTrademark",
|
|
361
|
-
"description": "",
|
|
362
|
-
fields: [
|
|
363
|
-
{ name: 'name', type: 'string', required: true },
|
|
364
|
-
{ name: 'logo', type: 'file' },
|
|
365
|
-
{ name: 'company', type: 'relation', relation: 'contact' }
|
|
366
|
-
]
|
|
367
|
-
},
|
|
368
|
-
|
|
369
|
-
product: {
|
|
370
|
-
name: 'product',
|
|
371
|
-
"icon": "FaShoppingBag",
|
|
372
|
-
"description": "",
|
|
373
|
-
fields: [
|
|
374
|
-
{ name: 'name', type: 'string_t', required: true },
|
|
375
|
-
{ name: 'image', type: 'array', itemsType: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
|
|
376
|
-
{ name: 'description', type: 'richtext_t' },
|
|
377
|
-
{ name: 'price', type: 'number', required: true },
|
|
378
|
-
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
379
|
-
{ name: 'billingFrequency', type: 'enum', items: ['aucune', 'au mois', 'à l\'année'] },
|
|
380
|
-
{ name: 'slug', type: 'string', required: true, unique: true },
|
|
381
|
-
{ name: 'brand', type: 'relation', relation: 'brand' },
|
|
382
|
-
{ name: 'category', type: 'relation', relation: 'taxonomy' },
|
|
383
|
-
{ name: 'seoTitle', type: 'string_t' },
|
|
384
|
-
{ name: 'seoDescription', type: 'string_t' }
|
|
385
|
-
]
|
|
386
|
-
},
|
|
387
|
-
productVariant: {
|
|
388
|
-
name: 'productVariant',
|
|
389
|
-
"icon": "FaBox",
|
|
390
|
-
"description": "",
|
|
391
|
-
fields: [
|
|
392
|
-
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
393
|
-
{ name: 'size', type: 'string' },
|
|
394
|
-
{ name: 'color', type: 'color' },
|
|
395
|
-
{ name: 'sku', type: 'string', unique: true },
|
|
396
|
-
{ name: 'price', type: 'number', required: true },
|
|
397
|
-
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
398
|
-
{ name: 'stock', type: 'number', default: 0 },
|
|
399
|
-
{ name: 'description', type: 'richtext' },
|
|
400
|
-
{ name: 'image', type: 'url' }
|
|
401
|
-
]
|
|
402
|
-
},
|
|
403
|
-
cart: {
|
|
404
|
-
name: 'cart',
|
|
405
|
-
"icon": "FaShoppingCart",
|
|
406
|
-
"description": "",
|
|
407
|
-
fields: [
|
|
408
|
-
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
409
|
-
{ name: 'items', type: 'relation', relation: 'cartItem', multiple: true },
|
|
410
|
-
{ name: 'creationDate', type: 'datetime', required: true },
|
|
411
|
-
{ name: 'lastUpdate', type: 'datetime', required: true },
|
|
412
|
-
{ name: 'active', type: 'boolean', default: true }
|
|
413
|
-
]
|
|
414
|
-
},
|
|
415
|
-
cartItem: {
|
|
416
|
-
name: 'cartItem',
|
|
417
|
-
"icon": "FaShoppingBasket",
|
|
418
|
-
"description": "",
|
|
419
|
-
fields: [
|
|
420
|
-
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
421
|
-
{ name: 'quantity', type: 'number', required: true, min: 1, step: 1 },
|
|
422
|
-
{ name: 'variant', type: 'relation', relation: 'productVariant' } // Optionnel, si vous avez des variantes
|
|
423
|
-
]
|
|
424
|
-
},
|
|
425
|
-
discount: {
|
|
426
|
-
name: "discount",
|
|
427
|
-
"icon": "FaTicketAlt",
|
|
428
|
-
locked: true,
|
|
429
|
-
"description": "",
|
|
430
|
-
fields: [
|
|
431
|
-
{ "name": "code", "type": "string", "required": true, "unique": true },
|
|
432
|
-
{ "name": "productSelection", "type": "relation", "relation": "product", "required": false, multiple: true },
|
|
433
|
-
{ "name": "description", "type": "richtext" },
|
|
434
|
-
{ "name": "percentAmount", "type": "number", "unit": "%", default: null, min: 0 },
|
|
435
|
-
{ "name": "fixedAmount", "type": "number", default: null, min: 0 },
|
|
436
|
-
{ "name": "minAmount", "type": "number", "unit": "€", default: null, min: 0 }, // Montant minimum pour la promotion
|
|
437
|
-
{ "name": "minProductQuantity", "type": "number", min: 0 }, // Montant minimum pour la promotion
|
|
438
|
-
{ "name": "freeProductQuantity", "type": "number", default: null, min: 0 }, // Quantité de produits offerts
|
|
439
|
-
{ "name": "startDate", "type": "datetime" },
|
|
440
|
-
{ "name": "endDate", "type": "datetime" }
|
|
441
|
-
]
|
|
442
|
-
},
|
|
443
|
-
order: {
|
|
444
|
-
name: "order",
|
|
445
|
-
"icon": "FaClipboardList",
|
|
446
|
-
locked: true,
|
|
447
|
-
"description": "",
|
|
448
|
-
fields: [
|
|
449
|
-
{ "name": "orderId", "type": "string", "required": true, "unique": true },
|
|
450
|
-
{ "name": "orderDate", "type": "datetime" },
|
|
451
|
-
{ "name": "status", "type": "enum", items: ["pending", "processing", "shipped", "delivered", "cancelled"] },
|
|
452
|
-
{ "name": "products", "type": "relation", "relation": "cartItem", "required": true, multiple: true },
|
|
453
|
-
{ "name": "customer", "type": "relation", relation: 'user' }, // Relation vers le modèle 'user'
|
|
454
|
-
{ "name": "totalAmount", "type": "number", "required": true },
|
|
455
|
-
{ "name": "paymentIntentId", "type": "string", "hint": "Stripe Payment Intent ID for this order." },
|
|
456
|
-
{ "name": "currency", "type": "relation", "relation": "currency" },
|
|
457
|
-
{ "name": "paymentMethod", "type": "string" },
|
|
458
|
-
{ "name": "shippingAddress", "type": "relation", "relation": "location" },
|
|
459
|
-
{ "name": "billingAddress", "type": "relation", "relation": "location" },
|
|
460
|
-
{ "name": "shippedDate", "type": "datetime" },
|
|
461
|
-
{ "name": "deliveryDate", "type": "datetime" },
|
|
462
|
-
{ "name": "discount", "type": "relation", relation: 'discount' } // Relation vers le modèle 'promotion'
|
|
463
|
-
]
|
|
464
|
-
},
|
|
465
|
-
invoice: {
|
|
466
|
-
name: 'invoice',
|
|
467
|
-
"icon": "FaFileInvoice",
|
|
468
|
-
"description": "",
|
|
469
|
-
fields: [
|
|
470
|
-
{ name: 'order', type: 'relation', relation: 'order', required: true },
|
|
471
|
-
{ name: 'invoiceId', type: 'string', required: true, unique: true },
|
|
472
|
-
{ name: 'invoiceDate', type: 'datetime', required: true },
|
|
473
|
-
{ name: 'dueDate', type: 'datetime' },
|
|
474
|
-
{ name: 'status', type: 'enum', items: ['paid', 'unpaid', 'partially_paid', 'cancelled'] }
|
|
475
|
-
]
|
|
476
|
-
},
|
|
477
|
-
userSubscription: {
|
|
478
|
-
name: 'userSubscription',
|
|
479
|
-
"icon": "FaCalendarCheck",
|
|
480
|
-
"description": "",
|
|
481
|
-
locked: true,
|
|
482
|
-
fields: [
|
|
483
|
-
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
484
|
-
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
485
|
-
{ name: 'startDate', type: 'datetime', required: true },
|
|
486
|
-
{ name: 'endDate', type: 'datetime' },
|
|
487
|
-
{ name: 'price', type: 'number', required: true },
|
|
488
|
-
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
489
|
-
{ name: 'paymentMethod', type: 'enum', items: ['bank_card', 'SEPA_mandate', 'cash', 'check', 'other'] },
|
|
490
|
-
{ name: 'status', type: 'enum', items: ['active', 'inactive', 'cancelled', 'expired', 'pending'] },
|
|
491
|
-
{ name: 'billingCycleAnchor', type: 'datetime' },
|
|
492
|
-
{ name: 'nextBillingDate', type: 'datetime' },
|
|
493
|
-
{ name: 'lastBillingDate', type: 'datetime' },
|
|
494
|
-
{ name: 'cancelReason', type: 'string' },
|
|
495
|
-
{ name: 'autoRenew', type: 'boolean', default: false }
|
|
496
|
-
]
|
|
497
|
-
},
|
|
498
|
-
stock: {
|
|
499
|
-
name: 'stock',
|
|
500
|
-
"icon": "FaWarehouse",
|
|
501
|
-
"description": "",
|
|
502
|
-
fields: [
|
|
503
|
-
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
504
|
-
{ name: 'variant', type: 'relation', relation: 'productVariant' }, // Optionnel
|
|
505
|
-
{ name: 'warehouse', type: 'relation', relation: 'warehouse', required: true },
|
|
506
|
-
{ name: 'available', type: 'number', default: 0 },
|
|
507
|
-
{ name: 'reserved', type: 'number', default: 0 } // Quantité réservée (pour les commandes en cours)
|
|
508
|
-
]
|
|
509
|
-
},
|
|
510
|
-
stockAlert: {
|
|
511
|
-
name: 'stockAlert',
|
|
512
|
-
"icon": "FaExclamationTriangle",
|
|
513
|
-
"description": "",
|
|
514
|
-
fields: [
|
|
515
|
-
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
516
|
-
{ name: 'stock', type: 'relation', relation: 'stock', required: true },
|
|
517
|
-
{ name: 'threshold', type: 'number', required: true, min: 0 }
|
|
518
|
-
]
|
|
519
|
-
// how to implement unique fields on COMBINATION of multiple columns ?
|
|
520
|
-
},
|
|
521
|
-
shipment: {
|
|
522
|
-
name: 'shipment',
|
|
523
|
-
"icon": "FaTruck",
|
|
524
|
-
"description": "",
|
|
525
|
-
fields: [
|
|
526
|
-
{ name: 'order', type: 'relation', relation: 'order', required: true },
|
|
527
|
-
{ name: 'trackingNumber', type: 'string' },
|
|
528
|
-
{ name: 'carrier', type: 'string' },
|
|
529
|
-
{ name: 'status', type: 'enum', items: ['pending', 'in_transit', 'delivered', 'issue'] },
|
|
530
|
-
{ name: 'estimatedDeliveryDate', type: 'datetime' },
|
|
531
|
-
{ name: 'actualDeliveryDate', type: 'datetime' }
|
|
532
|
-
]
|
|
533
|
-
},
|
|
534
|
-
warehouse: {
|
|
535
|
-
name: 'warehouse',
|
|
536
|
-
"description": "",
|
|
537
|
-
"icon": "FaWarehouse",
|
|
538
|
-
fields: [
|
|
539
|
-
{ name: 'name', type: 'string_t', required: true },
|
|
540
|
-
{ name: 'location', type: 'relation', relation: 'location' },
|
|
541
|
-
{ name: 'capacity', type: 'number' }
|
|
542
|
-
]
|
|
543
|
-
},
|
|
544
|
-
'return': {
|
|
545
|
-
name: "return",
|
|
546
|
-
"description": "",
|
|
547
|
-
"icon": "FaUndo",
|
|
548
|
-
fields: [
|
|
549
|
-
{ "name": "order", "type": "relation", "relation": "order", "required": true },
|
|
550
|
-
{ "name": "user", "type": "relation", relation: "user" },
|
|
551
|
-
{ "name": "reason", "type": "string", maxlength: 2048, required: true },
|
|
552
|
-
{ "name": "channel", "type": "relation", relation: 'channel' },
|
|
553
|
-
{ "name": "status", "type": "enum", items: ["pending", "approved", "refunded", "refused"] },
|
|
554
|
-
{ name: 'amount', type: 'number', min: 0 },
|
|
555
|
-
{ name: 'currency', type: 'relation', relation: 'currency' },
|
|
556
|
-
{ name: 'refundDate', type: 'datetime' }
|
|
557
|
-
]
|
|
558
|
-
},
|
|
559
|
-
returnItem: {
|
|
560
|
-
name: 'returnItem',
|
|
561
|
-
"icon": "FaBoxOpen",
|
|
562
|
-
"description": "",
|
|
563
|
-
fields: [
|
|
564
|
-
{ name: 'return', type: 'relation', relation: 'return', required: true },
|
|
565
|
-
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
566
|
-
{ name: 'variant', type: 'relation', relation: 'productVariant' },
|
|
567
|
-
{ name: 'quantity', type: 'number', required: true, min: 1 },
|
|
568
|
-
{ name: 'condition', type: 'enum', items: ['new', 'very_good', 'good', 'degraded', 'damaged', 'unusable'] }
|
|
569
|
-
]
|
|
570
|
-
},
|
|
571
|
-
ticket: {
|
|
572
|
-
name: 'ticket',
|
|
573
|
-
"icon": "FaTicketAlt",
|
|
574
|
-
"description": "",
|
|
575
|
-
locked: true,
|
|
576
|
-
fields: [
|
|
577
|
-
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
578
|
-
{ name: 'order', type: 'relation', relation: 'order' },
|
|
579
|
-
{ name: 'channel', type: 'relation', relation: 'channel' },
|
|
580
|
-
{ name: 'parent', type: 'relation', relation: 'ticket' },
|
|
581
|
-
{ name: 'subject', type: 'string', required: true },
|
|
582
|
-
{ name: 'message', type: 'richtext', required: true },
|
|
583
|
-
{ name: 'status', type: 'enum', items: ['opened', 'in_progress', 'closed'] },
|
|
584
|
-
{ name: 'priority', type: 'enum', items: ['low', 'medium', 'high', 'urgent'] },
|
|
585
|
-
{ name: 'assignedTo', type: 'relation', relation: 'user' },
|
|
586
|
-
{ name: 'createdAt', type: 'datetime', required: true }
|
|
587
|
-
]
|
|
588
|
-
},
|
|
589
|
-
review: {
|
|
590
|
-
name: "review",
|
|
591
|
-
"icon": "FaStar",
|
|
592
|
-
"description": "",
|
|
593
|
-
fields: [
|
|
594
|
-
{ "name": "user", "type": "relation", relation: "user" },
|
|
595
|
-
{ "name": "product", "type": "relation", relation: 'product' },
|
|
596
|
-
{ "name": "productVariant", "type": "relation", relation: 'productVariant' },
|
|
597
|
-
{ "name": "comment", "type": "richtext", maxlength: 2048, required: true },
|
|
598
|
-
{ "name": "score", "type": "number" },
|
|
599
|
-
{ "name": "publishedAt", "type": "datetime", required: true }
|
|
600
|
-
]
|
|
601
|
-
},
|
|
602
|
-
device: {
|
|
603
|
-
name: "device",
|
|
604
|
-
"icon": "FaMobile",
|
|
605
|
-
"description": "",
|
|
606
|
-
fields: [
|
|
607
|
-
{ "name": "location", "type": "relation", relation: 'location' },
|
|
608
|
-
{ "name": "lastLocationUpdate", "type": "datetime" }
|
|
609
|
-
]
|
|
610
|
-
},
|
|
611
|
-
// Modèle pour l'exercice comptable et l'entreprise
|
|
612
|
-
accountingExercise: {
|
|
613
|
-
name: 'accountingExercise',
|
|
614
|
-
"icon": "FaBook",
|
|
615
|
-
description: "Représente un exercice comptable pour une entreprise donnée.",
|
|
616
|
-
fields: [
|
|
617
|
-
{ name: 'name', type: 'string_t', 'required': true, unique: true, hint: "Intitulé de l'exercice comptable" },
|
|
618
|
-
{ name: 'companyContact', type: 'relation', relation: 'contact', 'required': true, hint: "Désignation de l'entreprise" },
|
|
619
|
-
{ name: 'companyIdentifier', type: 'string', asMain: true, hint: "SIRET de l'entreprise", unique: true },
|
|
620
|
-
{ name: 'startDate', type: 'date', required: true, asMain: true, hint: "Date de début de l'exercice" },
|
|
621
|
-
{ name: 'endDate', type: 'date', required: true, asMain: true, hint: "Date de clôture de l'exercice" }
|
|
622
|
-
]
|
|
623
|
-
},
|
|
624
|
-
|
|
625
|
-
// Modèle pour définir la structure des lignes comptables (le "plan")
|
|
626
|
-
accountingLineItem: {
|
|
627
|
-
name: 'accountingLineItem',
|
|
628
|
-
"icon": "FaListAlt",
|
|
629
|
-
description: "Définit une ligne/catégorie dans un document comptable.",
|
|
630
|
-
locked: true, // Probablement géré par l'application, pas par l'utilisateur final
|
|
631
|
-
fields: [
|
|
632
|
-
{ name: 'accountingExercise', type: 'relation', required: true, unique: true, relation: "accountingExercise" },
|
|
633
|
-
{ name: 'code', type: 'string', required: true, unique: true, hint: "Code unique de la ligne (ex: AA, FB, HA)" },
|
|
634
|
-
{ name: 'label', type: 'string_t', required: true, hint: "Libellé de la ligne (ex: Frais d'établissement)" },
|
|
635
|
-
{
|
|
636
|
-
name: 'documentType', type: 'enum', required: true,
|
|
637
|
-
items: ['bilan_actif', 'bilan_passif', 'compte_resultat', 'immobilisations', 'amortissements', 'provisions', 'creances_dettes',
|
|
638
|
-
'deficits',
|
|
639
|
-
'plus_moins_values',
|
|
640
|
-
'effectifs_valeur_ajoutee',
|
|
641
|
-
'capital_social',
|
|
642
|
-
'filiales_participations',
|
|
643
|
-
'resultat_fiscal']
|
|
644
|
-
},
|
|
645
|
-
{ name: 'section', type: 'string_t', required: true, hint: "Section principale (ex: ACTIF IMMOBILISÉ)" },
|
|
646
|
-
{ name: 'subSection', type: 'string_t', hint: "Sous-section (ex: IMMOBILISATIONS INCORPORELLES)" },
|
|
647
|
-
{ name: 'order', type: 'number', hint: "Ordre d'affichage dans la section/sous-section" },
|
|
648
|
-
{ name: 'calculationFormula', type: 'string', hint: "Formule de calcul (si applicable)" },
|
|
649
|
-
{
|
|
650
|
-
name: 'values', type: 'array', itemsType: 'number', required: true,
|
|
651
|
-
hint: "Valeurs de la ligne comptable"
|
|
652
|
-
},
|
|
653
|
-
{ name: 'notes', type: 'richtext', hint: "Notes ou renvois (ex: (1), (3))" }
|
|
654
|
-
]
|
|
655
|
-
},
|
|
656
|
-
accountingEntry: {
|
|
657
|
-
"name": "accountingEntry",
|
|
658
|
-
"icon": "FaPenAlt",
|
|
659
|
-
"description": "",
|
|
660
|
-
"fields": [
|
|
661
|
-
{
|
|
662
|
-
"name": "exercise",
|
|
663
|
-
"type": "relation",
|
|
664
|
-
"relation": "accountingExercise",
|
|
665
|
-
"required": true
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
"name": "label",
|
|
669
|
-
"type": "string",
|
|
670
|
-
"required": true,
|
|
671
|
-
"asMain": true,
|
|
672
|
-
"maxlength": 255
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
"name": "entryDate",
|
|
676
|
-
"type": "date",
|
|
677
|
-
"required": true
|
|
678
|
-
},
|
|
679
|
-
{
|
|
680
|
-
"name": "amount",
|
|
681
|
-
"type": "number",
|
|
682
|
-
"default": 0
|
|
683
|
-
},
|
|
684
|
-
{
|
|
685
|
-
"name": "currency",
|
|
686
|
-
"type": "relation",
|
|
687
|
-
"relation": "currency",
|
|
688
|
-
"required": true
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
"name": "referenceNumber",
|
|
692
|
-
"type": "string",
|
|
693
|
-
"maxlength": 100
|
|
694
|
-
},
|
|
695
|
-
{
|
|
696
|
-
"name": "notes",
|
|
697
|
-
"type": "richtext"
|
|
698
|
-
},
|
|
699
|
-
{
|
|
700
|
-
"name": "status",
|
|
701
|
-
"type": "enum",
|
|
702
|
-
"items": ["draft", "validated", "cancelled"],
|
|
703
|
-
"default": "brouillon"
|
|
704
|
-
},
|
|
705
|
-
{
|
|
706
|
-
"name": "createdBy",
|
|
707
|
-
"type": "relation",
|
|
708
|
-
"relation": "user"
|
|
709
|
-
},
|
|
710
|
-
{
|
|
711
|
-
"name": "validatedBy",
|
|
712
|
-
"type": "relation",
|
|
713
|
-
"relation": "user"
|
|
714
|
-
},
|
|
715
|
-
{
|
|
716
|
-
"name": "validationDate",
|
|
717
|
-
"type": "datetime"
|
|
718
|
-
},
|
|
719
|
-
{
|
|
720
|
-
"name": "attachments",
|
|
721
|
-
"type": "array",
|
|
722
|
-
"itemsType": "file"
|
|
723
|
-
}
|
|
724
|
-
]
|
|
725
|
-
},
|
|
726
|
-
employee: {
|
|
727
|
-
"name": "employee",
|
|
728
|
-
"icon": "FaUserTie",
|
|
729
|
-
"description": "",
|
|
730
|
-
"fields": [
|
|
731
|
-
{
|
|
732
|
-
"name": "employeeId",
|
|
733
|
-
"type": "string",
|
|
734
|
-
"required": true,
|
|
735
|
-
"unique": true
|
|
736
|
-
},
|
|
737
|
-
{
|
|
738
|
-
"name": "personalInfo",
|
|
739
|
-
"type": "relation",
|
|
740
|
-
"relation": "user",
|
|
741
|
-
"required": true
|
|
742
|
-
},
|
|
743
|
-
{
|
|
744
|
-
"name": "jobTitle",
|
|
745
|
-
"type": "string",
|
|
746
|
-
"required": true
|
|
747
|
-
},
|
|
748
|
-
{
|
|
749
|
-
"name": "department",
|
|
750
|
-
"type": "string"
|
|
751
|
-
},
|
|
752
|
-
{
|
|
753
|
-
"name": "manager",
|
|
754
|
-
"type": "relation",
|
|
755
|
-
"relation": "employee"
|
|
756
|
-
},
|
|
757
|
-
{
|
|
758
|
-
"name": "workLocation",
|
|
759
|
-
"type": "relation",
|
|
760
|
-
"relation": "location"
|
|
761
|
-
},
|
|
762
|
-
{
|
|
763
|
-
"name": "employmentType",
|
|
764
|
-
"type": "enum",
|
|
765
|
-
"items": ["full_time", "part_time", "contractor", "intern", "temporary"]
|
|
766
|
-
},
|
|
767
|
-
{
|
|
768
|
-
"name": "emergencyContact",
|
|
769
|
-
"type": "relation",
|
|
770
|
-
"relation": "contact"
|
|
771
|
-
},
|
|
772
|
-
{
|
|
773
|
-
"name": "homeAddress",
|
|
774
|
-
"type": "relation",
|
|
775
|
-
"relation": "location"
|
|
776
|
-
},
|
|
777
|
-
{
|
|
778
|
-
"name": "dateOfBirth",
|
|
779
|
-
"type": "date"
|
|
780
|
-
},
|
|
781
|
-
{
|
|
782
|
-
"name": "nationality",
|
|
783
|
-
"type": "string"
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
"name": "nationalId",
|
|
787
|
-
"type": "string"
|
|
788
|
-
},
|
|
789
|
-
{
|
|
790
|
-
"name": "socialSecurityNumber",
|
|
791
|
-
"type": "string"
|
|
792
|
-
},
|
|
793
|
-
{
|
|
794
|
-
"name": "taxId",
|
|
795
|
-
"type": "string"
|
|
796
|
-
},
|
|
797
|
-
{
|
|
798
|
-
"name": "startDate",
|
|
799
|
-
"type": "date",
|
|
800
|
-
"required": true
|
|
801
|
-
},
|
|
802
|
-
{
|
|
803
|
-
"name": "endDate",
|
|
804
|
-
"type": "date"
|
|
805
|
-
},
|
|
806
|
-
{
|
|
807
|
-
"name": "contractType",
|
|
808
|
-
"type": "string"
|
|
809
|
-
},
|
|
810
|
-
{
|
|
811
|
-
"name": "salary",
|
|
812
|
-
"type": "number"
|
|
813
|
-
},
|
|
814
|
-
{
|
|
815
|
-
"name": "salaryCurrency",
|
|
816
|
-
"type": "relation",
|
|
817
|
-
"relation": "currency"
|
|
818
|
-
},
|
|
819
|
-
{
|
|
820
|
-
"name": "payFrequency",
|
|
821
|
-
"type": "enum",
|
|
822
|
-
"items": ["weekly", "bi_weekly", "monthly"]
|
|
823
|
-
},
|
|
824
|
-
{
|
|
825
|
-
"name": "bankAccountNumber",
|
|
826
|
-
"type": "string"
|
|
827
|
-
},
|
|
828
|
-
{
|
|
829
|
-
"name": "bankName",
|
|
830
|
-
"type": "string"
|
|
831
|
-
},
|
|
832
|
-
{
|
|
833
|
-
"name": "iban",
|
|
834
|
-
"type": "string"
|
|
835
|
-
},
|
|
836
|
-
{
|
|
837
|
-
"name": "swiftBic",
|
|
838
|
-
"type": "string"
|
|
839
|
-
},
|
|
840
|
-
{
|
|
841
|
-
"name": "workPermitNumber",
|
|
842
|
-
"type": "string"
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
"name": "workPermitExpiry",
|
|
846
|
-
"type": "date"
|
|
847
|
-
},
|
|
848
|
-
{
|
|
849
|
-
"name": "visaType",
|
|
850
|
-
"type": "string"
|
|
851
|
-
},
|
|
852
|
-
{
|
|
853
|
-
"name": "visaExpiry",
|
|
854
|
-
"type": "date"
|
|
855
|
-
},
|
|
856
|
-
{
|
|
857
|
-
"name": "skills",
|
|
858
|
-
"type": "array",
|
|
859
|
-
"itemsType": "string"
|
|
860
|
-
},
|
|
861
|
-
{
|
|
862
|
-
"name": "notes",
|
|
863
|
-
"type": "richtext"
|
|
864
|
-
}
|
|
865
|
-
]
|
|
866
|
-
},
|
|
867
|
-
workflow: {
|
|
868
|
-
name: 'workflow',
|
|
869
|
-
"icon": "FaProjectDiagram",
|
|
870
|
-
description: "Defines an automated process.",
|
|
871
|
-
fields: [
|
|
872
|
-
{ name: 'name', type: 'string_t', required: true, hint: "Unique name for the workflow (e.g., 'Order Validation', 'Low Stock Notification')." },
|
|
873
|
-
{ name: 'description', type: 'richtext', hint: "Detailed explanation of the workflow's purpose." },
|
|
874
|
-
{ name: 'startStep', type: 'relation', relation: 'workflowStep', required: false, hint: "The first step to execute when the workflow starts." }
|
|
875
|
-
]
|
|
876
|
-
},
|
|
877
|
-
workflowTrigger: {
|
|
878
|
-
name: 'workflowTrigger',
|
|
879
|
-
"icon": "FaPlay",
|
|
880
|
-
description: "Represents an event that can initiate a workflow.",
|
|
881
|
-
fields: [
|
|
882
|
-
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
|
|
883
|
-
{ name: 'name', type: 'string_t', required: true, unique: true, hint: "Descriptive name for the trigger (e.g., 'New Order Created', 'Stock < 5', 'Monday 9 AM Report')." },
|
|
884
|
-
{
|
|
885
|
-
name: 'type',
|
|
886
|
-
type: 'enum',
|
|
887
|
-
items: ['manual', 'scheduled'],
|
|
888
|
-
required: true
|
|
889
|
-
},
|
|
890
|
-
{
|
|
891
|
-
name: 'onEvent',
|
|
892
|
-
type: 'enum',
|
|
893
|
-
items: ['DataAdded', 'DataEdited', 'DataDeleted', 'ModelAdded', 'ModelEdited', 'ModelDeleted'],
|
|
894
|
-
condition: { $eq: ["$type", "manual"] }
|
|
895
|
-
},
|
|
896
|
-
{ name: 'targetModel', type: 'model', condition: { // Condition pour afficher le champ
|
|
897
|
-
$and: [
|
|
898
|
-
{$eq: ["$type", "manual"]},
|
|
899
|
-
{
|
|
900
|
-
$or: [
|
|
901
|
-
{
|
|
902
|
-
{
|
|
903
|
-
{
|
|
904
|
-
]
|
|
905
|
-
}
|
|
906
|
-
]
|
|
907
|
-
}},
|
|
908
|
-
{ name: 'dataFilter', type: 'code', language: 'json', targetModel: '$targetModel', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action.",
|
|
909
|
-
condition: { // Condition pour afficher le champ
|
|
910
|
-
$and: [
|
|
911
|
-
{$eq: ["$type", "manual"]},
|
|
912
|
-
{
|
|
913
|
-
$or: [
|
|
914
|
-
{
|
|
915
|
-
{
|
|
916
|
-
{
|
|
917
|
-
]
|
|
918
|
-
}
|
|
919
|
-
]
|
|
920
|
-
}
|
|
921
|
-
},
|
|
922
|
-
{ name: 'env', type: 'code', language: 'json', hint: "Environment variables (JSON key/value pairs)",default: {} },
|
|
923
|
-
{ name: 'isActive', type: 'boolean' },
|
|
924
|
-
{ name: 'cronExpression', type: 'cronSchedule', cronMask:[false, true, true, true, true, true], hint: "Cron expression for scheduling (e.g., '0 9 * * 1' for Monday 9 AM) (used by Scheduled type).",
|
|
925
|
-
condition:
|
|
926
|
-
{$eq: ["$type", "scheduled"]}}
|
|
927
|
-
]
|
|
928
|
-
},
|
|
929
|
-
workflowStep: {
|
|
930
|
-
name: 'workflowStep',
|
|
931
|
-
"icon": "FaStepForward",
|
|
932
|
-
description: "A single step within a workflow process.",
|
|
933
|
-
fields: [
|
|
934
|
-
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
|
|
935
|
-
{ name: 'name', type: 'string_t', hint: "Optional descriptive name for the step (e.g., 'Check Inventory', 'Send Confirmation Email')." },
|
|
936
|
-
{ name: 'conditions', type: 'code', language: 'json', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action." },
|
|
937
|
-
{ name: 'actions', type: 'relation', relation: 'workflowAction', multiple: true, required: true, hint: "The main actions performed by this step." },
|
|
938
|
-
{ name: 'onSuccessStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if this step's action succeeds." },
|
|
939
|
-
{ name: 'onFailureStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if conditions fail or the action fails." },
|
|
940
|
-
{ name: 'isTerminal', type: 'boolean', default: false, hint: "Indicates if this step marks the end of a workflow path." }
|
|
941
|
-
]
|
|
942
|
-
},
|
|
943
|
-
workflowAction: {
|
|
944
|
-
name: 'workflowAction',
|
|
945
|
-
"icon": "FaCogs",
|
|
946
|
-
description: "Defines a specific operation to be performed by a workflow step.",
|
|
947
|
-
fields: [
|
|
948
|
-
{ name: 'name', type: 'string_t', required: true, hint: "Name of the action (e.g., 'Update Order Status', 'Send Email', 'Call Payment API')." },
|
|
949
|
-
{
|
|
950
|
-
name: 'type',
|
|
951
|
-
type: 'enum',
|
|
952
|
-
required: true,
|
|
953
|
-
items: ['UpdateData', 'CreateData', 'DeleteData', 'ExecuteScript', 'HttpRequest', 'SendEmail', 'Wait', 'GenerateAIContent', 'ExecuteServiceFunction'],
|
|
954
|
-
hint: "The type of operation to perform."
|
|
955
|
-
},
|
|
956
|
-
// For UpdateData / CreateData / DeleteData
|
|
957
|
-
{ name: 'targetModel', condition: {
|
|
958
|
-
$or: [
|
|
959
|
-
{$eq: ["$type", "CreateData"]},
|
|
960
|
-
{$eq: ["$type", "UpdateData"]},
|
|
961
|
-
{$eq: ["$type", "DeleteData"]}
|
|
962
|
-
]
|
|
963
|
-
}, type: 'model', hint: "Model to target" },
|
|
964
|
-
|
|
965
|
-
// For UpdateData / DeleteData
|
|
966
|
-
{ name: 'targetSelector', targetModel: "$targetModel", conditionBuilder: true, condition: {
|
|
967
|
-
$or: [
|
|
968
|
-
{$eq: ["$type", "UpdateData"]},
|
|
969
|
-
{$eq: ["$type", "DeleteData"]}
|
|
970
|
-
]
|
|
971
|
-
}, type: 'code', language: 'json', hint: "Expression to filter to the target document(s)." },
|
|
972
|
-
|
|
973
|
-
// For UpdateData
|
|
974
|
-
{ name: 'fieldsToUpdate', condition: {$eq: ["$type", "UpdateData"]}, type: 'code', language: 'json', default: {}, hint: "Key-value pairs of fields to update (e.g., { status: 'Validé', lastUpdated: '{now}' })" },
|
|
975
|
-
|
|
976
|
-
// For CreateData
|
|
977
|
-
{ name: 'dataToCreate', condition: {$eq: ["$type", "CreateData"]}, type: 'code', language: 'json', default: {}, hint: "Object template for the new document to create" },
|
|
978
|
-
|
|
979
|
-
// For HttpRequest
|
|
980
|
-
{ name: 'url', condition: {$eq: ["$type", "HttpRequest"]}, type: 'string', hint: "The URL to call." },
|
|
981
|
-
{ name: 'method', condition: {$eq: ["$type", "HttpRequest"]}, type: 'enum', items: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST', hint: "HTTP method." },
|
|
982
|
-
{ name: 'headers', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "HTTP headers as key-value pairs." },
|
|
983
|
-
{ name: 'body', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "Request body, can include variables." },
|
|
984
|
-
|
|
985
|
-
// For SendEmail
|
|
986
|
-
{
|
|
987
|
-
name: 'emailRecipients',
|
|
988
|
-
type: 'array',
|
|
989
|
-
itemsType: 'string',
|
|
990
|
-
condition: { $eq: ["$type", "SendEmail"] },
|
|
991
|
-
hint: "Destinataire(s) de l'e-mail. Peut être une adresse, plusieurs adresses séparées par des virgules, ou une variable comme {triggerData.client.email}."
|
|
992
|
-
},
|
|
993
|
-
{
|
|
994
|
-
name: 'emailSubject',
|
|
995
|
-
type: 'string',
|
|
996
|
-
condition: { $eq: ["$type", "SendEmail"] },
|
|
997
|
-
hint: "Sujet de l'e-mail. Peut contenir des variables."
|
|
998
|
-
},
|
|
999
|
-
{
|
|
1000
|
-
name: 'emailContent',
|
|
1001
|
-
type: 'richtext',
|
|
1002
|
-
condition: { $eq: ["$type", "SendEmail"] },
|
|
1003
|
-
hint: "Contenu de l'e-mail. Peut contenir des variables et du HTML."
|
|
1004
|
-
},
|
|
1005
|
-
|
|
1006
|
-
// For Wait
|
|
1007
|
-
{ name: 'duration', condition: {$eq: ["$type", "Wait"]}, type: 'number', hint: "Duration to wait." },
|
|
1008
|
-
{ name: 'durationUnit', condition:{$eq: ["$type", "Wait"]}, type: 'enum', items: ['milliseconds', 'seconds', 'minutes', 'hours', 'days'], default: 'seconds', hint: "Unit for the duration." },
|
|
1009
|
-
|
|
1010
|
-
// For GenerateAIContents
|
|
1011
|
-
{
|
|
1012
|
-
name: 'aiProvider',
|
|
1013
|
-
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1014
|
-
type: 'enum',
|
|
1015
|
-
items: ['OpenAI', 'GoogleGemini'], // Extensible avec d'autres fournisseurs
|
|
1016
|
-
hint: "Le fournisseur de LLM à utiliser."
|
|
1017
|
-
},
|
|
1018
|
-
{
|
|
1019
|
-
name: 'aiModel',
|
|
1020
|
-
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1021
|
-
type: 'string',
|
|
1022
|
-
default: 'gpt-4o-mini', // Un défaut raisonnable
|
|
1023
|
-
hint: "Le modèle spécifique à utiliser (ex: gpt-4o-mini, gemini-1.5-pro-latest)."
|
|
1024
|
-
},
|
|
1025
|
-
{
|
|
1026
|
-
name: 'prompt',
|
|
1027
|
-
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1028
|
-
type: 'richtext', // richtext est bien pour les longs prompts
|
|
1029
|
-
hint: "Le modèle de prompt. Utilise des variables comme {triggerData.field} ou {context.variable}."
|
|
1030
|
-
},
|
|
1031
|
-
|
|
1032
|
-
// For ExecuteScript
|
|
1033
|
-
{ name: 'script', condition: {$eq: ["$type", "ExecuteScript"]}, type: 'code', language: 'javascript', hint: "The script to execute." },
|
|
1034
|
-
|
|
1035
|
-
// For ExecuteServiceFunction
|
|
1036
|
-
{ name: 'serviceName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the registered service to call (e.g., 'stripe')." },
|
|
1037
|
-
{ name: 'functionName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the function to execute within the service." },
|
|
1038
|
-
{ name: 'args', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'code', language: 'json', default: [], hint: "An array of arguments to pass to the function. Can include variables." }
|
|
1039
|
-
|
|
1040
|
-
]
|
|
1041
|
-
},
|
|
1042
|
-
|
|
1043
|
-
workflowRun: {
|
|
1044
|
-
name: 'workflowRun',
|
|
1045
|
-
"icon": "FaRunning",
|
|
1046
|
-
description: "Tracks a specific execution instance of a workflow.",
|
|
1047
|
-
fields: [
|
|
1048
|
-
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow definition that was executed." },
|
|
1049
|
-
{ name: 'contextData', type: 'code', language: 'json',default: {}, hint: "Snapshot of the data or event that triggered this run." },
|
|
1050
|
-
{
|
|
1051
|
-
name: 'status',
|
|
1052
|
-
type: 'enum',
|
|
1053
|
-
required: true,
|
|
1054
|
-
items: ['pending', 'running', 'completed', 'failed', 'waiting', 'cancelled'],
|
|
1055
|
-
default: 'pending',
|
|
1056
|
-
hint: "The current status of the workflow execution."
|
|
1057
|
-
},
|
|
1058
|
-
{ name: 'stepExecutionsCount', type: 'object' },
|
|
1059
|
-
{ name: 'currentStep', type: 'relation', relation: 'workflowStep', hint: "The step currently being executed or waited on." },
|
|
1060
|
-
{ name: 'owner', type: 'relation', relation: 'user', required: false },
|
|
1061
|
-
{ name: 'startedAt', type: 'datetime', required: true, hint: "Timestamp when the workflow run began." },
|
|
1062
|
-
{ name: 'completedAt', type: 'datetime', hint: "Timestamp when the workflow run finished (successfully or failed)." },
|
|
1063
|
-
{ name: 'log', type: 'string', maxlength: 4096, hint: "Error message if the workflow run failed." }
|
|
1064
|
-
]
|
|
1065
|
-
},
|
|
1066
|
-
dashboard:{
|
|
1067
|
-
name: 'dashboard', // Nom technique du modèle
|
|
1068
|
-
"icon": "FaTachometerAlt",
|
|
1069
|
-
description: "Configuration d'un tableau de bord personnalisé par l'utilisateur.", // Description du modèle
|
|
1070
|
-
locked: false, // Indique si le modèle peut être modifié par l'utilisateur (false = modifiable)
|
|
1071
|
-
fields: [
|
|
1072
|
-
{
|
|
1073
|
-
name: 'name', // Nom du tableau de bord
|
|
1074
|
-
type: 'string', // Type texte simple
|
|
1075
|
-
required: true, // Ce champ est obligatoire
|
|
1076
|
-
hint: "Nom affiché et personnalisable du tableau de bord."
|
|
1077
|
-
},
|
|
1078
|
-
{
|
|
1079
|
-
name: 'description', // Description optionnelle
|
|
1080
|
-
type: 'string', // Type texte simple (pourrait être 'richtext' si besoin de mise en forme)
|
|
1081
|
-
hint: "Description facultative pour donner plus de contexte au tableau de bord."
|
|
1082
|
-
},
|
|
1083
|
-
{
|
|
1084
|
-
name: 'layout', // Configuration de la disposition des éléments
|
|
1085
|
-
type: 'code', // Utilisation du type 'code' pour stocker une structure JSON flexible
|
|
1086
|
-
language: 'json', // Précise que le contenu est du JSON
|
|
1087
|
-
required: true, // La disposition est essentielle
|
|
1088
|
-
default: { "type": "columns", "columns": [] }, // Valeur par défaut : une disposition en colonnes vide, stockée comme chaîne JSON
|
|
1089
|
-
hint: "Structure JSON décrivant l'organisation des KPIs. Exemple : { \"type\": \"columns\", \"columns\": [ [\"kpi_id_1\"], [\"kpi_id_2\", \"kpi_id_3\"] ] }."
|
|
1090
|
-
},
|
|
1091
|
-
{
|
|
1092
|
-
name: 'refreshInterval',
|
|
1093
|
-
type: 'number',
|
|
1094
|
-
delay: true, // Sera interprété par le front-end comme un champ de durée
|
|
1095
|
-
unit: 's',
|
|
1096
|
-
min: 0,
|
|
1097
|
-
hint: "Intervalle de rafraîchissement automatique en secondes. Laisser vide ou à 0 pour désactiver."
|
|
1098
|
-
},
|
|
1099
|
-
{
|
|
1100
|
-
name: 'isDefault', // Indicateur pour le tableau de bord par défaut
|
|
1101
|
-
type: 'boolean', // Type booléen (vrai/faux)
|
|
1102
|
-
default: false, // Par défaut, un nouveau tableau de bord n'est pas celui par défaut
|
|
1103
|
-
hint: "Si 'true', ce tableau de bord est affiché par défaut pour l'utilisateur."
|
|
1104
|
-
}
|
|
1105
|
-
]
|
|
1106
|
-
},
|
|
1107
|
-
'request': {
|
|
1108
|
-
name: 'request',
|
|
1109
|
-
"icon": "FaExchangeAlt",
|
|
1110
|
-
description: "Journal des requêtes reçues par l'API.",
|
|
1111
|
-
locked: true, // Géré par le système, non modifiable directement par l'utilisateur via l'UI standard
|
|
1112
|
-
fields: [
|
|
1113
|
-
{
|
|
1114
|
-
name: 'timestamp',
|
|
1115
|
-
type: 'datetime',
|
|
1116
|
-
required: true,
|
|
1117
|
-
hint: "Date et heure exactes de la réception de la requête."
|
|
1118
|
-
},
|
|
1119
|
-
{
|
|
1120
|
-
name: 'method',
|
|
1121
|
-
type: 'enum',
|
|
1122
|
-
items: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'],
|
|
1123
|
-
required: true,
|
|
1124
|
-
hint: "Méthode HTTP utilisée (GET, POST, etc.)."
|
|
1125
|
-
},
|
|
1126
|
-
{
|
|
1127
|
-
name: 'url',
|
|
1128
|
-
type: 'string',
|
|
1129
|
-
required: true,
|
|
1130
|
-
multiline: false,
|
|
1131
|
-
maxlength: 2048, // Limite raisonnable pour une URL
|
|
1132
|
-
hint: "URL complète de la requête, incluant les query parameters."
|
|
1133
|
-
},
|
|
1134
|
-
{
|
|
1135
|
-
name: 'status',
|
|
1136
|
-
type: 'number',
|
|
1137
|
-
step: 100,
|
|
1138
|
-
default: 200,
|
|
1139
|
-
required: true,
|
|
1140
|
-
hint: "Code de statut HTTP retourné par le serveur (ex: 200, 404, 500)."
|
|
1141
|
-
},
|
|
1142
|
-
{
|
|
1143
|
-
name: 'latencyMs',
|
|
1144
|
-
type: 'number',
|
|
1145
|
-
required: true,
|
|
1146
|
-
color: '#e8c965',
|
|
1147
|
-
unit: 'ms',
|
|
1148
|
-
hint: "Temps de traitement de la requête par le serveur, en millisecondes."
|
|
1149
|
-
},
|
|
1150
|
-
{
|
|
1151
|
-
name: 'ip',
|
|
1152
|
-
type: 'string',
|
|
1153
|
-
hint: "Adresse IP du client ayant effectué la requête."
|
|
1154
|
-
},
|
|
1155
|
-
/*{
|
|
1156
|
-
name: 'requestHeaders',
|
|
1157
|
-
type: 'code',
|
|
1158
|
-
language: 'json',
|
|
1159
|
-
required: false,
|
|
1160
|
-
hint: "En-têtes HTTP de la requête (stockés sous forme de chaîne JSON). Peut être volumineux."
|
|
1161
|
-
},*/
|
|
1162
|
-
{
|
|
1163
|
-
name: 'requestBody', // Optionnel, peut être sensible/volumineux
|
|
1164
|
-
type: 'code',
|
|
1165
|
-
language: 'json', // Ou 'text' si ce n'est pas toujours du JSON
|
|
1166
|
-
required: false,
|
|
1167
|
-
hint: "Corps de la requête (stocké sous forme de chaîne JSON/texte). Attention: peut contenir des données sensibles et être volumineux."
|
|
1168
|
-
},
|
|
1169
|
-
{
|
|
1170
|
-
name: 'responseBody', // Optionnel, peut être volumineux
|
|
1171
|
-
type: 'code',
|
|
1172
|
-
language: 'json', // Ou 'text'
|
|
1173
|
-
required: false,
|
|
1174
|
-
"condition": {
|
|
1175
|
-
"path": [
|
|
1176
|
-
"status"
|
|
1177
|
-
],
|
|
1178
|
-
"op": "$gte",
|
|
1179
|
-
"value": "400"
|
|
1180
|
-
},
|
|
1181
|
-
hint: "Corps de la réponse (stocké sous forme de chaîne JSON/texte). Attention: peut être volumineux."
|
|
1182
|
-
},
|
|
1183
|
-
{
|
|
1184
|
-
name: 'error',
|
|
1185
|
-
type: 'string',
|
|
1186
|
-
maxlength: 4096, // Espace pour les messages d'erreur détaillés
|
|
1187
|
-
required: false,
|
|
1188
|
-
hint: "Message d'erreur si la requête a échoué côté serveur (ex: statut 500)."
|
|
1189
|
-
}
|
|
1190
|
-
]
|
|
1191
|
-
},
|
|
1192
|
-
|
|
1193
|
-
kpi : {
|
|
1194
|
-
name: 'kpi',
|
|
1195
|
-
"icon": "FaChartLine",
|
|
1196
|
-
description: "Configuration d'un Indicateur Clé de Performance (KPI)",
|
|
1197
|
-
fields: [
|
|
1198
|
-
{ name: 'name', type: 'string_t', required: true, hint: "Nom affiché du KPI (ex: Chiffre d'affaires total)" },
|
|
1199
|
-
{ name: 'description', type: 'string_t', hint: "Informations complémentaires sur le KPI" },
|
|
1200
|
-
{ name: 'targetModel', type: 'model', required: true, hint: "Nom du modèle sur lequel calculer le KPI (ex: order)" },
|
|
1201
|
-
{
|
|
1202
|
-
name: 'aggregationType',
|
|
1203
|
-
type: 'enum',
|
|
1204
|
-
required: true,
|
|
1205
|
-
items: ['count', 'sum', 'avg', 'min', 'max'], // Types d'agrégation courants
|
|
1206
|
-
hint: "Type de calcul à effectuer"
|
|
1207
|
-
},
|
|
1208
|
-
{
|
|
1209
|
-
name: 'aggregationField',
|
|
1210
|
-
type: '
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
"
|
|
1227
|
-
"
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
"
|
|
1232
|
-
"
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
"
|
|
1236
|
-
"
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
"
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
"
|
|
1385
|
-
"
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
"
|
|
1390
|
-
"
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
"
|
|
1396
|
-
"
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
"
|
|
1402
|
-
"
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
"
|
|
1408
|
-
"
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
"
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
"
|
|
1415
|
-
"
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
"
|
|
1421
|
-
"
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
"
|
|
1427
|
-
"
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
"
|
|
1432
|
-
"
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
"
|
|
1437
|
-
"
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
"
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
"
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
"
|
|
1454
|
-
"
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
"
|
|
1459
|
-
"
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
"
|
|
1465
|
-
"
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
"
|
|
1470
|
-
"
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
"
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
"
|
|
1477
|
-
"
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
"
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1
|
+
// Définition des structures de modèles
|
|
2
|
+
export const defaultModels = {
|
|
3
|
+
permission: {
|
|
4
|
+
"name": "permission",
|
|
5
|
+
"icon": "FaKey",
|
|
6
|
+
"description": "",
|
|
7
|
+
"fields": [
|
|
8
|
+
{
|
|
9
|
+
"name": "name",
|
|
10
|
+
"type": "string_t",
|
|
11
|
+
color: '#757BCC'
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "description",
|
|
15
|
+
"type": "richtext"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
role: {
|
|
20
|
+
name: 'role',
|
|
21
|
+
"icon": "FaUserTag",
|
|
22
|
+
"description": "",
|
|
23
|
+
fields: [
|
|
24
|
+
{ name: 'name', type: 'string_t', required: true, unique: true, color: '#363636' },
|
|
25
|
+
{ name: 'permissions', type: 'relation', multiple: true, relation: 'permission' }
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
user: {
|
|
29
|
+
name: 'user',
|
|
30
|
+
"description": "",
|
|
31
|
+
"icon": "FaUser",
|
|
32
|
+
locked: true,
|
|
33
|
+
fields: [
|
|
34
|
+
{ name: 'username', type: 'string', required: true, unique: true, color: '#3C7D08' },
|
|
35
|
+
{ name: 'password', type: 'password' },
|
|
36
|
+
{
|
|
37
|
+
"name": "gender",
|
|
38
|
+
"type": "enum",
|
|
39
|
+
"items": ["male", "female", "other", "prefer_not_to_say"]
|
|
40
|
+
},
|
|
41
|
+
{ name: 'contact', type: 'relation', relation: 'contact' },
|
|
42
|
+
{ name: 'roles', type: 'relation', multiple: true, relation: 'role' },
|
|
43
|
+
{ name: 'lang', type: 'relation', relation: 'lang', color: '#4CACCD' },
|
|
44
|
+
{
|
|
45
|
+
"name": "profilePicture",
|
|
46
|
+
"type": "file",
|
|
47
|
+
"mimeTypes": ["image/jpeg", "image/png"]
|
|
48
|
+
},
|
|
49
|
+
{ name: 'tokens', type: 'relation', multiple: true, relation: 'token' }
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
userPermission: {
|
|
53
|
+
"icon": "FaUserCheck",
|
|
54
|
+
"name": "userPermission",
|
|
55
|
+
"description": "Gère les exceptions aux permissions des rôles pour un utilisateur (ajouts ou retraits, permanents ou temporaires).",
|
|
56
|
+
"fields": [
|
|
57
|
+
{
|
|
58
|
+
"name": "user",
|
|
59
|
+
"type": "relation",
|
|
60
|
+
"relation": "user",
|
|
61
|
+
"required": true,
|
|
62
|
+
"index": true
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "permission",
|
|
66
|
+
"type": "relation",
|
|
67
|
+
"relation": "permission",
|
|
68
|
+
"required": true,
|
|
69
|
+
"index": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "isGranted",
|
|
73
|
+
"type": "boolean",
|
|
74
|
+
"required": true,
|
|
75
|
+
"hint": "True pour accorder la permission, False pour la révoquer explicitement."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "expiresAt",
|
|
79
|
+
"type": "datetime",
|
|
80
|
+
"required": false,
|
|
81
|
+
"index": true,
|
|
82
|
+
"hint": "Si défini, l'exception (l'octroi ou la révocation) est temporaire."
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
token: {
|
|
87
|
+
name: 'token',
|
|
88
|
+
"icon": "FaKey",
|
|
89
|
+
"description": "",
|
|
90
|
+
fields: [
|
|
91
|
+
{ name: 'name', type: 'string' },
|
|
92
|
+
{ name: 'value', type: 'password' },
|
|
93
|
+
{ name: 'lastRefresh', type: 'datetime' }
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
translation: {
|
|
97
|
+
name: 'translation',
|
|
98
|
+
"icon": "FaLanguage",
|
|
99
|
+
locked: true,
|
|
100
|
+
"description": "",
|
|
101
|
+
fields: [
|
|
102
|
+
{ name: 'lang', type: 'relation', 'relation': 'lang', required: true, color: '#4CACCD' },
|
|
103
|
+
{ name: 'key', type: 'string', maxlength: 200, required: true },
|
|
104
|
+
{ name: 'value', type: 'string' }
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
lang: {
|
|
108
|
+
name: 'lang',
|
|
109
|
+
"icon": "FaGlobe",
|
|
110
|
+
locked: true,
|
|
111
|
+
"description": "",
|
|
112
|
+
fields: [
|
|
113
|
+
{ name: 'name', unique: true, type: 'string_t', maxlength: 200, color: '#4CACCD' },
|
|
114
|
+
{ name: 'code', type: 'string', maxlength: 5 }
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
currency: {
|
|
118
|
+
name: 'currency',
|
|
119
|
+
"icon": "FaMoneyBill",
|
|
120
|
+
"description": "",
|
|
121
|
+
locked: true,
|
|
122
|
+
fields: [
|
|
123
|
+
{ name: 'symbol', type: 'string', required: true, color: '#E0E0E0', maxlength: 20, asMain: true },
|
|
124
|
+
{ name: 'code', type: 'string', required: true, unique: true, maxlength: 3, asMain: true },
|
|
125
|
+
{ name: 'name', type: 'string_t', required: true, color: '#AE6FA3' },
|
|
126
|
+
{ name: 'exchangeRate', type: 'number', required: false },
|
|
127
|
+
{ name: 'default', type: 'boolean', default: false }
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
channel: {
|
|
131
|
+
name: 'channel',
|
|
132
|
+
"icon": "FaComments",
|
|
133
|
+
"description": "",
|
|
134
|
+
fields: [
|
|
135
|
+
{ name: 'name', type: 'string_t', required: true, unique: true }, // Nom du canal (ex: "email", "SMS")
|
|
136
|
+
{ name: 'description', type: 'string_t' },
|
|
137
|
+
{ name: 'type', type: 'enum', items: ['web', 'mobile', 'email', 'sms', 'push'], required: true } // Type de canal
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
message: {
|
|
141
|
+
name: 'message',
|
|
142
|
+
"icon": "FaEnvelope",
|
|
143
|
+
"description": "",
|
|
144
|
+
locked: true,
|
|
145
|
+
fields: [
|
|
146
|
+
{ name: 'sender', type: 'relation', relation: 'user' }, // Utilisateur émetteur (si applicable, sinon système)
|
|
147
|
+
{ name: 'recipient', type: 'relation', relation: 'user' }, // Utilisateur destinataire
|
|
148
|
+
{ name: 'lang', type: 'relation', relation: 'lang' }, // Utilisateur destinataire
|
|
149
|
+
{ name: 'subject', type: 'string' }, // Sujet de la notification (ex: titre de l'email)
|
|
150
|
+
{ name: 'content', type: 'richtext', required: true }, // Contenu du message (localisable)
|
|
151
|
+
{ name: 'channels', type: 'relation', multiple: true, relation: 'channel' }, // Canaux de diffusion (email, SMS, forum, etc.)
|
|
152
|
+
{ name: 'status', type: 'enum', items: ['pending', 'sent', 'read', 'failed'] },
|
|
153
|
+
{ name: 'sentAt', type: 'datetime' },
|
|
154
|
+
{ name: 'readAt', type: 'datetime' },
|
|
155
|
+
{ name: 'type', type: 'string' }, // Type de notification (ex: "commande.miseAJour", "messageForum")
|
|
156
|
+
{ name: 'priority', type: 'enum', items: ['low', 'medium', 'high']}
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
alert: {
|
|
160
|
+
name: "alert",
|
|
161
|
+
"icon": "FaBell",
|
|
162
|
+
description: "Définit les règles pour les alertes et les insights automatiques.",
|
|
163
|
+
fields: [
|
|
164
|
+
{ name: "name", type: "string", required: true, asMain: true },
|
|
165
|
+
{ name: "targetModel", type: "model", required: true },
|
|
166
|
+
{ name: "description", type: "string_t", multiline: true },
|
|
167
|
+
{
|
|
168
|
+
name: "triggerCondition",
|
|
169
|
+
type: "code",
|
|
170
|
+
language: "json",
|
|
171
|
+
conditionBuilder: true,
|
|
172
|
+
targetModel: '$targetModel',
|
|
173
|
+
required: true,
|
|
174
|
+
hint: "La condition qui, si elle est remplie, déclenchera l'alerte."
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "frequency",
|
|
178
|
+
type: "cronSchedule",
|
|
179
|
+
required: true,
|
|
180
|
+
cronMask: [false, true, true, true, true, true],
|
|
181
|
+
hint: "À quelle fréquence vérifier si la condition est remplie."
|
|
182
|
+
},
|
|
183
|
+
{ name: "isActive", type: "boolean", default: true },
|
|
184
|
+
{
|
|
185
|
+
name: "sendEmail",
|
|
186
|
+
type: "boolean",
|
|
187
|
+
default: false,
|
|
188
|
+
hint: "Cochez pour envoyer également une notification par e-mail."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "lastNotifiedAt",
|
|
192
|
+
type: "datetime",
|
|
193
|
+
required: false, // Important: ce champ est géré par le système
|
|
194
|
+
hint: "Timestamp de la dernière notification envoyée pour cette alerte."
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "message",
|
|
198
|
+
type: "richtext_t",
|
|
199
|
+
required: false,
|
|
200
|
+
hint: "Message personnalisé pour l'e-mail. Si vide, un message par défaut sera utilisé. Vous pouvez utiliser les variables {count}, {alert.name}....",
|
|
201
|
+
condition: { $eq: ["$sendEmail", true] }
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
env: {
|
|
206
|
+
name: "env",
|
|
207
|
+
"icon": "FaCog",
|
|
208
|
+
description: "Définit les variables d'environnement qui seront accessibles dans vos scripts et webhooks.",
|
|
209
|
+
fields: [
|
|
210
|
+
{ name: "name", type: "string", required: true, unique: true, asMain: true },
|
|
211
|
+
{ name: "value", type: "string", anonymized: true, hiddenable: true }
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
webpage: {
|
|
215
|
+
name: 'webpage',
|
|
216
|
+
"icon": "FaFileAlt",
|
|
217
|
+
locked: true,
|
|
218
|
+
"description": "",
|
|
219
|
+
fields: [
|
|
220
|
+
{ name: 'title', type: 'string_t', required: true, color: '#659DE6' },
|
|
221
|
+
{ name: 'path', type: 'string', required: true, unique: true, color: '#DEDEDE' },
|
|
222
|
+
{ name: 'html', type: 'richtext' },
|
|
223
|
+
{ name: 'published', type: 'boolean', default: false },
|
|
224
|
+
{ name: 'inSitemap', type: 'boolean', default: true },
|
|
225
|
+
{ name: 'description', type: 'string' },
|
|
226
|
+
{ name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true },
|
|
227
|
+
{ name: 'image', type: 'url' },
|
|
228
|
+
{ name: 'category', type: 'relation', relation: 'taxonomy' }
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
content: {
|
|
232
|
+
name: 'content',
|
|
233
|
+
"icon": "FaFileAlt",
|
|
234
|
+
"description": "",
|
|
235
|
+
fields: [
|
|
236
|
+
{ name: 'lang', type: 'relation', relation: 'lang' },
|
|
237
|
+
{ name: 'title', type: 'string_t', required: true },
|
|
238
|
+
{ name: 'slug', type: 'string' },
|
|
239
|
+
{ name: 'html', type: 'richtext_t' },
|
|
240
|
+
{ name: 'image', type: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
|
|
241
|
+
{ name: 'published', type: 'boolean' },
|
|
242
|
+
{ name: 'publishedAt', type: 'datetime' },
|
|
243
|
+
{ name: 'author', type: 'relation', relation: 'user' },
|
|
244
|
+
{ name: 'category', type: 'relation', relation: 'taxonomy', "relationFilter": {
|
|
245
|
+
"path": [
|
|
246
|
+
"type"
|
|
247
|
+
],
|
|
248
|
+
"op": "$eq",
|
|
249
|
+
"value": "category"
|
|
250
|
+
} },
|
|
251
|
+
{ name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true, "relationFilter": {
|
|
252
|
+
"path": [
|
|
253
|
+
"type"
|
|
254
|
+
],
|
|
255
|
+
"op": "$eq",
|
|
256
|
+
"value": "keyword"
|
|
257
|
+
} },
|
|
258
|
+
{ name: 'order', type: 'number', step: 1, default: 0 },
|
|
259
|
+
{ name: 'inSitemap', type: 'boolean', default: false }
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
resource: {
|
|
263
|
+
name: 'resource',
|
|
264
|
+
"icon": "FaBoxOpen",
|
|
265
|
+
"description": "",
|
|
266
|
+
fields: [
|
|
267
|
+
{ name: "source", type: "url"},
|
|
268
|
+
{ name: "file", type: "file"}
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
taxonomy: {
|
|
272
|
+
name: 'taxonomy',
|
|
273
|
+
"icon": "FaTags",
|
|
274
|
+
"description": "",
|
|
275
|
+
fields: [
|
|
276
|
+
{ name: 'name', type: 'string_t', required: true, color: '#71A314' },
|
|
277
|
+
{ name: 'parent', type: 'relation', relation: 'taxonomy', color: '#233607' }, // Relation vers la taxonomie parente
|
|
278
|
+
{ name: 'type', type: 'enum', items: ['keyword', 'category'], color: '#BFBFBF' },
|
|
279
|
+
{ name: 'identifier', type: 'string' },
|
|
280
|
+
{ name: 'order', type: 'number', step: 1, default: 0 },
|
|
281
|
+
{ name: 'description', type: 'richtext' }
|
|
282
|
+
]
|
|
283
|
+
},
|
|
284
|
+
contact: {
|
|
285
|
+
locked: true,
|
|
286
|
+
name: 'contact',
|
|
287
|
+
"icon": "FaAddressBook",
|
|
288
|
+
"description": "",
|
|
289
|
+
fields: [
|
|
290
|
+
{ name: 'legalName', type: 'string', asMain: true, color: '#D9D9D9' },
|
|
291
|
+
{ name: 'firstName', type: 'string', asMain: true},
|
|
292
|
+
{ name: 'lastName', type: 'string', asMain: true },
|
|
293
|
+
{ name: 'email', type: 'email', color: '#F4ECE2' },
|
|
294
|
+
{ name: 'phone', type: 'phone', color: '#B4A693' },
|
|
295
|
+
{ name: 'location', type: 'relation', relation: 'location' }
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
location: {
|
|
300
|
+
"name": "location",
|
|
301
|
+
"icon": "FaMapMarkerAlt",
|
|
302
|
+
locked: true,
|
|
303
|
+
"description": "",
|
|
304
|
+
"fields": [
|
|
305
|
+
{
|
|
306
|
+
"name": "address_1",
|
|
307
|
+
"type": "string",
|
|
308
|
+
asMain: true,
|
|
309
|
+
color: '#D6D6D6'
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "address_2",
|
|
313
|
+
"type": "string"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"name": "address_3",
|
|
317
|
+
"type": "string"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"name": "address_4",
|
|
321
|
+
"type": "string"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"name": "city",
|
|
325
|
+
"type": "string",
|
|
326
|
+
asMain: true,
|
|
327
|
+
color: '#E63345'
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"name": "postalCode",
|
|
331
|
+
"type": "string",
|
|
332
|
+
asMain: true,
|
|
333
|
+
color: '#8B1D1D'
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"name": "region",
|
|
337
|
+
"type": "string"
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"name": "country",
|
|
341
|
+
"type": "string",
|
|
342
|
+
color: "#4F80BF",
|
|
343
|
+
asMain: true
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"name": "latitude",
|
|
347
|
+
"type": "number",
|
|
348
|
+
"unit": "°"
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"name": "longitude",
|
|
352
|
+
"type": "number",
|
|
353
|
+
"unit": "°"
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
brand: {
|
|
359
|
+
name: 'brand',
|
|
360
|
+
"icon": "FaTrademark",
|
|
361
|
+
"description": "",
|
|
362
|
+
fields: [
|
|
363
|
+
{ name: 'name', type: 'string', required: true },
|
|
364
|
+
{ name: 'logo', type: 'file' },
|
|
365
|
+
{ name: 'company', type: 'relation', relation: 'contact' }
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
product: {
|
|
370
|
+
name: 'product',
|
|
371
|
+
"icon": "FaShoppingBag",
|
|
372
|
+
"description": "",
|
|
373
|
+
fields: [
|
|
374
|
+
{ name: 'name', type: 'string_t', required: true },
|
|
375
|
+
{ name: 'image', type: 'array', itemsType: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
|
|
376
|
+
{ name: 'description', type: 'richtext_t' },
|
|
377
|
+
{ name: 'price', type: 'number', required: true },
|
|
378
|
+
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
379
|
+
{ name: 'billingFrequency', type: 'enum', items: ['aucune', 'au mois', 'à l\'année'] },
|
|
380
|
+
{ name: 'slug', type: 'string', required: true, unique: true },
|
|
381
|
+
{ name: 'brand', type: 'relation', relation: 'brand' },
|
|
382
|
+
{ name: 'category', type: 'relation', relation: 'taxonomy' },
|
|
383
|
+
{ name: 'seoTitle', type: 'string_t' },
|
|
384
|
+
{ name: 'seoDescription', type: 'string_t' }
|
|
385
|
+
]
|
|
386
|
+
},
|
|
387
|
+
productVariant: {
|
|
388
|
+
name: 'productVariant',
|
|
389
|
+
"icon": "FaBox",
|
|
390
|
+
"description": "",
|
|
391
|
+
fields: [
|
|
392
|
+
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
393
|
+
{ name: 'size', type: 'string' },
|
|
394
|
+
{ name: 'color', type: 'color' },
|
|
395
|
+
{ name: 'sku', type: 'string', unique: true },
|
|
396
|
+
{ name: 'price', type: 'number', required: true },
|
|
397
|
+
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
398
|
+
{ name: 'stock', type: 'number', default: 0 },
|
|
399
|
+
{ name: 'description', type: 'richtext' },
|
|
400
|
+
{ name: 'image', type: 'url' }
|
|
401
|
+
]
|
|
402
|
+
},
|
|
403
|
+
cart: {
|
|
404
|
+
name: 'cart',
|
|
405
|
+
"icon": "FaShoppingCart",
|
|
406
|
+
"description": "",
|
|
407
|
+
fields: [
|
|
408
|
+
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
409
|
+
{ name: 'items', type: 'relation', relation: 'cartItem', multiple: true },
|
|
410
|
+
{ name: 'creationDate', type: 'datetime', required: true },
|
|
411
|
+
{ name: 'lastUpdate', type: 'datetime', required: true },
|
|
412
|
+
{ name: 'active', type: 'boolean', default: true }
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
cartItem: {
|
|
416
|
+
name: 'cartItem',
|
|
417
|
+
"icon": "FaShoppingBasket",
|
|
418
|
+
"description": "",
|
|
419
|
+
fields: [
|
|
420
|
+
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
421
|
+
{ name: 'quantity', type: 'number', required: true, min: 1, step: 1 },
|
|
422
|
+
{ name: 'variant', type: 'relation', relation: 'productVariant' } // Optionnel, si vous avez des variantes
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
discount: {
|
|
426
|
+
name: "discount",
|
|
427
|
+
"icon": "FaTicketAlt",
|
|
428
|
+
locked: true,
|
|
429
|
+
"description": "",
|
|
430
|
+
fields: [
|
|
431
|
+
{ "name": "code", "type": "string", "required": true, "unique": true },
|
|
432
|
+
{ "name": "productSelection", "type": "relation", "relation": "product", "required": false, multiple: true },
|
|
433
|
+
{ "name": "description", "type": "richtext" },
|
|
434
|
+
{ "name": "percentAmount", "type": "number", "unit": "%", default: null, min: 0 },
|
|
435
|
+
{ "name": "fixedAmount", "type": "number", default: null, min: 0 },
|
|
436
|
+
{ "name": "minAmount", "type": "number", "unit": "€", default: null, min: 0 }, // Montant minimum pour la promotion
|
|
437
|
+
{ "name": "minProductQuantity", "type": "number", min: 0 }, // Montant minimum pour la promotion
|
|
438
|
+
{ "name": "freeProductQuantity", "type": "number", default: null, min: 0 }, // Quantité de produits offerts
|
|
439
|
+
{ "name": "startDate", "type": "datetime" },
|
|
440
|
+
{ "name": "endDate", "type": "datetime" }
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
order: {
|
|
444
|
+
name: "order",
|
|
445
|
+
"icon": "FaClipboardList",
|
|
446
|
+
locked: true,
|
|
447
|
+
"description": "",
|
|
448
|
+
fields: [
|
|
449
|
+
{ "name": "orderId", "type": "string", "required": true, "unique": true },
|
|
450
|
+
{ "name": "orderDate", "type": "datetime" },
|
|
451
|
+
{ "name": "status", "type": "enum", items: ["pending", "processing", "shipped", "delivered", "cancelled"] },
|
|
452
|
+
{ "name": "products", "type": "relation", "relation": "cartItem", "required": true, multiple: true },
|
|
453
|
+
{ "name": "customer", "type": "relation", relation: 'user' }, // Relation vers le modèle 'user'
|
|
454
|
+
{ "name": "totalAmount", "type": "number", "required": true },
|
|
455
|
+
{ "name": "paymentIntentId", "type": "string", "hint": "Stripe Payment Intent ID for this order." },
|
|
456
|
+
{ "name": "currency", "type": "relation", "relation": "currency" },
|
|
457
|
+
{ "name": "paymentMethod", "type": "string" },
|
|
458
|
+
{ "name": "shippingAddress", "type": "relation", "relation": "location" },
|
|
459
|
+
{ "name": "billingAddress", "type": "relation", "relation": "location" },
|
|
460
|
+
{ "name": "shippedDate", "type": "datetime" },
|
|
461
|
+
{ "name": "deliveryDate", "type": "datetime" },
|
|
462
|
+
{ "name": "discount", "type": "relation", relation: 'discount' } // Relation vers le modèle 'promotion'
|
|
463
|
+
]
|
|
464
|
+
},
|
|
465
|
+
invoice: {
|
|
466
|
+
name: 'invoice',
|
|
467
|
+
"icon": "FaFileInvoice",
|
|
468
|
+
"description": "",
|
|
469
|
+
fields: [
|
|
470
|
+
{ name: 'order', type: 'relation', relation: 'order', required: true },
|
|
471
|
+
{ name: 'invoiceId', type: 'string', required: true, unique: true },
|
|
472
|
+
{ name: 'invoiceDate', type: 'datetime', required: true },
|
|
473
|
+
{ name: 'dueDate', type: 'datetime' },
|
|
474
|
+
{ name: 'status', type: 'enum', items: ['paid', 'unpaid', 'partially_paid', 'cancelled'] }
|
|
475
|
+
]
|
|
476
|
+
},
|
|
477
|
+
userSubscription: {
|
|
478
|
+
name: 'userSubscription',
|
|
479
|
+
"icon": "FaCalendarCheck",
|
|
480
|
+
"description": "",
|
|
481
|
+
locked: true,
|
|
482
|
+
fields: [
|
|
483
|
+
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
484
|
+
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
485
|
+
{ name: 'startDate', type: 'datetime', required: true },
|
|
486
|
+
{ name: 'endDate', type: 'datetime' },
|
|
487
|
+
{ name: 'price', type: 'number', required: true },
|
|
488
|
+
{ name: 'currency', type: 'relation', relation: 'currency', required: true },
|
|
489
|
+
{ name: 'paymentMethod', type: 'enum', items: ['bank_card', 'SEPA_mandate', 'cash', 'check', 'other'] },
|
|
490
|
+
{ name: 'status', type: 'enum', items: ['active', 'inactive', 'cancelled', 'expired', 'pending'] },
|
|
491
|
+
{ name: 'billingCycleAnchor', type: 'datetime' },
|
|
492
|
+
{ name: 'nextBillingDate', type: 'datetime' },
|
|
493
|
+
{ name: 'lastBillingDate', type: 'datetime' },
|
|
494
|
+
{ name: 'cancelReason', type: 'string' },
|
|
495
|
+
{ name: 'autoRenew', type: 'boolean', default: false }
|
|
496
|
+
]
|
|
497
|
+
},
|
|
498
|
+
stock: {
|
|
499
|
+
name: 'stock',
|
|
500
|
+
"icon": "FaWarehouse",
|
|
501
|
+
"description": "",
|
|
502
|
+
fields: [
|
|
503
|
+
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
504
|
+
{ name: 'variant', type: 'relation', relation: 'productVariant' }, // Optionnel
|
|
505
|
+
{ name: 'warehouse', type: 'relation', relation: 'warehouse', required: true },
|
|
506
|
+
{ name: 'available', type: 'number', default: 0 },
|
|
507
|
+
{ name: 'reserved', type: 'number', default: 0 } // Quantité réservée (pour les commandes en cours)
|
|
508
|
+
]
|
|
509
|
+
},
|
|
510
|
+
stockAlert: {
|
|
511
|
+
name: 'stockAlert',
|
|
512
|
+
"icon": "FaExclamationTriangle",
|
|
513
|
+
"description": "",
|
|
514
|
+
fields: [
|
|
515
|
+
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
516
|
+
{ name: 'stock', type: 'relation', relation: 'stock', required: true },
|
|
517
|
+
{ name: 'threshold', type: 'number', required: true, min: 0 }
|
|
518
|
+
]
|
|
519
|
+
// how to implement unique fields on COMBINATION of multiple columns ?
|
|
520
|
+
},
|
|
521
|
+
shipment: {
|
|
522
|
+
name: 'shipment',
|
|
523
|
+
"icon": "FaTruck",
|
|
524
|
+
"description": "",
|
|
525
|
+
fields: [
|
|
526
|
+
{ name: 'order', type: 'relation', relation: 'order', required: true },
|
|
527
|
+
{ name: 'trackingNumber', type: 'string' },
|
|
528
|
+
{ name: 'carrier', type: 'string' },
|
|
529
|
+
{ name: 'status', type: 'enum', items: ['pending', 'in_transit', 'delivered', 'issue'] },
|
|
530
|
+
{ name: 'estimatedDeliveryDate', type: 'datetime' },
|
|
531
|
+
{ name: 'actualDeliveryDate', type: 'datetime' }
|
|
532
|
+
]
|
|
533
|
+
},
|
|
534
|
+
warehouse: {
|
|
535
|
+
name: 'warehouse',
|
|
536
|
+
"description": "",
|
|
537
|
+
"icon": "FaWarehouse",
|
|
538
|
+
fields: [
|
|
539
|
+
{ name: 'name', type: 'string_t', required: true },
|
|
540
|
+
{ name: 'location', type: 'relation', relation: 'location' },
|
|
541
|
+
{ name: 'capacity', type: 'number' }
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
'return': {
|
|
545
|
+
name: "return",
|
|
546
|
+
"description": "",
|
|
547
|
+
"icon": "FaUndo",
|
|
548
|
+
fields: [
|
|
549
|
+
{ "name": "order", "type": "relation", "relation": "order", "required": true },
|
|
550
|
+
{ "name": "user", "type": "relation", relation: "user" },
|
|
551
|
+
{ "name": "reason", "type": "string", maxlength: 2048, required: true },
|
|
552
|
+
{ "name": "channel", "type": "relation", relation: 'channel' },
|
|
553
|
+
{ "name": "status", "type": "enum", items: ["pending", "approved", "refunded", "refused"] },
|
|
554
|
+
{ name: 'amount', type: 'number', min: 0 },
|
|
555
|
+
{ name: 'currency', type: 'relation', relation: 'currency' },
|
|
556
|
+
{ name: 'refundDate', type: 'datetime' }
|
|
557
|
+
]
|
|
558
|
+
},
|
|
559
|
+
returnItem: {
|
|
560
|
+
name: 'returnItem',
|
|
561
|
+
"icon": "FaBoxOpen",
|
|
562
|
+
"description": "",
|
|
563
|
+
fields: [
|
|
564
|
+
{ name: 'return', type: 'relation', relation: 'return', required: true },
|
|
565
|
+
{ name: 'product', type: 'relation', relation: 'product', required: true },
|
|
566
|
+
{ name: 'variant', type: 'relation', relation: 'productVariant' },
|
|
567
|
+
{ name: 'quantity', type: 'number', required: true, min: 1 },
|
|
568
|
+
{ name: 'condition', type: 'enum', items: ['new', 'very_good', 'good', 'degraded', 'damaged', 'unusable'] }
|
|
569
|
+
]
|
|
570
|
+
},
|
|
571
|
+
ticket: {
|
|
572
|
+
name: 'ticket',
|
|
573
|
+
"icon": "FaTicketAlt",
|
|
574
|
+
"description": "",
|
|
575
|
+
locked: true,
|
|
576
|
+
fields: [
|
|
577
|
+
{ name: 'user', type: 'relation', relation: 'user', required: true },
|
|
578
|
+
{ name: 'order', type: 'relation', relation: 'order' },
|
|
579
|
+
{ name: 'channel', type: 'relation', relation: 'channel' },
|
|
580
|
+
{ name: 'parent', type: 'relation', relation: 'ticket' },
|
|
581
|
+
{ name: 'subject', type: 'string', required: true },
|
|
582
|
+
{ name: 'message', type: 'richtext', required: true },
|
|
583
|
+
{ name: 'status', type: 'enum', items: ['opened', 'in_progress', 'closed'] },
|
|
584
|
+
{ name: 'priority', type: 'enum', items: ['low', 'medium', 'high', 'urgent'] },
|
|
585
|
+
{ name: 'assignedTo', type: 'relation', relation: 'user' },
|
|
586
|
+
{ name: 'createdAt', type: 'datetime', required: true }
|
|
587
|
+
]
|
|
588
|
+
},
|
|
589
|
+
review: {
|
|
590
|
+
name: "review",
|
|
591
|
+
"icon": "FaStar",
|
|
592
|
+
"description": "",
|
|
593
|
+
fields: [
|
|
594
|
+
{ "name": "user", "type": "relation", relation: "user" },
|
|
595
|
+
{ "name": "product", "type": "relation", relation: 'product' },
|
|
596
|
+
{ "name": "productVariant", "type": "relation", relation: 'productVariant' },
|
|
597
|
+
{ "name": "comment", "type": "richtext", maxlength: 2048, required: true },
|
|
598
|
+
{ "name": "score", "type": "number" },
|
|
599
|
+
{ "name": "publishedAt", "type": "datetime", required: true }
|
|
600
|
+
]
|
|
601
|
+
},
|
|
602
|
+
device: {
|
|
603
|
+
name: "device",
|
|
604
|
+
"icon": "FaMobile",
|
|
605
|
+
"description": "",
|
|
606
|
+
fields: [
|
|
607
|
+
{ "name": "location", "type": "relation", relation: 'location' },
|
|
608
|
+
{ "name": "lastLocationUpdate", "type": "datetime" }
|
|
609
|
+
]
|
|
610
|
+
},
|
|
611
|
+
// Modèle pour l'exercice comptable et l'entreprise
|
|
612
|
+
accountingExercise: {
|
|
613
|
+
name: 'accountingExercise',
|
|
614
|
+
"icon": "FaBook",
|
|
615
|
+
description: "Représente un exercice comptable pour une entreprise donnée.",
|
|
616
|
+
fields: [
|
|
617
|
+
{ name: 'name', type: 'string_t', 'required': true, unique: true, hint: "Intitulé de l'exercice comptable" },
|
|
618
|
+
{ name: 'companyContact', type: 'relation', relation: 'contact', 'required': true, hint: "Désignation de l'entreprise" },
|
|
619
|
+
{ name: 'companyIdentifier', type: 'string', asMain: true, hint: "SIRET de l'entreprise", unique: true },
|
|
620
|
+
{ name: 'startDate', type: 'date', required: true, asMain: true, hint: "Date de début de l'exercice" },
|
|
621
|
+
{ name: 'endDate', type: 'date', required: true, asMain: true, hint: "Date de clôture de l'exercice" }
|
|
622
|
+
]
|
|
623
|
+
},
|
|
624
|
+
|
|
625
|
+
// Modèle pour définir la structure des lignes comptables (le "plan")
|
|
626
|
+
accountingLineItem: {
|
|
627
|
+
name: 'accountingLineItem',
|
|
628
|
+
"icon": "FaListAlt",
|
|
629
|
+
description: "Définit une ligne/catégorie dans un document comptable.",
|
|
630
|
+
locked: true, // Probablement géré par l'application, pas par l'utilisateur final
|
|
631
|
+
fields: [
|
|
632
|
+
{ name: 'accountingExercise', type: 'relation', required: true, unique: true, relation: "accountingExercise" },
|
|
633
|
+
{ name: 'code', type: 'string', required: true, unique: true, hint: "Code unique de la ligne (ex: AA, FB, HA)" },
|
|
634
|
+
{ name: 'label', type: 'string_t', required: true, hint: "Libellé de la ligne (ex: Frais d'établissement)" },
|
|
635
|
+
{
|
|
636
|
+
name: 'documentType', type: 'enum', required: true,
|
|
637
|
+
items: ['bilan_actif', 'bilan_passif', 'compte_resultat', 'immobilisations', 'amortissements', 'provisions', 'creances_dettes',
|
|
638
|
+
'deficits',
|
|
639
|
+
'plus_moins_values',
|
|
640
|
+
'effectifs_valeur_ajoutee',
|
|
641
|
+
'capital_social',
|
|
642
|
+
'filiales_participations',
|
|
643
|
+
'resultat_fiscal']
|
|
644
|
+
},
|
|
645
|
+
{ name: 'section', type: 'string_t', required: true, hint: "Section principale (ex: ACTIF IMMOBILISÉ)" },
|
|
646
|
+
{ name: 'subSection', type: 'string_t', hint: "Sous-section (ex: IMMOBILISATIONS INCORPORELLES)" },
|
|
647
|
+
{ name: 'order', type: 'number', hint: "Ordre d'affichage dans la section/sous-section" },
|
|
648
|
+
{ name: 'calculationFormula', type: 'string', hint: "Formule de calcul (si applicable)" },
|
|
649
|
+
{
|
|
650
|
+
name: 'values', type: 'array', itemsType: 'number', required: true,
|
|
651
|
+
hint: "Valeurs de la ligne comptable"
|
|
652
|
+
},
|
|
653
|
+
{ name: 'notes', type: 'richtext', hint: "Notes ou renvois (ex: (1), (3))" }
|
|
654
|
+
]
|
|
655
|
+
},
|
|
656
|
+
accountingEntry: {
|
|
657
|
+
"name": "accountingEntry",
|
|
658
|
+
"icon": "FaPenAlt",
|
|
659
|
+
"description": "",
|
|
660
|
+
"fields": [
|
|
661
|
+
{
|
|
662
|
+
"name": "exercise",
|
|
663
|
+
"type": "relation",
|
|
664
|
+
"relation": "accountingExercise",
|
|
665
|
+
"required": true
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
"name": "label",
|
|
669
|
+
"type": "string",
|
|
670
|
+
"required": true,
|
|
671
|
+
"asMain": true,
|
|
672
|
+
"maxlength": 255
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"name": "entryDate",
|
|
676
|
+
"type": "date",
|
|
677
|
+
"required": true
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
"name": "amount",
|
|
681
|
+
"type": "number",
|
|
682
|
+
"default": 0
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"name": "currency",
|
|
686
|
+
"type": "relation",
|
|
687
|
+
"relation": "currency",
|
|
688
|
+
"required": true
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"name": "referenceNumber",
|
|
692
|
+
"type": "string",
|
|
693
|
+
"maxlength": 100
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"name": "notes",
|
|
697
|
+
"type": "richtext"
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
"name": "status",
|
|
701
|
+
"type": "enum",
|
|
702
|
+
"items": ["draft", "validated", "cancelled"],
|
|
703
|
+
"default": "brouillon"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"name": "createdBy",
|
|
707
|
+
"type": "relation",
|
|
708
|
+
"relation": "user"
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"name": "validatedBy",
|
|
712
|
+
"type": "relation",
|
|
713
|
+
"relation": "user"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
"name": "validationDate",
|
|
717
|
+
"type": "datetime"
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
"name": "attachments",
|
|
721
|
+
"type": "array",
|
|
722
|
+
"itemsType": "file"
|
|
723
|
+
}
|
|
724
|
+
]
|
|
725
|
+
},
|
|
726
|
+
employee: {
|
|
727
|
+
"name": "employee",
|
|
728
|
+
"icon": "FaUserTie",
|
|
729
|
+
"description": "",
|
|
730
|
+
"fields": [
|
|
731
|
+
{
|
|
732
|
+
"name": "employeeId",
|
|
733
|
+
"type": "string",
|
|
734
|
+
"required": true,
|
|
735
|
+
"unique": true
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
"name": "personalInfo",
|
|
739
|
+
"type": "relation",
|
|
740
|
+
"relation": "user",
|
|
741
|
+
"required": true
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"name": "jobTitle",
|
|
745
|
+
"type": "string",
|
|
746
|
+
"required": true
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"name": "department",
|
|
750
|
+
"type": "string"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
"name": "manager",
|
|
754
|
+
"type": "relation",
|
|
755
|
+
"relation": "employee"
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"name": "workLocation",
|
|
759
|
+
"type": "relation",
|
|
760
|
+
"relation": "location"
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
"name": "employmentType",
|
|
764
|
+
"type": "enum",
|
|
765
|
+
"items": ["full_time", "part_time", "contractor", "intern", "temporary"]
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
"name": "emergencyContact",
|
|
769
|
+
"type": "relation",
|
|
770
|
+
"relation": "contact"
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"name": "homeAddress",
|
|
774
|
+
"type": "relation",
|
|
775
|
+
"relation": "location"
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
"name": "dateOfBirth",
|
|
779
|
+
"type": "date"
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"name": "nationality",
|
|
783
|
+
"type": "string"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"name": "nationalId",
|
|
787
|
+
"type": "string"
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
"name": "socialSecurityNumber",
|
|
791
|
+
"type": "string"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"name": "taxId",
|
|
795
|
+
"type": "string"
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"name": "startDate",
|
|
799
|
+
"type": "date",
|
|
800
|
+
"required": true
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"name": "endDate",
|
|
804
|
+
"type": "date"
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
"name": "contractType",
|
|
808
|
+
"type": "string"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
"name": "salary",
|
|
812
|
+
"type": "number"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
"name": "salaryCurrency",
|
|
816
|
+
"type": "relation",
|
|
817
|
+
"relation": "currency"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"name": "payFrequency",
|
|
821
|
+
"type": "enum",
|
|
822
|
+
"items": ["weekly", "bi_weekly", "monthly"]
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
"name": "bankAccountNumber",
|
|
826
|
+
"type": "string"
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
"name": "bankName",
|
|
830
|
+
"type": "string"
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
"name": "iban",
|
|
834
|
+
"type": "string"
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
"name": "swiftBic",
|
|
838
|
+
"type": "string"
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"name": "workPermitNumber",
|
|
842
|
+
"type": "string"
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
"name": "workPermitExpiry",
|
|
846
|
+
"type": "date"
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
"name": "visaType",
|
|
850
|
+
"type": "string"
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
"name": "visaExpiry",
|
|
854
|
+
"type": "date"
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
"name": "skills",
|
|
858
|
+
"type": "array",
|
|
859
|
+
"itemsType": "string"
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"name": "notes",
|
|
863
|
+
"type": "richtext"
|
|
864
|
+
}
|
|
865
|
+
]
|
|
866
|
+
},
|
|
867
|
+
workflow: {
|
|
868
|
+
name: 'workflow',
|
|
869
|
+
"icon": "FaProjectDiagram",
|
|
870
|
+
description: "Defines an automated process.",
|
|
871
|
+
fields: [
|
|
872
|
+
{ name: 'name', type: 'string_t', required: true, hint: "Unique name for the workflow (e.g., 'Order Validation', 'Low Stock Notification')." },
|
|
873
|
+
{ name: 'description', type: 'richtext', hint: "Detailed explanation of the workflow's purpose." },
|
|
874
|
+
{ name: 'startStep', type: 'relation', relation: 'workflowStep', required: false, hint: "The first step to execute when the workflow starts." }
|
|
875
|
+
]
|
|
876
|
+
},
|
|
877
|
+
workflowTrigger: {
|
|
878
|
+
name: 'workflowTrigger',
|
|
879
|
+
"icon": "FaPlay",
|
|
880
|
+
description: "Represents an event that can initiate a workflow.",
|
|
881
|
+
fields: [
|
|
882
|
+
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
|
|
883
|
+
{ name: 'name', type: 'string_t', required: true, unique: true, hint: "Descriptive name for the trigger (e.g., 'New Order Created', 'Stock < 5', 'Monday 9 AM Report')." },
|
|
884
|
+
{
|
|
885
|
+
name: 'type',
|
|
886
|
+
type: 'enum',
|
|
887
|
+
items: ['manual', 'scheduled'],
|
|
888
|
+
required: true
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
name: 'onEvent',
|
|
892
|
+
type: 'enum',
|
|
893
|
+
items: ['DataAdded', 'DataEdited', 'DataDeleted', 'ModelAdded', 'ModelEdited', 'ModelDeleted'],
|
|
894
|
+
condition: { $eq: ["$type", "manual"] }
|
|
895
|
+
},
|
|
896
|
+
{ name: 'targetModel', type: 'model', condition: { // Condition pour afficher le champ
|
|
897
|
+
$and: [
|
|
898
|
+
{$eq: ["$type", "manual"]},
|
|
899
|
+
{
|
|
900
|
+
$or: [
|
|
901
|
+
{ $eq: ["$onEvent", "DataAdded"] },
|
|
902
|
+
{ $eq: ["$onEvent", "DataEdited"] },
|
|
903
|
+
{ $eq: ["$onEvent", "DataDeleted"] }
|
|
904
|
+
]
|
|
905
|
+
}
|
|
906
|
+
]
|
|
907
|
+
}},
|
|
908
|
+
{ name: 'dataFilter', type: 'code', language: 'json', targetModel: '$targetModel', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action.",
|
|
909
|
+
condition: { // Condition pour afficher le champ
|
|
910
|
+
$and: [
|
|
911
|
+
{$eq: ["$type", "manual"]},
|
|
912
|
+
{
|
|
913
|
+
$or: [
|
|
914
|
+
{ $eq: ["$onEvent", "DataAdded"] },
|
|
915
|
+
{ $eq: ["$onEvent", "DataEdited"] },
|
|
916
|
+
{ $eq: ["$onEvent", "DataDeleted"] }
|
|
917
|
+
]
|
|
918
|
+
}
|
|
919
|
+
]
|
|
920
|
+
}
|
|
921
|
+
},
|
|
922
|
+
{ name: 'env', type: 'code', language: 'json', hint: "Environment variables (JSON key/value pairs)",default: {} },
|
|
923
|
+
{ name: 'isActive', type: 'boolean' },
|
|
924
|
+
{ name: 'cronExpression', type: 'cronSchedule', cronMask:[false, true, true, true, true, true], hint: "Cron expression for scheduling (e.g., '0 9 * * 1' for Monday 9 AM) (used by Scheduled type).",
|
|
925
|
+
condition:
|
|
926
|
+
{$eq: ["$type", "scheduled"]}}
|
|
927
|
+
]
|
|
928
|
+
},
|
|
929
|
+
workflowStep: {
|
|
930
|
+
name: 'workflowStep',
|
|
931
|
+
"icon": "FaStepForward",
|
|
932
|
+
description: "A single step within a workflow process.",
|
|
933
|
+
fields: [
|
|
934
|
+
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
|
|
935
|
+
{ name: 'name', type: 'string_t', hint: "Optional descriptive name for the step (e.g., 'Check Inventory', 'Send Confirmation Email')." },
|
|
936
|
+
{ name: 'conditions', type: 'code', language: 'json', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action." },
|
|
937
|
+
{ name: 'actions', type: 'relation', relation: 'workflowAction', multiple: true, required: true, hint: "The main actions performed by this step." },
|
|
938
|
+
{ name: 'onSuccessStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if this step's action succeeds." },
|
|
939
|
+
{ name: 'onFailureStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if conditions fail or the action fails." },
|
|
940
|
+
{ name: 'isTerminal', type: 'boolean', default: false, hint: "Indicates if this step marks the end of a workflow path." }
|
|
941
|
+
]
|
|
942
|
+
},
|
|
943
|
+
workflowAction: {
|
|
944
|
+
name: 'workflowAction',
|
|
945
|
+
"icon": "FaCogs",
|
|
946
|
+
description: "Defines a specific operation to be performed by a workflow step.",
|
|
947
|
+
fields: [
|
|
948
|
+
{ name: 'name', type: 'string_t', required: true, hint: "Name of the action (e.g., 'Update Order Status', 'Send Email', 'Call Payment API')." },
|
|
949
|
+
{
|
|
950
|
+
name: 'type',
|
|
951
|
+
type: 'enum',
|
|
952
|
+
required: true,
|
|
953
|
+
items: ['UpdateData', 'CreateData', 'DeleteData', 'ExecuteScript', 'HttpRequest', 'SendEmail', 'Wait', 'GenerateAIContent', 'ExecuteServiceFunction'],
|
|
954
|
+
hint: "The type of operation to perform."
|
|
955
|
+
},
|
|
956
|
+
// For UpdateData / CreateData / DeleteData
|
|
957
|
+
{ name: 'targetModel', condition: {
|
|
958
|
+
$or: [
|
|
959
|
+
{$eq: ["$type", "CreateData"]},
|
|
960
|
+
{$eq: ["$type", "UpdateData"]},
|
|
961
|
+
{$eq: ["$type", "DeleteData"]}
|
|
962
|
+
]
|
|
963
|
+
}, type: 'model', hint: "Model to target" },
|
|
964
|
+
|
|
965
|
+
// For UpdateData / DeleteData
|
|
966
|
+
{ name: 'targetSelector', targetModel: "$targetModel", conditionBuilder: true, condition: {
|
|
967
|
+
$or: [
|
|
968
|
+
{$eq: ["$type", "UpdateData"]},
|
|
969
|
+
{$eq: ["$type", "DeleteData"]}
|
|
970
|
+
]
|
|
971
|
+
}, type: 'code', language: 'json', hint: "Expression to filter to the target document(s)." },
|
|
972
|
+
|
|
973
|
+
// For UpdateData
|
|
974
|
+
{ name: 'fieldsToUpdate', condition: {$eq: ["$type", "UpdateData"]}, type: 'code', language: 'json', default: {}, hint: "Key-value pairs of fields to update (e.g., { status: 'Validé', lastUpdated: '{now}' })" },
|
|
975
|
+
|
|
976
|
+
// For CreateData
|
|
977
|
+
{ name: 'dataToCreate', condition: {$eq: ["$type", "CreateData"]}, type: 'code', language: 'json', default: {}, hint: "Object template for the new document to create" },
|
|
978
|
+
|
|
979
|
+
// For HttpRequest
|
|
980
|
+
{ name: 'url', condition: {$eq: ["$type", "HttpRequest"]}, type: 'string', hint: "The URL to call." },
|
|
981
|
+
{ name: 'method', condition: {$eq: ["$type", "HttpRequest"]}, type: 'enum', items: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST', hint: "HTTP method." },
|
|
982
|
+
{ name: 'headers', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "HTTP headers as key-value pairs." },
|
|
983
|
+
{ name: 'body', condition: {$eq: ["$type", "HttpRequest"]}, type: 'code', language: 'json',default: {}, hint: "Request body, can include variables." },
|
|
984
|
+
|
|
985
|
+
// For SendEmail
|
|
986
|
+
{
|
|
987
|
+
name: 'emailRecipients',
|
|
988
|
+
type: 'array',
|
|
989
|
+
itemsType: 'string',
|
|
990
|
+
condition: { $eq: ["$type", "SendEmail"] },
|
|
991
|
+
hint: "Destinataire(s) de l'e-mail. Peut être une adresse, plusieurs adresses séparées par des virgules, ou une variable comme {triggerData.client.email}."
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
name: 'emailSubject',
|
|
995
|
+
type: 'string',
|
|
996
|
+
condition: { $eq: ["$type", "SendEmail"] },
|
|
997
|
+
hint: "Sujet de l'e-mail. Peut contenir des variables."
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
name: 'emailContent',
|
|
1001
|
+
type: 'richtext',
|
|
1002
|
+
condition: { $eq: ["$type", "SendEmail"] },
|
|
1003
|
+
hint: "Contenu de l'e-mail. Peut contenir des variables et du HTML."
|
|
1004
|
+
},
|
|
1005
|
+
|
|
1006
|
+
// For Wait
|
|
1007
|
+
{ name: 'duration', condition: {$eq: ["$type", "Wait"]}, type: 'number', hint: "Duration to wait." },
|
|
1008
|
+
{ name: 'durationUnit', condition:{$eq: ["$type", "Wait"]}, type: 'enum', items: ['milliseconds', 'seconds', 'minutes', 'hours', 'days'], default: 'seconds', hint: "Unit for the duration." },
|
|
1009
|
+
|
|
1010
|
+
// For GenerateAIContents
|
|
1011
|
+
{
|
|
1012
|
+
name: 'aiProvider',
|
|
1013
|
+
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1014
|
+
type: 'enum',
|
|
1015
|
+
items: ['OpenAI', 'GoogleGemini'], // Extensible avec d'autres fournisseurs
|
|
1016
|
+
hint: "Le fournisseur de LLM à utiliser."
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
name: 'aiModel',
|
|
1020
|
+
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1021
|
+
type: 'string',
|
|
1022
|
+
default: 'gpt-4o-mini', // Un défaut raisonnable
|
|
1023
|
+
hint: "Le modèle spécifique à utiliser (ex: gpt-4o-mini, gemini-1.5-pro-latest)."
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
name: 'prompt',
|
|
1027
|
+
condition: { $eq: ["$type", "GenerateAIContent"] },
|
|
1028
|
+
type: 'richtext', // richtext est bien pour les longs prompts
|
|
1029
|
+
hint: "Le modèle de prompt. Utilise des variables comme {triggerData.field} ou {context.variable}."
|
|
1030
|
+
},
|
|
1031
|
+
|
|
1032
|
+
// For ExecuteScript
|
|
1033
|
+
{ name: 'script', condition: {$eq: ["$type", "ExecuteScript"]}, type: 'code', language: 'javascript', hint: "The script to execute." },
|
|
1034
|
+
|
|
1035
|
+
// For ExecuteServiceFunction
|
|
1036
|
+
{ name: 'serviceName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the registered service to call (e.g., 'stripe')." },
|
|
1037
|
+
{ name: 'functionName', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'string', hint: "The name of the function to execute within the service." },
|
|
1038
|
+
{ name: 'args', condition: {$eq: ["$type", "ExecuteServiceFunction"]}, type: 'code', language: 'json', default: [], hint: "An array of arguments to pass to the function. Can include variables." }
|
|
1039
|
+
|
|
1040
|
+
]
|
|
1041
|
+
},
|
|
1042
|
+
|
|
1043
|
+
workflowRun: {
|
|
1044
|
+
name: 'workflowRun',
|
|
1045
|
+
"icon": "FaRunning",
|
|
1046
|
+
description: "Tracks a specific execution instance of a workflow.",
|
|
1047
|
+
fields: [
|
|
1048
|
+
{ name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow definition that was executed." },
|
|
1049
|
+
{ name: 'contextData', type: 'code', language: 'json',default: {}, hint: "Snapshot of the data or event that triggered this run." },
|
|
1050
|
+
{
|
|
1051
|
+
name: 'status',
|
|
1052
|
+
type: 'enum',
|
|
1053
|
+
required: true,
|
|
1054
|
+
items: ['pending', 'running', 'completed', 'failed', 'waiting', 'cancelled'],
|
|
1055
|
+
default: 'pending',
|
|
1056
|
+
hint: "The current status of the workflow execution."
|
|
1057
|
+
},
|
|
1058
|
+
{ name: 'stepExecutionsCount', type: 'object' },
|
|
1059
|
+
{ name: 'currentStep', type: 'relation', relation: 'workflowStep', hint: "The step currently being executed or waited on." },
|
|
1060
|
+
{ name: 'owner', type: 'relation', relation: 'user', required: false },
|
|
1061
|
+
{ name: 'startedAt', type: 'datetime', required: true, hint: "Timestamp when the workflow run began." },
|
|
1062
|
+
{ name: 'completedAt', type: 'datetime', hint: "Timestamp when the workflow run finished (successfully or failed)." },
|
|
1063
|
+
{ name: 'log', type: 'string', maxlength: 4096, hint: "Error message if the workflow run failed." }
|
|
1064
|
+
]
|
|
1065
|
+
},
|
|
1066
|
+
dashboard:{
|
|
1067
|
+
name: 'dashboard', // Nom technique du modèle
|
|
1068
|
+
"icon": "FaTachometerAlt",
|
|
1069
|
+
description: "Configuration d'un tableau de bord personnalisé par l'utilisateur.", // Description du modèle
|
|
1070
|
+
locked: false, // Indique si le modèle peut être modifié par l'utilisateur (false = modifiable)
|
|
1071
|
+
fields: [
|
|
1072
|
+
{
|
|
1073
|
+
name: 'name', // Nom du tableau de bord
|
|
1074
|
+
type: 'string', // Type texte simple
|
|
1075
|
+
required: true, // Ce champ est obligatoire
|
|
1076
|
+
hint: "Nom affiché et personnalisable du tableau de bord."
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
name: 'description', // Description optionnelle
|
|
1080
|
+
type: 'string', // Type texte simple (pourrait être 'richtext' si besoin de mise en forme)
|
|
1081
|
+
hint: "Description facultative pour donner plus de contexte au tableau de bord."
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
name: 'layout', // Configuration de la disposition des éléments
|
|
1085
|
+
type: 'code', // Utilisation du type 'code' pour stocker une structure JSON flexible
|
|
1086
|
+
language: 'json', // Précise que le contenu est du JSON
|
|
1087
|
+
required: true, // La disposition est essentielle
|
|
1088
|
+
default: { "type": "columns", "columns": [] }, // Valeur par défaut : une disposition en colonnes vide, stockée comme chaîne JSON
|
|
1089
|
+
hint: "Structure JSON décrivant l'organisation des KPIs. Exemple : { \"type\": \"columns\", \"columns\": [ [\"kpi_id_1\"], [\"kpi_id_2\", \"kpi_id_3\"] ] }."
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
name: 'refreshInterval',
|
|
1093
|
+
type: 'number',
|
|
1094
|
+
delay: true, // Sera interprété par le front-end comme un champ de durée
|
|
1095
|
+
unit: 's',
|
|
1096
|
+
min: 0,
|
|
1097
|
+
hint: "Intervalle de rafraîchissement automatique en secondes. Laisser vide ou à 0 pour désactiver."
|
|
1098
|
+
},
|
|
1099
|
+
{
|
|
1100
|
+
name: 'isDefault', // Indicateur pour le tableau de bord par défaut
|
|
1101
|
+
type: 'boolean', // Type booléen (vrai/faux)
|
|
1102
|
+
default: false, // Par défaut, un nouveau tableau de bord n'est pas celui par défaut
|
|
1103
|
+
hint: "Si 'true', ce tableau de bord est affiché par défaut pour l'utilisateur."
|
|
1104
|
+
}
|
|
1105
|
+
]
|
|
1106
|
+
},
|
|
1107
|
+
'request': {
|
|
1108
|
+
name: 'request',
|
|
1109
|
+
"icon": "FaExchangeAlt",
|
|
1110
|
+
description: "Journal des requêtes reçues par l'API.",
|
|
1111
|
+
locked: true, // Géré par le système, non modifiable directement par l'utilisateur via l'UI standard
|
|
1112
|
+
fields: [
|
|
1113
|
+
{
|
|
1114
|
+
name: 'timestamp',
|
|
1115
|
+
type: 'datetime',
|
|
1116
|
+
required: true,
|
|
1117
|
+
hint: "Date et heure exactes de la réception de la requête."
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
name: 'method',
|
|
1121
|
+
type: 'enum',
|
|
1122
|
+
items: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'],
|
|
1123
|
+
required: true,
|
|
1124
|
+
hint: "Méthode HTTP utilisée (GET, POST, etc.)."
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
name: 'url',
|
|
1128
|
+
type: 'string',
|
|
1129
|
+
required: true,
|
|
1130
|
+
multiline: false,
|
|
1131
|
+
maxlength: 2048, // Limite raisonnable pour une URL
|
|
1132
|
+
hint: "URL complète de la requête, incluant les query parameters."
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
name: 'status',
|
|
1136
|
+
type: 'number',
|
|
1137
|
+
step: 100,
|
|
1138
|
+
default: 200,
|
|
1139
|
+
required: true,
|
|
1140
|
+
hint: "Code de statut HTTP retourné par le serveur (ex: 200, 404, 500)."
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: 'latencyMs',
|
|
1144
|
+
type: 'number',
|
|
1145
|
+
required: true,
|
|
1146
|
+
color: '#e8c965',
|
|
1147
|
+
unit: 'ms',
|
|
1148
|
+
hint: "Temps de traitement de la requête par le serveur, en millisecondes."
|
|
1149
|
+
},
|
|
1150
|
+
{
|
|
1151
|
+
name: 'ip',
|
|
1152
|
+
type: 'string',
|
|
1153
|
+
hint: "Adresse IP du client ayant effectué la requête."
|
|
1154
|
+
},
|
|
1155
|
+
/*{
|
|
1156
|
+
name: 'requestHeaders',
|
|
1157
|
+
type: 'code',
|
|
1158
|
+
language: 'json',
|
|
1159
|
+
required: false,
|
|
1160
|
+
hint: "En-têtes HTTP de la requête (stockés sous forme de chaîne JSON). Peut être volumineux."
|
|
1161
|
+
},*/
|
|
1162
|
+
{
|
|
1163
|
+
name: 'requestBody', // Optionnel, peut être sensible/volumineux
|
|
1164
|
+
type: 'code',
|
|
1165
|
+
language: 'json', // Ou 'text' si ce n'est pas toujours du JSON
|
|
1166
|
+
required: false,
|
|
1167
|
+
hint: "Corps de la requête (stocké sous forme de chaîne JSON/texte). Attention: peut contenir des données sensibles et être volumineux."
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
name: 'responseBody', // Optionnel, peut être volumineux
|
|
1171
|
+
type: 'code',
|
|
1172
|
+
language: 'json', // Ou 'text'
|
|
1173
|
+
required: false,
|
|
1174
|
+
"condition": {
|
|
1175
|
+
"path": [
|
|
1176
|
+
"status"
|
|
1177
|
+
],
|
|
1178
|
+
"op": "$gte",
|
|
1179
|
+
"value": "400"
|
|
1180
|
+
},
|
|
1181
|
+
hint: "Corps de la réponse (stocké sous forme de chaîne JSON/texte). Attention: peut être volumineux."
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
name: 'error',
|
|
1185
|
+
type: 'string',
|
|
1186
|
+
maxlength: 4096, // Espace pour les messages d'erreur détaillés
|
|
1187
|
+
required: false,
|
|
1188
|
+
hint: "Message d'erreur si la requête a échoué côté serveur (ex: statut 500)."
|
|
1189
|
+
}
|
|
1190
|
+
]
|
|
1191
|
+
},
|
|
1192
|
+
|
|
1193
|
+
kpi : {
|
|
1194
|
+
name: 'kpi',
|
|
1195
|
+
"icon": "FaChartLine",
|
|
1196
|
+
description: "Configuration d'un Indicateur Clé de Performance (KPI)",
|
|
1197
|
+
fields: [
|
|
1198
|
+
{ name: 'name', type: 'string_t', required: true, hint: "Nom affiché du KPI (ex: Chiffre d'affaires total)" },
|
|
1199
|
+
{ name: 'description', type: 'string_t', hint: "Informations complémentaires sur le KPI" },
|
|
1200
|
+
{ name: 'targetModel', type: 'model', required: true, hint: "Nom du modèle sur lequel calculer le KPI (ex: order)" },
|
|
1201
|
+
{
|
|
1202
|
+
name: 'aggregationType',
|
|
1203
|
+
type: 'enum',
|
|
1204
|
+
required: true,
|
|
1205
|
+
items: ['count', 'sum', 'avg', 'min', 'max'], // Types d'agrégation courants
|
|
1206
|
+
hint: "Type de calcul à effectuer"
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
name: 'aggregationField',
|
|
1210
|
+
type: 'modelField',
|
|
1211
|
+
targetModel: '$targetModel',
|
|
1212
|
+
condition: { $ne: ["$aggregationType", "count"] },
|
|
1213
|
+
hint: "Nom du champ numérique sur lequel appliquer l'agrégation (ex: totalAmount). Non requis pour 'count'."
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
name: 'matchFormula',
|
|
1217
|
+
type: 'code', // Utiliser l'éditeur de code pour le JSON
|
|
1218
|
+
language: 'json',
|
|
1219
|
+
conditionBuilder: true,
|
|
1220
|
+
targetModel: '$targetModel',
|
|
1221
|
+
default: {}, // Valeur par défaut: aucun filtre
|
|
1222
|
+
hint: "Filtre JSON (MongoDB $match) à appliquer avant l'agrégation (ex: { \"status\": \"delivered\" })"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
"name": "showTotal",
|
|
1226
|
+
"hint": "Afficher le total",
|
|
1227
|
+
"type": "boolean"
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
"name": "showPercentTotal",
|
|
1231
|
+
"hint": "Afficher le total en %",
|
|
1232
|
+
"type": "boolean"
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
"name": "totalMatchFormula",
|
|
1236
|
+
"hint": "Formule pour le total (calcul %)",
|
|
1237
|
+
"type": "code",
|
|
1238
|
+
"language": "json",
|
|
1239
|
+
"required": false,
|
|
1240
|
+
"default": "{}",
|
|
1241
|
+
condition: { "$or": [
|
|
1242
|
+
{$eq: ["$showTotal", true]},
|
|
1243
|
+
{$eq: ["$showPercentTotal", true]}
|
|
1244
|
+
]}
|
|
1245
|
+
},
|
|
1246
|
+
{
|
|
1247
|
+
name: 'unit', // Optionnel: Unité à afficher avec la valeur
|
|
1248
|
+
type: 'string',
|
|
1249
|
+
hint: "Unité à afficher (ex: €, $, utilisateurs)"
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
name: 'icon', // Optionnel: Icône à afficher
|
|
1253
|
+
type: 'string', // Ou un type 'icon' si tu en as un
|
|
1254
|
+
hint: "Nom de l'icône (ex: FaUsers, FaShoppingCart)"
|
|
1255
|
+
},
|
|
1256
|
+
// Optionnel: Ajouter des champs pour le style, l'ordre d'affichage, etc.
|
|
1257
|
+
{ name: 'order', type: 'number', hint: "Ordre d'affichage sur un tableau de bord" },
|
|
1258
|
+
{ name: 'color', type: 'color', hint: "Couleur associée au KPI" }
|
|
1259
|
+
]
|
|
1260
|
+
},
|
|
1261
|
+
imageGallery: {
|
|
1262
|
+
name: 'imageGallery',
|
|
1263
|
+
"icon": "FaImages",
|
|
1264
|
+
description: "Représente une galerie d'images avec un titre et une description.",
|
|
1265
|
+
locked: false, // Les utilisateurs peuvent créer/gérer leurs galeries
|
|
1266
|
+
fields: [
|
|
1267
|
+
{
|
|
1268
|
+
name: 'name',
|
|
1269
|
+
type: 'string_t', // Titre traduisible
|
|
1270
|
+
required: true,
|
|
1271
|
+
asMain: true, // Champ principal pour l'affichage
|
|
1272
|
+
color: '#4CAF50', // Couleur indicative
|
|
1273
|
+
hint: "Le nom ou titre de la galerie d'images."
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
name: 'images',
|
|
1277
|
+
type: 'array',
|
|
1278
|
+
itemsType: 'file', // Type des éléments du tableau
|
|
1279
|
+
required: false, // Permet de créer une galerie vide initialement
|
|
1280
|
+
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], // Types d'images autorisés
|
|
1281
|
+
hint: "Les fichiers images de cette galerie."
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
name: 'description',
|
|
1285
|
+
type: 'richtext', // Description riche
|
|
1286
|
+
hint: "Description de la galerie (optionnel)."
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
name: 'tags',
|
|
1290
|
+
type: 'relation',
|
|
1291
|
+
relation: 'taxonomy', // Relation vers le modèle 'taxonomy'
|
|
1292
|
+
multiple: true, // Peut avoir plusieurs tags
|
|
1293
|
+
hint: "Tags ou catégories pour organiser les galeries (optionnel)."
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
name: 'createdAt',
|
|
1297
|
+
type: 'datetime',
|
|
1298
|
+
// Ce champ pourrait être rempli automatiquement par le système lors de la création
|
|
1299
|
+
hint: "Date de création de la galerie (généralement géré par le système)."
|
|
1300
|
+
}
|
|
1301
|
+
]
|
|
1302
|
+
},
|
|
1303
|
+
budget: {
|
|
1304
|
+
name: 'budget',
|
|
1305
|
+
"icon": "FaMoneyCheck",
|
|
1306
|
+
description: "Un budget permet de lister vos transactions personnelles.",
|
|
1307
|
+
fields: [
|
|
1308
|
+
{
|
|
1309
|
+
name: 'name',
|
|
1310
|
+
type: 'string_t',
|
|
1311
|
+
asMain: true,
|
|
1312
|
+
hint: "Nom ou description de la transaction (ex: Courses, Salaire Janvier)."
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
name: 'amount',
|
|
1316
|
+
type: 'number',
|
|
1317
|
+
step: 1,
|
|
1318
|
+
asMain: true,
|
|
1319
|
+
required: true,
|
|
1320
|
+
hint: "Montant de la transaction. Positif pour un revenu, négatif pour une dépense."
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
name: 'currency',
|
|
1324
|
+
type: 'relation',
|
|
1325
|
+
relation: 'currency',
|
|
1326
|
+
asMain: true,
|
|
1327
|
+
required: true,
|
|
1328
|
+
hint: "Devise de la transaction."
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
name: 'transactionDate',
|
|
1332
|
+
type: 'datetime',
|
|
1333
|
+
required: true,
|
|
1334
|
+
asMain: true,
|
|
1335
|
+
hint: "Date à laquelle la transaction a eu lieu."
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
name: 'description',
|
|
1339
|
+
type: 'richtext', // Pour des notes plus détaillées
|
|
1340
|
+
hint: "Notes ou détails supplémentaires sur la transaction."
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
name: 'paymentMethod',
|
|
1344
|
+
type: 'string', // Ou enum si vous avez une liste fixe
|
|
1345
|
+
hint: "Méthode de paiement utilisée (ex: Carte de crédit, Espèces, Virement)."
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
name: 'category',
|
|
1349
|
+
type: 'relation',
|
|
1350
|
+
relation: 'taxonomy', // Utiliser le modèle 'taxonomy' pour les catégories
|
|
1351
|
+
// Vous pourriez vouloir filtrer les taxonomies de type 'budget_category'
|
|
1352
|
+
hint: "Catégorie de la transaction (ex: Alimentation, Logement, Transport)."
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
name: 'isRecurring',
|
|
1356
|
+
type: 'boolean',
|
|
1357
|
+
default: false,
|
|
1358
|
+
hint: "Indique si cette transaction est récurrente."
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
name: 'recurringFrequency',
|
|
1362
|
+
type: 'enum',
|
|
1363
|
+
items: ['daily', 'weekly', 'monthly', 'yearly'],
|
|
1364
|
+
condition: {$eq: ["$isRecurring", true]}
|
|
1365
|
+
},
|
|
1366
|
+
{name: 'recurringEndDate', type: 'date', condition: {$eq: ["$isRecurring", true]}},
|
|
1367
|
+
{
|
|
1368
|
+
name: 'attachments',
|
|
1369
|
+
type: 'array',
|
|
1370
|
+
itemsType: 'file', // Pour joindre des reçus, factures, etc.
|
|
1371
|
+
hint: "Pièces jointes (reçus, factures)."
|
|
1372
|
+
}
|
|
1373
|
+
]
|
|
1374
|
+
},
|
|
1375
|
+
event: {
|
|
1376
|
+
"name": "event",
|
|
1377
|
+
"icon": "FaCalendar",
|
|
1378
|
+
"description": "A model for managing events, conferences, meetups, and gatherings.",
|
|
1379
|
+
"fields": [
|
|
1380
|
+
{
|
|
1381
|
+
"name": "title",
|
|
1382
|
+
"type": "string",
|
|
1383
|
+
"required": true,
|
|
1384
|
+
"asMain": true,
|
|
1385
|
+
"hint": "The title of the event"
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
"name": "description",
|
|
1389
|
+
"type": "richtext_t",
|
|
1390
|
+
"hint": "A detailed description of the event, including agenda, speakers, and other relevant information."
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
"name": "startDate",
|
|
1394
|
+
"type": "datetime",
|
|
1395
|
+
"required": true,
|
|
1396
|
+
"hint": "The starting date and time of the event"
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
"name": "endDate",
|
|
1400
|
+
"type": "datetime",
|
|
1401
|
+
"required": true,
|
|
1402
|
+
"hint": "The ending date and time of the event"
|
|
1403
|
+
},
|
|
1404
|
+
{
|
|
1405
|
+
"name": "location",
|
|
1406
|
+
"type": "relation",
|
|
1407
|
+
"relation": "location",
|
|
1408
|
+
"hint": "The venue or location where the event will be held. This could be a physical address or an online meeting link."
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
"name": "categories",
|
|
1412
|
+
"type": "relation",
|
|
1413
|
+
"relation": "taxonomy",
|
|
1414
|
+
"multiple": true,
|
|
1415
|
+
"hint": "Categories or tags associated with the event (e.g., \"conference\", \"workshop\", \"music\", \"technology\")."
|
|
1416
|
+
},
|
|
1417
|
+
{
|
|
1418
|
+
"name": "organizer",
|
|
1419
|
+
"type": "relation",
|
|
1420
|
+
"relation": "contact",
|
|
1421
|
+
"hint": "The name of the organization or individual hosting the event."
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
"name": "isOnline",
|
|
1425
|
+
"type": "boolean",
|
|
1426
|
+
"default": false,
|
|
1427
|
+
"hint": "Whether the event is online or in-person."
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
"name": "eventUrl",
|
|
1431
|
+
"type": "url",
|
|
1432
|
+
"hint": "A link to the official event webpage or registration page."
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
"name": "imageUrl",
|
|
1436
|
+
"type": "file",
|
|
1437
|
+
"hint": "URL of the event image or banner."
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
"name": "status",
|
|
1441
|
+
"type": "enum",
|
|
1442
|
+
"items": [
|
|
1443
|
+
"scheduled",
|
|
1444
|
+
"ongoing",
|
|
1445
|
+
"completed",
|
|
1446
|
+
"cancelled",
|
|
1447
|
+
"postponed"
|
|
1448
|
+
],
|
|
1449
|
+
"hint": "The current status of the event."
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
"name": "capacity",
|
|
1453
|
+
"type": "number",
|
|
1454
|
+
"hint": "The maximum number of attendees allowed for the event."
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
"name": "price",
|
|
1458
|
+
"type": "number",
|
|
1459
|
+
"hint": "The price of admission, if applicable."
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
"name": "currency",
|
|
1463
|
+
"type": "relation",
|
|
1464
|
+
"relation": "currency",
|
|
1465
|
+
"hint": "The currency for the price (e.g., USD, EUR)."
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
"name": "registrationDeadline",
|
|
1469
|
+
"type": "datetime",
|
|
1470
|
+
"hint": "The date by which attendees must register for the event."
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
"name": "attendees",
|
|
1474
|
+
"type": "relation",
|
|
1475
|
+
"relation": "contact",
|
|
1476
|
+
"multiple": true,
|
|
1477
|
+
"hint": "A relation to the contacts attending the event"
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
"name": "sponsors",
|
|
1481
|
+
"type": "relation",
|
|
1482
|
+
"relation": "contact",
|
|
1483
|
+
"multiple": true,
|
|
1484
|
+
"hint": "List of sponsors or partners involved in the event."
|
|
1485
|
+
}
|
|
1486
|
+
]
|
|
1487
|
+
},
|
|
1488
|
+
endpoint: {
|
|
1489
|
+
name: "endpoint",
|
|
1490
|
+
"icon": "FaCode",
|
|
1491
|
+
description: "Defines custom API endpoints that execute a server-side script.",
|
|
1492
|
+
fields: [
|
|
1493
|
+
{
|
|
1494
|
+
name: "isActive",
|
|
1495
|
+
type: "boolean",
|
|
1496
|
+
default: true,
|
|
1497
|
+
hint: "If checked, the endpoint is active and can be called."
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
name: "name",
|
|
1501
|
+
type: "string",
|
|
1502
|
+
required: true,
|
|
1503
|
+
asMain: true,
|
|
1504
|
+
hint: "A human-readable name to identify the endpoint."
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
name: "path",
|
|
1508
|
+
type: "string",
|
|
1509
|
+
required: true,
|
|
1510
|
+
hint: "The URL path after /api/actions/ (e.g., 'send-welcome-email'). Do not include '/'.",
|
|
1511
|
+
placeholder: "my-custom-action"
|
|
1512
|
+
},
|
|
1513
|
+
{
|
|
1514
|
+
name: "method",
|
|
1515
|
+
type: "enum",
|
|
1516
|
+
items: ["GET", "POST", "PUT", "PATCH", "DELETE"],
|
|
1517
|
+
required: true,
|
|
1518
|
+
default: "POST",
|
|
1519
|
+
hint: "The HTTP method required to call this endpoint."
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
name: "code",
|
|
1523
|
+
type: "code",
|
|
1524
|
+
language: "javascript",
|
|
1525
|
+
required: true,
|
|
1526
|
+
hint: "The script to execute. Must return a value or an object that will be the JSON response.",
|
|
1527
|
+
default: `// The script can access 'db', 'logger', 'env'.
|
|
1528
|
+
// request.body, request.query, request.params, request.headers available
|
|
1529
|
+
// The returned value will be the API's JSON response.
|
|
1530
|
+
|
|
1531
|
+
logger.info('Custom endpoint executed with body:', request.body);
|
|
1532
|
+
|
|
1533
|
+
return { success: true, message: 'Endpoint executed!', received: request.body };
|
|
1534
|
+
`
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
name: 'isPublic',
|
|
1538
|
+
type: 'boolean',
|
|
1539
|
+
default: false,
|
|
1540
|
+
hint: "Si coché, ce point d'accès sera accessible sans authentification."
|
|
1541
|
+
}
|
|
1542
|
+
]
|
|
1543
|
+
}
|
|
1544
|
+
};
|