data-primals-engine 1.0.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.
@@ -0,0 +1,1287 @@
1
+ // Définition des structures de modèles
2
+ export const defaultModels = {
3
+ permission: {
4
+ "name": "permission",
5
+ "description": "",
6
+ "fields": [
7
+ {
8
+ "name": "name",
9
+ "type": "string_t",
10
+ color: '#757BCC'
11
+ },
12
+ {
13
+ "name": "description",
14
+ "type": "richtext"
15
+ }
16
+ ]
17
+ },
18
+ role: {
19
+ name: 'role',
20
+ "description": "",
21
+ fields: [
22
+ { name: 'name', type: 'string_t', required: true, unique: true, color: '#363636' },
23
+ { name: 'permissions', type: 'relation', multiple: true, relation: 'permission' },
24
+ ],
25
+ },
26
+ user: {
27
+ name: 'user',
28
+ "description": "",
29
+ locked: true,
30
+ fields: [
31
+ { name: 'username', type: 'string', required: true, unique: true, color: '#3C7D08' },
32
+ { name: 'password', type: 'password' },
33
+ {
34
+ "name": "gender",
35
+ "type": "enum",
36
+ "items": ["male", "female", "other", "prefer_not_to_say"],
37
+ },
38
+ { name: 'contact', type: 'relation', relation: 'contact' },
39
+ { name: 'roles', type: 'relation', multiple: true, relation: 'role' },
40
+ { name: 'lang', type: 'relation', relation: 'lang', color: '#4CACCD' },
41
+ {
42
+ "name": "profilePicture",
43
+ "type": "file",
44
+ "mimeTypes": ["image/jpeg", "image/png"],
45
+ },
46
+ { name: 'tokens', type: 'relation', multiple: true, relation: 'token' },
47
+ ],
48
+ },
49
+ token: {
50
+ name: 'token',
51
+ "description": "",
52
+ fields: [
53
+ { name: 'name', type: 'string' },
54
+ { name: 'value', type: 'password' },
55
+ { name: 'lastRefresh', type: 'datetime' }
56
+ ],
57
+ },
58
+ translation: {
59
+ name: 'translation',
60
+ locked: true,
61
+ "description": "",
62
+ fields: [
63
+ { name: 'lang', type: 'relation', 'relation': 'lang', required: true, color: '#4CACCD' },
64
+ { name: 'key', type: 'string', maxlength: 200, required: true },
65
+ { name: 'value', type: 'string' },
66
+ ]
67
+ },
68
+ lang: {
69
+ name: 'lang',
70
+ locked: true,
71
+ "description": "",
72
+ fields: [
73
+ { name: 'name', unique: true, type: 'string_t', maxlength: 200, color: '#4CACCD' },
74
+ { name: 'code', type: 'string', maxlength: 5 },
75
+ ]
76
+ },
77
+ currency: {
78
+ name: 'currency',
79
+ "description": "",
80
+ locked: true,
81
+ fields: [
82
+ { name: 'symbol', type: 'string', required: true, color: '#E0E0E0', maxlength: 20, asMain: true },
83
+ { name: 'code', type: 'string', required: true, unique: true, maxlength: 3, asMain: true },
84
+ { name: 'name', type: 'string_t', required: true, color: '#AE6FA3' },
85
+ { name: 'exchangeRate', type: 'number', required: false },
86
+ { name: 'default', type: 'boolean', default: false }
87
+ ],
88
+ },
89
+ channel: {
90
+ name: 'channel',
91
+ "description": "",
92
+ fields: [
93
+ { name: 'name', type: 'string_t', required: true, unique: true }, // Nom du canal (ex: "email", "SMS")
94
+ { name: 'description', type: 'string_t' },
95
+ { name: 'type', type: 'enum', items: ['web', 'mobile', 'email', 'sms', 'push'], required: true }, // Type de canal
96
+ ],
97
+ },
98
+ message: {
99
+ name: 'message',
100
+ "description": "",
101
+ locked: true,
102
+ fields: [
103
+ { name: 'sender', type: 'relation', relation: 'user' }, // Utilisateur émetteur (si applicable, sinon système)
104
+ { name: 'recipient', type: 'relation', relation: 'user' }, // Utilisateur destinataire
105
+ { name: 'lang', type: 'relation', relation: 'lang' }, // Utilisateur destinataire
106
+ { name: 'subject', type: 'string' }, // Sujet de la notification (ex: titre de l'email)
107
+ { name: 'content', type: 'richtext', required: true }, // Contenu du message (localisable)
108
+ { name: 'channels', type: 'relation', multiple: true, relation: 'channel' }, // Canaux de diffusion (email, SMS, forum, etc.)
109
+ { name: 'status', type: 'enum', items: ['en attente', 'envoyée', 'lue', 'échouée'] },
110
+ { name: 'sentAt', type: 'datetime' },
111
+ { name: 'readAt', type: 'datetime' },
112
+ { name: 'type', type: 'string' }, // Type de notification (ex: "commande.miseAJour", "messageForum")
113
+ { name: 'priority', type: 'enum', items: ['basse', 'moyenne', 'haute'] },
114
+ ],
115
+ },
116
+ alert: {
117
+ name: "alert",
118
+ description: "Définit les règles pour les alertes et les insights automatiques.",
119
+ fields: [
120
+ { name: "name", type: "string", required: true, asMain: true },
121
+ { name: "targetModel", type: "model", required: true },
122
+ { name: "description", type: "string_t", multiline: true },
123
+ {
124
+ name: "triggerCondition",
125
+ type: "code",
126
+ language: "json",
127
+ conditionBuilder: true,
128
+ targetModel: '$targetModel',
129
+ required: true,
130
+ hint: "La condition qui, si elle est remplie, déclenchera l'alerte."
131
+ },
132
+ {
133
+ name: "frequency",
134
+ type: "cronSchedule",
135
+ required: true,
136
+ cronMask: [false, true, true, true, true, true],
137
+ hint: "À quelle fréquence vérifier si la condition est remplie."
138
+ },
139
+ {
140
+ name: "notificationChannel",
141
+ type: "enum",
142
+ items: ["in_app", "email"],
143
+ default: "in_app"
144
+ },
145
+ { name: "isActive", type: "boolean", default: true },
146
+ {
147
+ name: "lastNotifiedAt",
148
+ type: "datetime",
149
+ required: false, // Important: ce champ est géré par le système
150
+ hint: "Timestamp de la dernière notification envoyée pour cette alerte."
151
+ },
152
+ ]
153
+ },
154
+ env: {
155
+ name: "env",
156
+ description: "Définit les variables d'environnement qui seront accessibles dans vos scripts et webhooks.",
157
+ fields: [
158
+ { name: "name", type: "string", required: true, unique: true, asMain: true },
159
+ { name: "value", type: "string", anonymized: true, hiddenable: true }
160
+ ]
161
+ },
162
+ webpage: {
163
+ name: 'webpage',
164
+ locked: true,
165
+ "description": "",
166
+ fields: [
167
+ { name: 'title', type: 'string_t', required: true, color: '#659DE6' },
168
+ { name: 'path', type: 'string', required: true, unique: true, color: '#DEDEDE' },
169
+ { name: 'html', type: 'richtext' },
170
+ { name: 'published', type: 'boolean', default: false },
171
+ { name: 'inSitemap', type: 'boolean', default: true },
172
+ { name: 'description', type: 'string' },
173
+ { name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true },
174
+ { name: 'image', type: 'url' },
175
+ { name: 'category', type: 'relation', relation: 'taxonomy' },
176
+ ],
177
+ },
178
+ content: {
179
+ name: 'content',
180
+ "description": "",
181
+ fields: [
182
+ { name: 'lang', type: 'relation', relation: 'lang' },
183
+ { name: 'title', type: 'string_t', required: true },
184
+ { name: 'slug', type: 'string' },
185
+ { name: 'html', type: 'richtext_t' },
186
+ { name: 'image', type: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
187
+ { name: 'published', type: 'boolean' },
188
+ { name: 'publishedAt', type: 'datetime' },
189
+ { name: 'author', type: 'relation', relation: 'user' },
190
+ { name: 'category', type: 'relation', relation: 'taxonomy', "relationFilter": {
191
+ "path": [
192
+ "type"
193
+ ],
194
+ "op": "$eq",
195
+ "value": "category"
196
+ } },
197
+ { name: 'keywords', type: 'relation', relation: 'taxonomy', multiple: true, "relationFilter": {
198
+ "path": [
199
+ "type"
200
+ ],
201
+ "op": "$eq",
202
+ "value": "keyword"
203
+ } },
204
+ { name: 'order', type: 'number', step: 1, default: 0 },
205
+ { name: 'inSitemap', type: 'boolean', default: false },
206
+ ],
207
+ },
208
+ resource: {
209
+ name: 'resource',
210
+ "description": "",
211
+ fields: [
212
+ { name: "source", type: "url"},
213
+ { name: "file", type: "file"}
214
+ ]
215
+ },
216
+ taxonomy: {
217
+ name: 'taxonomy',
218
+ "description": "",
219
+ fields: [
220
+ { name: 'name', type: 'string_t', required: true, color: '#71A314' },
221
+ { name: 'parent', type: 'relation', relation: 'taxonomy', color: '#233607' }, // Relation vers la taxonomie parente
222
+ { name: 'type', type: 'enum', items: ['keyword', 'category'], color: '#BFBFBF' },
223
+ { name: 'identifier', type: 'string' },
224
+ { name: 'order', type: 'number', step: 1, default: 0 },
225
+ { name: 'description', type: 'richtext' },
226
+ ],
227
+ },
228
+ contact: {
229
+ locked: true,
230
+ name: 'contact',
231
+ "description": "",
232
+ fields: [
233
+ { name: 'legalName', type: 'string', asMain: true, color: '#D9D9D9' },
234
+ { name: 'firstName', type: 'string', asMain: true},
235
+ { name: 'lastName', type: 'string', asMain: true },
236
+ { name: 'email', type: 'email', color: '#F4ECE2' },
237
+ { name: 'phone', type: 'phone', color: '#B4A693' },
238
+ { name: 'location', type: 'relation', relation: 'location' },
239
+ ]
240
+ },
241
+
242
+ location: {
243
+ "name": "location",
244
+ locked: true,
245
+ "description": "",
246
+ "fields": [
247
+ {
248
+ "name": "address_1",
249
+ "type": "string",
250
+ asMain: true,
251
+ color: '#D6D6D6'
252
+ },
253
+ {
254
+ "name": "address_2",
255
+ "type": "string"
256
+ },
257
+ {
258
+ "name": "address_3",
259
+ "type": "string"
260
+ },
261
+ {
262
+ "name": "address_4",
263
+ "type": "string"
264
+ },
265
+ {
266
+ "name": "city",
267
+ "type": "string",
268
+ asMain: true,
269
+ color: '#E63345'
270
+ },
271
+ {
272
+ "name": "postalCode",
273
+ "type": "string",
274
+ asMain: true,
275
+ color: '#8B1D1D'
276
+ },
277
+ {
278
+ "name": "region",
279
+ "type": "string"
280
+ },
281
+ {
282
+ "name": "country",
283
+ "type": "string",
284
+ color: "#4F80BF",
285
+ asMain: true
286
+ },
287
+ {
288
+ "name": "latitude",
289
+ "type": "number",
290
+ "unit": "°"
291
+ },
292
+ {
293
+ "name": "longitude",
294
+ "type": "number",
295
+ "unit": "°"
296
+ },
297
+ ]
298
+ },
299
+
300
+ brand: {
301
+ name: 'brand',
302
+ "description": "",
303
+ fields: [
304
+ { name: 'name', type: 'string', required: true },
305
+ { name: 'logo', type: 'file' },
306
+ { name: 'company', type: 'relation', relation: 'contact' },
307
+ ],
308
+ },
309
+
310
+ product: {
311
+ name: 'product',
312
+ "description": "",
313
+ fields: [
314
+ { name: 'name', type: 'string_t', required: true },
315
+ { name: 'image', type: 'array', itemsType: 'file', mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
316
+ { name: 'description', type: 'richtext_t' },
317
+ { name: 'price', type: 'number', required: true },
318
+ { name: 'currency', type: 'relation', relation: 'currency', required: true },
319
+ { name: 'billingFrequency', type: 'enum', items: ['aucune', 'au mois', 'à l\'année'] },
320
+ { name: 'slug', type: 'string', required: true, unique: true },
321
+ { name: 'brand', type: 'relation', relation: 'brand' },
322
+ { name: 'category', type: 'relation', relation: 'taxonomy' },
323
+ { name: 'seoTitle', type: 'string_t' },
324
+ { name: 'seoDescription', type: 'string_t' },
325
+ ],
326
+ },
327
+ productVariant: {
328
+ name: 'productVariant',
329
+ "description": "",
330
+ fields: [
331
+ { name: 'product', type: 'relation', relation: 'product', required: true },
332
+ { name: 'size', type: 'string' },
333
+ { name: 'color', type: 'color' },
334
+ { name: 'sku', type: 'string', unique: true },
335
+ { name: 'price', type: 'number', required: true },
336
+ { name: 'currency', type: 'relation', relation: 'currency', required: true },
337
+ { name: 'stock', type: 'number', default: 0 },
338
+ { name: 'description', type: 'richtext' },
339
+ { name: 'image', type: 'url' },
340
+ ],
341
+ },
342
+ cart: {
343
+ name: 'cart',
344
+ "description": "",
345
+ fields: [
346
+ { name: 'user', type: 'relation', relation: 'user', required: true },
347
+ { name: 'items', type: 'relation', relation: 'cartItem', multiple: true },
348
+ { name: 'creationDate', type: 'datetime', required: true },
349
+ { name: 'lastUpdate', type: 'datetime', required: true },
350
+ { name: 'active', type: 'boolean', default: true },
351
+ ],
352
+ },
353
+ cartItem: {
354
+ name: 'cartItem',
355
+ "description": "",
356
+ fields: [
357
+ { name: 'product', type: 'relation', relation: 'product', required: true },
358
+ { name: 'quantity', type: 'number', required: true, min: 1, step: 1 },
359
+ { name: 'variant', type: 'relation', relation: 'productVariant' }, // Optionnel, si vous avez des variantes
360
+ ],
361
+ },
362
+ discount: {
363
+ name: "discount",
364
+ locked: true,
365
+ "description": "",
366
+ fields: [
367
+ { "name": "code", "type": "string", "required": true, "unique": true },
368
+ { "name": "productSelection", "type": "relation", "relation": "product", "required": false, multiple: true },
369
+ { "name": "description", "type": "richtext" },
370
+ { "name": "percentAmount", "type": "number", "unit": "%", default: null, min: 0 },
371
+ { "name": "fixedAmount", "type": "number", default: null, min: 0 },
372
+ { "name": "minAmount", "type": "number", "unit": "€", default: null, min: 0 }, // Montant minimum pour la promotion
373
+ { "name": "minProductQuantity", "type": "number", min: 0 }, // Montant minimum pour la promotion
374
+ { "name": "freeProductQuantity", "type": "number", default: null, min: 0 }, // Quantité de produits offerts
375
+ { "name": "startDate", "type": "datetime" },
376
+ { "name": "endDate", "type": "datetime" },
377
+ ]
378
+ },
379
+ order: {
380
+ name: "order",
381
+ locked: true,
382
+ "description": "",
383
+ fields: [
384
+ { "name": "orderId", "type": "string", "required": true, "unique": true },
385
+ { "name": "orderDate", "type": "datetime" },
386
+ { "name": "status", "type": "enum", items: ["pending", "processing", "shipped", "delivered", "cancelled"] },
387
+ { "name": "products", "type": "relation", "relation": "product", "required": true, multiple: true },
388
+ { "name": "customer", "type": "relation", relation: 'user' }, // Relation vers le modèle 'user'
389
+ { "name": "totalAmount", "type": "number", "required": true },
390
+ { "name": "currency", "type": "relation", "relation": "currency" },
391
+ { "name": "paymentMethod", "type": "string" },
392
+ { "name": "shippingAddress", "type": "relation", "relation": "location" },
393
+ { "name": "billingAddress", "type": "relation", "relation": "location" },
394
+ { "name": "shippedDate", "type": "datetime" },
395
+ { "name": "deliveryDate", "type": "datetime" },
396
+ { "name": "discount", "type": "relation", relation: 'discount' } // Relation vers le modèle 'promotion'
397
+ ]
398
+ },
399
+ invoice: {
400
+ name: 'invoice',
401
+ "description": "",
402
+ fields: [
403
+ { name: 'order', type: 'relation', relation: 'order', required: true },
404
+ { name: 'invoiceId', type: 'string', required: true, unique: true },
405
+ { name: 'invoiceDate', type: 'datetime', required: true },
406
+ { name: 'dueDate', type: 'datetime' },
407
+ { name: 'status', type: 'enum', items: ['payée', 'non payée', 'partiellement payée', 'annulée'] },
408
+ ],
409
+ },
410
+ userSubscription: {
411
+ name: 'userSubscription',
412
+ "description": "",
413
+ locked: true,
414
+ fields: [
415
+ { name: 'user', type: 'relation', relation: 'user', required: true },
416
+ { name: 'product', type: 'relation', relation: 'product', required: true },
417
+ { name: 'startDate', type: 'datetime', required: true },
418
+ { name: 'endDate', type: 'datetime' },
419
+ { name: 'price', type: 'number', required: true },
420
+ { name: 'currency', type: 'relation', relation: 'currency', required: true },
421
+ { name: 'paymentMethod', type: 'enum', items: ['carte bancaire', 'mandat SEPA'] },
422
+ { name: 'status', type: 'enum', items: ['actif', 'inactif', 'annulé', 'expiré', 'en attente'] },
423
+ { name: 'billingCycleAnchor', type: 'datetime' },
424
+ { name: 'nextBillingDate', type: 'datetime' },
425
+ { name: 'lastBillingDate', type: 'datetime' },
426
+ { name: 'cancelReason', type: 'string' },
427
+ { name: 'autoRenew', type: 'boolean', default: false },
428
+ ],
429
+ },
430
+ stock: {
431
+ name: 'stock',
432
+ "description": "",
433
+ fields: [
434
+ { name: 'product', type: 'relation', relation: 'product', required: true },
435
+ { name: 'variant', type: 'relation', relation: 'productVariant' }, // Optionnel
436
+ { name: 'warehouse', type: 'relation', relation: 'warehouse', required: true },
437
+ { name: 'available', type: 'number', default: 0 },
438
+ { name: 'reserved', type: 'number', default: 0 }, // Quantité réservée (pour les commandes en cours)
439
+ ],
440
+ },
441
+ stockAlert: {
442
+ name: 'stockAlert',
443
+ "description": "",
444
+ fields: [
445
+ { name: 'user', type: 'relation', relation: 'user', required: true },
446
+ { name: 'stock', type: 'relation', relation: 'stock', required: true },
447
+ { name: 'threshold', type: 'number', required: true, min: 0 },
448
+ ],
449
+ // how to implement unique fields on COMBINATION of multiple columns ?
450
+ },
451
+ shipment: {
452
+ name: 'shipment',
453
+ "description": "",
454
+ fields: [
455
+ { name: 'order', type: 'relation', relation: 'order', required: true },
456
+ { name: 'trackingNumber', type: 'string' },
457
+ { name: 'carrier', type: 'string' },
458
+ { name: 'status', type: 'enum', items: ['en attente', 'en transit', 'livrée', 'problème'] },
459
+ { name: 'estimatedDeliveryDate', type: 'datetime' },
460
+ { name: 'actualDeliveryDate', type: 'datetime' }
461
+ ],
462
+ },
463
+ warehouse: {
464
+ name: 'warehouse',
465
+ "description": "",
466
+ fields: [
467
+ { name: 'name', type: 'string_t', required: true },
468
+ { name: 'location', type: 'relation', relation: 'location' },
469
+ { name: 'capacity', type: 'number' },
470
+ ],
471
+ },
472
+ 'return': {
473
+ name: "return",
474
+ "description": "",
475
+ fields: [
476
+ { "name": "user", "type": "relation", relation: "user" },
477
+ { "name": "reason", "type": "string", maxlength: 2048, required: true },
478
+ { "name": "channel", "type": "relation", relation: 'channel' },
479
+ { "name": "status", "type": "enum", items: ["en attente", "approuvé", "remboursé", "refusé"] },
480
+ { name: 'amount', type: 'number', min: 0 },
481
+ { name: 'currency', type: 'relation', relation: 'currency' },
482
+ { name: 'refundDate', type: 'datetime' },
483
+ ]
484
+ },
485
+ returnItem: {
486
+ name: 'returnItem',
487
+ "description": "",
488
+ fields: [
489
+ { name: 'return', type: 'relation', relation: 'return', required: true },
490
+ { name: 'product', type: 'relation', relation: 'product', required: true },
491
+ { name: 'variant', type: 'relation', relation: 'productVariant' },
492
+ { name: 'quantity', type: 'number', required: true, min: 1 },
493
+ { name: 'condition', type: 'enum', items: ['neuf', 'très bon état', 'bon état', 'dégradé', 'endommagé', 'inutilisable'] }
494
+ ],
495
+ },
496
+ ticket: {
497
+ name: 'ticket',
498
+ "description": "",
499
+ locked: true,
500
+ fields: [
501
+ { name: 'user', type: 'relation', relation: 'user', required: true },
502
+ { name: 'order', type: 'relation', relation: 'order' },
503
+ { name: 'channel', type: 'relation', relation: 'channel' },
504
+ { name: 'parent', type: 'relation', relation: 'ticket' },
505
+ { name: 'subject', type: 'string', required: true },
506
+ { name: 'message', type: 'richtext', required: true },
507
+ { name: 'status', type: 'enum', items: ['ouvert', 'en cours', 'fermé'] },
508
+ { name: 'priority', type: 'enum', items: ['basse', 'moyenne', 'haute'] },
509
+ { name: 'assignedTo', type: 'relation', relation: 'user' },
510
+ { name: 'createdAt', type: 'datetime', required: true }
511
+ ],
512
+ },
513
+ campaign: {
514
+ name: 'campaign',
515
+ "description": "",
516
+ fields: [
517
+ { name: 'name', type: 'string_t', required: true },
518
+ { name: 'description', type: 'richtext' },
519
+ { name: 'startDate', type: 'datetime' },
520
+ { name: 'endDate', type: 'datetime' },
521
+ { name: 'type', type: 'enum', items: ['email', 'SMS', 'publicité', 'promotion'] },
522
+ { name: 'status', type: 'enum', items: ['planifiée', 'en cours', 'terminée', 'annulée'] },
523
+ { name: 'budget', type: 'number' }
524
+ ],
525
+ },
526
+ review: {
527
+ name: "review",
528
+ "description": "",
529
+ fields: [
530
+ { "name": "user", "type": "relation", relation: "user" },
531
+ { "name": "product", "type": "relation", relation: 'product' },
532
+ { "name": "productVariant", "type": "relation", relation: 'productVariant' },
533
+ { "name": "comment", "type": "richtext", maxlength: 2048, required: true },
534
+ { "name": "score", "type": "number" },
535
+ { "name": "publishedAt", "type": "datetime", required: true },
536
+ ]
537
+ },
538
+ device: {
539
+ name: "device",
540
+ "description": "",
541
+ fields: [
542
+ { "name": "location", "type": "relation", relation: 'location' },
543
+ { "name": "lastLocationUpdate", "type": "datetime" }
544
+ ]
545
+ },
546
+ // Modèle pour l'exercice comptable et l'entreprise
547
+ accountingExercise: {
548
+ name: 'accountingExercise',
549
+ description: "Représente un exercice comptable pour une entreprise donnée.",
550
+ fields: [
551
+ { name: 'name', type: 'string_t', 'required': true, unique: true, hint: "Intitulé de l'exercice comptable" },
552
+ { name: 'companyContact', type: 'relation', relation: 'contact', 'required': true, hint: "Désignation de l'entreprise" },
553
+ { name: 'companyIdentifier', type: 'string', asMain: true, hint: "SIRET de l'entreprise", unique: true },
554
+ { name: 'startDate', type: 'date', required: true, asMain: true, hint: "Date de début de l'exercice" },
555
+ { name: 'endDate', type: 'date', required: true, asMain: true, hint: "Date de clôture de l'exercice" },
556
+ ]
557
+ },
558
+
559
+ // Modèle pour définir la structure des lignes comptables (le "plan")
560
+ accountingLineItem: {
561
+ name: 'accountingLineItem',
562
+ description: "Définit une ligne/catégorie dans un document comptable.",
563
+ locked: true, // Probablement géré par l'application, pas par l'utilisateur final
564
+ fields: [
565
+ { name: 'accountingExercise', type: 'relation', required: true, unique: true, relation: "accountingExercise" },
566
+ { name: 'code', type: 'string', required: true, unique: true, hint: "Code unique de la ligne (ex: AA, FB, HA)" },
567
+ { name: 'label', type: 'string_t', required: true, hint: "Libellé de la ligne (ex: Frais d'établissement)" },
568
+ {
569
+ name: 'documentType', type: 'enum', required: true,
570
+ items: ['bilan_actif', 'bilan_passif', 'compte_resultat', 'immobilisations', 'amortissements', 'provisions', 'creances_dettes',
571
+ 'deficits',
572
+ 'plus_moins_values',
573
+ 'effectifs_valeur_ajoutee',
574
+ 'capital_social',
575
+ 'filiales_participations',
576
+ 'resultat_fiscal'],
577
+ },
578
+ { name: 'section', type: 'string_t', required: true, hint: "Section principale (ex: ACTIF IMMOBILISÉ)" },
579
+ { name: 'subSection', type: 'string_t', hint: "Sous-section (ex: IMMOBILISATIONS INCORPORELLES)" },
580
+ { name: 'order', type: 'number', hint: "Ordre d'affichage dans la section/sous-section" },
581
+ { name: 'calculationFormula', type: 'string', hint: "Formule de calcul (si applicable)" },
582
+ {
583
+ name: 'values', type: 'array', itemsType: 'number', required: true,
584
+ hint: "Valeurs de la ligne comptable"
585
+ },
586
+ { name: 'notes', type: 'richtext', hint: "Notes ou renvois (ex: (1), (3))" }
587
+ ]
588
+ },
589
+ accountingEntry: {
590
+ "name": "accountingEntry",
591
+ "description": "",
592
+ "fields": [
593
+ {
594
+ "name": "exercise",
595
+ "type": "relation",
596
+ "relation": "accountingExercise",
597
+ "required": true,
598
+ },
599
+ {
600
+ "name": "label",
601
+ "type": "string",
602
+ "required": true,
603
+ "asMain": true,
604
+ "maxlength": 255
605
+ },
606
+ {
607
+ "name": "entryDate",
608
+ "type": "date",
609
+ "required": true,
610
+ },
611
+ {
612
+ "name": "amount",
613
+ "type": "number",
614
+ "default": 0
615
+ },
616
+ {
617
+ "name": "currency",
618
+ "type": "relation",
619
+ "relation": "currency",
620
+ "required": true,
621
+ },
622
+ {
623
+ "name": "referenceNumber",
624
+ "type": "string",
625
+ "maxlength": 100
626
+ },
627
+ {
628
+ "name": "notes",
629
+ "type": "richtext"
630
+ },
631
+ {
632
+ "name": "status",
633
+ "type": "enum",
634
+ "items": ["brouillon", "validée", "annulée"],
635
+ "default": "brouillon"
636
+ },
637
+ {
638
+ "name": "createdBy",
639
+ "type": "relation",
640
+ "relation": "user"
641
+ },
642
+ {
643
+ "name": "validatedBy",
644
+ "type": "relation",
645
+ "relation": "user"
646
+ },
647
+ {
648
+ "name": "validationDate",
649
+ "type": "datetime"
650
+ },
651
+ {
652
+ "name": "attachments",
653
+ "type": "array",
654
+ "itemsType": "file"
655
+ }
656
+ ]
657
+ },
658
+ employee: {
659
+ "name": "employee",
660
+ "description": "",
661
+ "fields": [
662
+ {
663
+ "name": "employeeId",
664
+ "type": "string",
665
+ "required": true,
666
+ "unique": true
667
+ },
668
+ {
669
+ "name": "personalInfo",
670
+ "type": "relation",
671
+ "relation": "user",
672
+ "required": true
673
+ },
674
+ {
675
+ "name": "jobTitle",
676
+ "type": "string",
677
+ "required": true,
678
+ },
679
+ {
680
+ "name": "department",
681
+ "type": "string",
682
+ },
683
+ {
684
+ "name": "manager",
685
+ "type": "relation",
686
+ "relation": "employee",
687
+ },
688
+ {
689
+ "name": "workLocation",
690
+ "type": "relation",
691
+ "relation": "location",
692
+ },
693
+ {
694
+ "name": "employmentType",
695
+ "type": "enum",
696
+ "items": ["full_time", "part_time", "contractor", "intern", "temporary"]
697
+ },
698
+ {
699
+ "name": "emergencyContact",
700
+ "type": "relation",
701
+ "relation": "contact"
702
+ },
703
+ {
704
+ "name": "homeAddress",
705
+ "type": "relation",
706
+ "relation": "location",
707
+ },
708
+ {
709
+ "name": "dateOfBirth",
710
+ "type": "date"
711
+ },
712
+ {
713
+ "name": "nationality",
714
+ "type": "string"
715
+ },
716
+ {
717
+ "name": "nationalId",
718
+ "type": "string"
719
+ },
720
+ {
721
+ "name": "socialSecurityNumber",
722
+ "type": "string",
723
+ },
724
+ {
725
+ "name": "taxId",
726
+ "type": "string"
727
+ },
728
+ {
729
+ "name": "startDate",
730
+ "type": "date",
731
+ "required": true,
732
+ },
733
+ {
734
+ "name": "endDate",
735
+ "type": "date",
736
+ },
737
+ {
738
+ "name": "contractType",
739
+ "type": "string"
740
+ },
741
+ {
742
+ "name": "salary",
743
+ "type": "number",
744
+ },
745
+ {
746
+ "name": "salaryCurrency",
747
+ "type": "relation",
748
+ "relation": "currency",
749
+ },
750
+ {
751
+ "name": "payFrequency",
752
+ "type": "enum",
753
+ "items": ["weekly", "bi_weekly", "monthly"],
754
+ },
755
+ {
756
+ "name": "bankAccountNumber",
757
+ "type": "string",
758
+ },
759
+ {
760
+ "name": "bankName",
761
+ "type": "string",
762
+ },
763
+ {
764
+ "name": "iban",
765
+ "type": "string"
766
+ },
767
+ {
768
+ "name": "swiftBic",
769
+ "type": "string"
770
+ },
771
+ {
772
+ "name": "workPermitNumber",
773
+ "type": "string"
774
+ },
775
+ {
776
+ "name": "workPermitExpiry",
777
+ "type": "date"
778
+ },
779
+ {
780
+ "name": "visaType",
781
+ "type": "string"
782
+ },
783
+ {
784
+ "name": "visaExpiry",
785
+ "type": "date"
786
+ },
787
+ {
788
+ "name": "skills",
789
+ "type": "array",
790
+ "itemsType": "string",
791
+ },
792
+ {
793
+ "name": "notes",
794
+ "type": "richtext"
795
+ }
796
+ ]
797
+ },
798
+ workflow: {
799
+ name: 'workflow',
800
+ description: "Defines an automated process.",
801
+ fields: [
802
+ { name: 'name', type: 'string_t', required: true, hint: "Unique name for the workflow (e.g., 'Order Validation', 'Low Stock Notification')." },
803
+ { name: 'description', type: 'richtext', hint: "Detailed explanation of the workflow's purpose." },
804
+ { name: 'startStep', type: 'relation', relation: 'workflowStep', required: false, hint: "The first step to execute when the workflow starts." },
805
+ ]
806
+ },
807
+ workflowTrigger: {
808
+ name: 'workflowTrigger',
809
+ description: "Represents an event that can initiate a workflow.",
810
+ fields: [
811
+ { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
812
+ { 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')." },
813
+ {
814
+ name: 'type',
815
+ type: 'enum',
816
+ items: ['manual', 'scheduled'],
817
+ required: true,
818
+ },
819
+ {
820
+ name: 'onEvent',
821
+ type: 'enum',
822
+ items: ['DataAdded', 'DataEdited', 'DataDeleted', 'ModelAdded', 'ModelEdited', 'ModelDeleted'],
823
+ condition: { $eq: ["$type", "manual"] },
824
+ },
825
+ { name: 'targetModel', type: 'model', condition: { // Condition pour afficher le champ
826
+ $and: [
827
+ {$eq: ["$type", "manual"]},
828
+ {
829
+ $or: [
830
+ { path: "onEvent", op: "$eq", value: "DataAdded" },
831
+ { path: "onEvent", op: "$eq", value: "DataEdited" },
832
+ { path: "onEvent", op: "$eq", value: "DataDeleted" }
833
+ ]
834
+ }
835
+ ]
836
+ },},
837
+ { name: 'dataFilter', type: 'code', language: 'json', targetModel: '$targetModel', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action.",
838
+ condition: { // Condition pour afficher le champ
839
+ $and: [
840
+ {$eq: ["$type", "manual"]},
841
+ {
842
+ $or: [
843
+ { path: "onEvent", op: "$eq", value: "DataAdded" },
844
+ { path: "onEvent", op: "$eq", value: "DataEdited" },
845
+ { path: "onEvent", op: "$eq", value: "DataDeleted" }
846
+ ]
847
+ }
848
+ ]
849
+ },
850
+ },
851
+ { name: 'env', type: 'code', language: 'json', hint: "Environment variables (JSON key/value pairs)",default: {} },
852
+ { name: 'isActive', type: 'boolean' },
853
+ { 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).",
854
+ condition:
855
+ {$eq: ["$type", "scheduled"]}}
856
+ ]
857
+ },
858
+ workflowStep: {
859
+ name: 'workflowStep',
860
+ description: "A single step within a workflow process.",
861
+ fields: [
862
+ { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
863
+ { name: 'name', type: 'string_t', hint: "Optional descriptive name for the step (e.g., 'Check Inventory', 'Send Confirmation Email')." },
864
+ { name: 'conditions', type: 'code', language: 'json', conditionBuilder: true, hint: "Optional conditions checked before executing the step's action." },
865
+ { name: 'actions', type: 'relation', relation: 'workflowAction', multiple: true, required: true, hint: "The main actions performed by this step." },
866
+ { name: 'onSuccessStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if this step's action succeeds." },
867
+ { name: 'onFailureStep', type: 'relation', relation: 'workflowStep', hint: "Optional: The next step if conditions fail or the action fails." },
868
+ { name: 'isTerminal', type: 'boolean', default: false, hint: "Indicates if this step marks the end of a workflow path." }
869
+ ]
870
+ },
871
+ workflowAction: {
872
+ name: 'workflowAction',
873
+ description: "Defines a specific operation to be performed by a workflow step.",
874
+ fields: [
875
+ { name: 'name', type: 'string_t', required: true, hint: "Name of the action (e.g., 'Update Order Status', 'Send Email', 'Call Payment API')." },
876
+ {
877
+ name: 'type',
878
+ type: 'enum',
879
+ required: true,
880
+ items: ['UpdateData', 'CreateData', 'DeleteData', 'ExecuteScript', 'CallWebhook', 'SendEmail', 'Wait', 'GenerateAIContent'],
881
+ hint: "The type of operation to perform."
882
+ },
883
+ // For UpdateData / CreateData / DeleteData
884
+ { name: 'targetModel', condition: {
885
+ $or: [
886
+
887
+ {$eq: ["$type", "CreateData"]},
888
+ {$eq: ["$type", "UpdateData"]},
889
+ {$eq: ["$type", "DeleteData"]},
890
+ ]
891
+ }, type: 'model', hint: "Model to target" },
892
+
893
+ // For UpdateData / DeleteData
894
+ { name: 'targetSelector', targetModel: "$targetModel", conditionBuilder: true, condition: {
895
+ $or: [
896
+ {$eq: ["$type", "UpdateData"]},
897
+ {$eq: ["$type", "DeleteData"]},
898
+ ]
899
+ }, type: 'code', language: 'json', hint: "Expression to filter to the target document(s)." },
900
+
901
+ // For UpdateData
902
+ { 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}' })" },
903
+
904
+ // For CreateData
905
+ { name: 'dataToCreate', condition: {$eq: ["$type", "CreateData"]}, type: 'code', language: 'json', default: {}, hint: "Object template for the new document to create" },
906
+
907
+ // For ExecuteScript
908
+ { name: 'script', condition: {$eq: ["$type", "ExecuteScript"]}, type: 'code', hint: "The script to execute." },
909
+
910
+ // For CallWebhook
911
+ { name: 'url', condition: {$eq: ["$type", "CallWebhook"]}, type: 'string', hint: "The URL to call." },
912
+ { name: 'method', condition: {$eq: ["$type", "CallWebhook"]}, type: 'enum', items: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], default: 'POST', hint: "HTTP method." },
913
+ { name: 'headers', condition: {$eq: ["$type", "CallWebhook"]}, type: 'code', language: 'json',default: {}, hint: "HTTP headers as key-value pairs." },
914
+ { name: 'body', condition: {$eq: ["$type", "CallWebhook"]}, type: 'code', language: 'json',default: {}, hint: "Request body, can include variables." },
915
+
916
+ // For SendEmail
917
+ {
918
+ name: 'emailRecipients',
919
+ type: 'array',
920
+ itemsType: 'string',
921
+ condition: { $eq: ["$type", "SendEmail"] },
922
+ 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}."
923
+ },
924
+ {
925
+ name: 'emailSubject',
926
+ type: 'string',
927
+ condition: { $eq: ["$type", "SendEmail"] },
928
+ hint: "Sujet de l'e-mail. Peut contenir des variables."
929
+ },
930
+ {
931
+ name: 'emailContent',
932
+ type: 'richtext',
933
+ condition: { $eq: ["$type", "SendEmail"] },
934
+ hint: "Contenu de l'e-mail. Peut contenir des variables et du HTML."
935
+ },
936
+
937
+ // For Wait
938
+ { name: 'duration', condition: {$eq: ["$type", "Wait"]}, type: 'number', hint: "Duration to wait." },
939
+ { name: 'durationUnit', condition:{$eq: ["$type", "Wait"]}, type: 'enum', items: ['milliseconds', 'seconds', 'minutes', 'hours', 'days'], default: 'seconds', hint: "Unit for the duration." },
940
+
941
+ // For GenerateAIContents
942
+ {
943
+ name: 'aiProvider',
944
+ condition: { $eq: ["$type", "GenerateAIContent"] },
945
+ type: 'enum',
946
+ items: ['OpenAI', 'GoogleGemini'], // Extensible avec d'autres fournisseurs
947
+ hint: "Le fournisseur de LLM à utiliser."
948
+ },
949
+ {
950
+ name: 'aiModel',
951
+ condition: { $eq: ["$type", "GenerateAIContent"] },
952
+ type: 'string',
953
+ default: 'gpt-4o-mini', // Un défaut raisonnable
954
+ hint: "Le modèle spécifique à utiliser (ex: gpt-4o-mini, gemini-1.5-pro-latest)."
955
+ },
956
+ {
957
+ name: 'prompt',
958
+ condition: { $eq: ["$type", "GenerateAIContent"] },
959
+ type: 'richtext', // richtext est bien pour les longs prompts
960
+ hint: "Le modèle de prompt. Utilise des variables comme {triggerData.field} ou {context.variable}."
961
+ },
962
+
963
+ ]
964
+ },
965
+
966
+ workflowRun: {
967
+ name: 'workflowRun',
968
+ description: "Tracks a specific execution instance of a workflow.",
969
+ fields: [
970
+ { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow definition that was executed." },
971
+ { name: 'contextData', type: 'code', language: 'json',default: {}, hint: "Snapshot of the data or event that triggered this run." },
972
+ {
973
+ name: 'status',
974
+ type: 'enum',
975
+ required: true,
976
+ items: ['pending', 'running', 'completed', 'failed', 'waiting', 'cancelled'],
977
+ default: 'pending',
978
+ hint: "The current status of the workflow execution."
979
+ },
980
+ { name: 'stepExecutionsCount', type: 'object' },
981
+ { name: 'currentStep', type: 'relation', relation: 'workflowStep', hint: "The step currently being executed or waited on." },
982
+ { name: 'owner', type: 'relation', relation: 'user', required: false },
983
+ { name: 'startedAt', type: 'datetime', required: true, hint: "Timestamp when the workflow run began." },
984
+ { name: 'completedAt', type: 'datetime', hint: "Timestamp when the workflow run finished (successfully or failed)." },
985
+ { name: 'error', type: 'string', maxlength: 4096, hint: "Error message if the workflow run failed." },
986
+ ]
987
+ },
988
+ dashboard:{
989
+ name: 'dashboard', // Nom technique du modèle
990
+ description: "Configuration d'un tableau de bord personnalisé par l'utilisateur.", // Description du modèle
991
+ locked: false, // Indique si le modèle peut être modifié par l'utilisateur (false = modifiable)
992
+ fields: [
993
+ {
994
+ name: 'name', // Nom du tableau de bord
995
+ type: 'string', // Type texte simple
996
+ required: true, // Ce champ est obligatoire
997
+ hint: "Nom affiché et personnalisable du tableau de bord."
998
+ },
999
+ {
1000
+ name: 'description', // Description optionnelle
1001
+ type: 'string', // Type texte simple (pourrait être 'richtext' si besoin de mise en forme)
1002
+ hint: "Description facultative pour donner plus de contexte au tableau de bord."
1003
+ },
1004
+ {
1005
+ name: 'layout', // Configuration de la disposition des éléments
1006
+ type: 'code', // Utilisation du type 'code' pour stocker une structure JSON flexible
1007
+ language: 'json', // Précise que le contenu est du JSON
1008
+ required: true, // La disposition est essentielle
1009
+ default: { "type": "columns", "columns": [] }, // Valeur par défaut : une disposition en colonnes vide, stockée comme chaîne JSON
1010
+ hint: "Structure JSON décrivant l'organisation des KPIs. Exemple : { \"type\": \"columns\", \"columns\": [ [\"kpi_id_1\"], [\"kpi_id_2\", \"kpi_id_3\"] ] }."
1011
+ },
1012
+ {
1013
+ name: 'settings', // Paramètres spécifiques à ce tableau de bord
1014
+ type: 'code', // Utilisation du type 'code' pour stocker des paramètres JSON
1015
+ language: 'json',
1016
+ default: { "defaultTimeRange": "last_7_days", "refreshInterval": null }, // Paramètres par défaut (plage de temps, pas de rafraîchissement auto)
1017
+ hint: "Paramètres JSON pour le tableau de bord, comme la plage de temps par défaut ('defaultTimeRange') ou l'intervalle de rafraîchissement en secondes ('refreshInterval')."
1018
+ },
1019
+ {
1020
+ name: 'isDefault', // Indicateur pour le tableau de bord par défaut
1021
+ type: 'boolean', // Type booléen (vrai/faux)
1022
+ default: false, // Par défaut, un nouveau tableau de bord n'est pas celui par défaut
1023
+ hint: "Si 'true', ce tableau de bord est affiché par défaut pour l'utilisateur."
1024
+ }
1025
+ ]
1026
+ },
1027
+ 'request': {
1028
+ name: 'request',
1029
+ description: "Journal des requêtes reçues par l'API.",
1030
+ locked: true, // Géré par le système, non modifiable directement par l'utilisateur via l'UI standard
1031
+ fields: [
1032
+ {
1033
+ name: 'timestamp',
1034
+ type: 'datetime',
1035
+ required: true,
1036
+ hint: "Date et heure exactes de la réception de la requête."
1037
+ },
1038
+ {
1039
+ name: 'method',
1040
+ type: 'enum',
1041
+ items: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'],
1042
+ required: true,
1043
+ hint: "Méthode HTTP utilisée (GET, POST, etc.)."
1044
+ },
1045
+ {
1046
+ name: 'url',
1047
+ type: 'string',
1048
+ required: true,
1049
+ multiline: false,
1050
+ maxlength: 2048, // Limite raisonnable pour une URL
1051
+ hint: "URL complète de la requête, incluant les query parameters."
1052
+ },
1053
+ {
1054
+ name: 'status',
1055
+ type: 'number',
1056
+ step: 100,
1057
+ default: 200,
1058
+ required: true,
1059
+ hint: "Code de statut HTTP retourné par le serveur (ex: 200, 404, 500)."
1060
+ },
1061
+ {
1062
+ name: 'latencyMs',
1063
+ type: 'number',
1064
+ required: true,
1065
+ color: '#e8c965',
1066
+ unit: 'ms',
1067
+ hint: "Temps de traitement de la requête par le serveur, en millisecondes."
1068
+ },
1069
+ {
1070
+ name: 'ip',
1071
+ type: 'string',
1072
+ hint: "Adresse IP du client ayant effectué la requête."
1073
+ },
1074
+ /*{
1075
+ name: 'requestHeaders',
1076
+ type: 'code',
1077
+ language: 'json',
1078
+ required: false,
1079
+ hint: "En-têtes HTTP de la requête (stockés sous forme de chaîne JSON). Peut être volumineux."
1080
+ },*/
1081
+ {
1082
+ name: 'requestBody', // Optionnel, peut être sensible/volumineux
1083
+ type: 'code',
1084
+ language: 'json', // Ou 'text' si ce n'est pas toujours du JSON
1085
+ required: false,
1086
+ hint: "Corps de la requête (stocké sous forme de chaîne JSON/texte). Attention: peut contenir des données sensibles et être volumineux."
1087
+ },
1088
+ {
1089
+ name: 'responseBody', // Optionnel, peut être volumineux
1090
+ type: 'code',
1091
+ language: 'json', // Ou 'text'
1092
+ required: false,
1093
+ "condition": {
1094
+ "path": [
1095
+ "status"
1096
+ ],
1097
+ "op": "$gte",
1098
+ "value": "400"
1099
+ },
1100
+ hint: "Corps de la réponse (stocké sous forme de chaîne JSON/texte). Attention: peut être volumineux."
1101
+ },
1102
+ {
1103
+ name: 'error',
1104
+ type: 'string',
1105
+ maxlength: 4096, // Espace pour les messages d'erreur détaillés
1106
+ required: false,
1107
+ hint: "Message d'erreur si la requête a échoué côté serveur (ex: statut 500)."
1108
+ }
1109
+ ]
1110
+ },
1111
+
1112
+ kpi : {
1113
+ name: 'kpi',
1114
+ description: "Configuration d'un Indicateur Clé de Performance (KPI)",
1115
+ fields: [
1116
+ { name: 'name', type: 'string_t', required: true, hint: "Nom affiché du KPI (ex: Chiffre d'affaires total)" },
1117
+ { name: 'description', type: 'string_t', hint: "Informations complémentaires sur le KPI" },
1118
+ { name: 'targetModel', type: 'model', required: true, hint: "Nom du modèle sur lequel calculer le KPI (ex: order)" },
1119
+ {
1120
+ name: 'aggregationType',
1121
+ type: 'enum',
1122
+ required: true,
1123
+ items: ['count', 'sum', 'avg', 'min', 'max'], // Types d'agrégation courants
1124
+ hint: "Type de calcul à effectuer"
1125
+ },
1126
+ {
1127
+ name: 'aggregationField',
1128
+ type: 'string',
1129
+ hint: "Nom du champ numérique sur lequel appliquer l'agrégation (ex: totalAmount). Non requis pour 'count'."
1130
+ },
1131
+ {
1132
+ name: 'matchFormula',
1133
+ type: 'code', // Utiliser l'éditeur de code pour le JSON
1134
+ language: 'json',
1135
+ default: {}, // Valeur par défaut: aucun filtre
1136
+ hint: "Filtre JSON (MongoDB $match) à appliquer avant l'agrégation (ex: { \"status\": \"delivered\" })"
1137
+ },
1138
+ {
1139
+ "name": "showTotal",
1140
+ "hint": "Afficher le total",
1141
+ "type": "boolean"
1142
+ },
1143
+ {
1144
+ "name": "showPercentTotal",
1145
+ "hint": "Afficher le total en %",
1146
+ "type": "boolean"
1147
+ },
1148
+ {
1149
+ "name": "totalMatchFormula",
1150
+ "hint": "Formule pour le total (calcul %)",
1151
+ "type": "code",
1152
+ "language": "json",
1153
+ "required": false,
1154
+ "default": "{}",
1155
+ condition: { "$or": [
1156
+ {$eq: ["$showTotal", true]},
1157
+ {$eq: ["$showPercentTotal", true]},
1158
+ ]}
1159
+ },
1160
+ {
1161
+ name: 'unit', // Optionnel: Unité à afficher avec la valeur
1162
+ type: 'string',
1163
+ hint: "Unité à afficher (ex: €, $, utilisateurs)"
1164
+ },
1165
+ {
1166
+ name: 'icon', // Optionnel: Icône à afficher
1167
+ type: 'string', // Ou un type 'icon' si tu en as un
1168
+ hint: "Nom de l'icône (ex: FaUsers, FaShoppingCart)"
1169
+ },
1170
+ // Optionnel: Ajouter des champs pour le style, l'ordre d'affichage, etc.
1171
+ { name: 'order', type: 'number', hint: "Ordre d'affichage sur un tableau de bord" },
1172
+ { name: 'color', type: 'color', hint: "Couleur associée au KPI" }
1173
+ ]
1174
+ },
1175
+ imageGallery: {
1176
+ name: 'imageGallery',
1177
+ description: "Représente une galerie d'images avec un titre et une description.",
1178
+ locked: false, // Les utilisateurs peuvent créer/gérer leurs galeries
1179
+ fields: [
1180
+ {
1181
+ name: 'name',
1182
+ type: 'string_t', // Titre traduisible
1183
+ required: true,
1184
+ asMain: true, // Champ principal pour l'affichage
1185
+ color: '#4CAF50', // Couleur indicative
1186
+ hint: "Le nom ou titre de la galerie d'images."
1187
+ },
1188
+ {
1189
+ name: 'images',
1190
+ type: 'array',
1191
+ itemsType: 'file', // Type des éléments du tableau
1192
+ required: false, // Permet de créer une galerie vide initialement
1193
+ mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], // Types d'images autorisés
1194
+ hint: "Les fichiers images de cette galerie."
1195
+ },
1196
+ {
1197
+ name: 'description',
1198
+ type: 'richtext', // Description riche
1199
+ hint: "Description de la galerie (optionnel)."
1200
+ },
1201
+ {
1202
+ name: 'tags',
1203
+ type: 'relation',
1204
+ relation: 'taxonomy', // Relation vers le modèle 'taxonomy'
1205
+ multiple: true, // Peut avoir plusieurs tags
1206
+ hint: "Tags ou catégories pour organiser les galeries (optionnel)."
1207
+ },
1208
+ {
1209
+ name: 'createdAt',
1210
+ type: 'datetime',
1211
+ // Ce champ pourrait être rempli automatiquement par le système lors de la création
1212
+ hint: "Date de création de la galerie (généralement géré par le système)."
1213
+ }
1214
+ ]
1215
+ },
1216
+ budget: {
1217
+ name: 'budget',
1218
+ description: "Un budget permet de lister vos transactions personnelles.",
1219
+ fields: [
1220
+ {
1221
+ name: 'name',
1222
+ type: 'string_t',
1223
+ asMain: true,
1224
+ hint: "Nom ou description de la transaction (ex: Courses, Salaire Janvier)."
1225
+ },
1226
+ {
1227
+ name: 'amount',
1228
+ type: 'number',
1229
+ step: 1,
1230
+ asMain: true,
1231
+ required: true,
1232
+ hint: "Montant de la transaction. Positif pour un revenu, négatif pour une dépense."
1233
+ },
1234
+ {
1235
+ name: 'currency',
1236
+ type: 'relation',
1237
+ relation: 'currency',
1238
+ asMain: true,
1239
+ required: true,
1240
+ hint: "Devise de la transaction."
1241
+ },
1242
+ {
1243
+ name: 'transactionDate',
1244
+ type: 'datetime',
1245
+ required: true,
1246
+ asMain: true,
1247
+ hint: "Date à laquelle la transaction a eu lieu."
1248
+ },
1249
+ {
1250
+ name: 'description',
1251
+ type: 'richtext', // Pour des notes plus détaillées
1252
+ hint: "Notes ou détails supplémentaires sur la transaction."
1253
+ },
1254
+ {
1255
+ name: 'paymentMethod',
1256
+ type: 'string', // Ou enum si vous avez une liste fixe
1257
+ hint: "Méthode de paiement utilisée (ex: Carte de crédit, Espèces, Virement)."
1258
+ },
1259
+ {
1260
+ name: 'category',
1261
+ type: 'relation',
1262
+ relation: 'taxonomy', // Utiliser le modèle 'taxonomy' pour les catégories
1263
+ // Vous pourriez vouloir filtrer les taxonomies de type 'budget_category'
1264
+ hint: "Catégorie de la transaction (ex: Alimentation, Logement, Transport)."
1265
+ },
1266
+ {
1267
+ name: 'isRecurring',
1268
+ type: 'boolean',
1269
+ default: false,
1270
+ hint: "Indique si cette transaction est récurrente."
1271
+ },
1272
+ {
1273
+ name: 'recurringFrequency',
1274
+ type: 'enum',
1275
+ items: ['daily', 'weekly', 'monthly', 'yearly'],
1276
+ condition: {$eq: ["$isRecurring", true]}
1277
+ },
1278
+ {name: 'recurringEndDate', type: 'date', condition: {$eq: ["$isRecurring", true]}},
1279
+ {
1280
+ name: 'attachments',
1281
+ type: 'array',
1282
+ itemsType: 'file', // Pour joindre des reçus, factures, etc.
1283
+ hint: "Pièces jointes (reçus, factures)."
1284
+ },
1285
+ ]
1286
+ }
1287
+ };