boondmanager-mcp-server 1.7.4 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/schemas/index.d.ts +50 -2
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +531 -168
- package/dist/schemas/index.js.map +1 -1
- package/dist/services/boond-client.d.ts +1 -5
- package/dist/services/boond-client.d.ts.map +1 -1
- package/dist/services/boond-client.js +85 -13
- package/dist/services/boond-client.js.map +1 -1
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +9 -2
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/reporting.d.ts.map +1 -1
- package/dist/tools/reporting.js +46 -8
- package/dist/tools/reporting.js.map +1 -1
- package/dist/tools/timesheets.d.ts.map +1 -1
- package/dist/tools/timesheets.js +8 -5
- package/dist/tools/timesheets.js.map +1 -1
- package/dist/tools/validations.d.ts.map +1 -1
- package/dist/tools/validations.js +12 -2
- package/dist/tools/validations.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +1 -1
package/dist/schemas/index.js
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, MAX_SEARCH_PAGE } from "../constants.js";
|
|
3
3
|
// Common search schema
|
|
4
|
-
export const SearchSchema = z
|
|
4
|
+
export const SearchSchema = z
|
|
5
|
+
.object({
|
|
5
6
|
keywords: z.string().optional().describe("Mots-clés de recherche (nom, email, compétences...)"),
|
|
6
|
-
page: z
|
|
7
|
-
|
|
7
|
+
page: z
|
|
8
|
+
.number()
|
|
9
|
+
.int()
|
|
10
|
+
.min(1)
|
|
11
|
+
.max(MAX_SEARCH_PAGE)
|
|
12
|
+
.default(1)
|
|
13
|
+
.describe(`Numéro de page (défaut: 1, max: ${MAX_SEARCH_PAGE})`),
|
|
14
|
+
pageSize: z
|
|
15
|
+
.number()
|
|
16
|
+
.int()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(MAX_PAGE_SIZE)
|
|
19
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
8
20
|
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
9
|
-
})
|
|
21
|
+
})
|
|
22
|
+
.strict();
|
|
10
23
|
// ---- Reusable filter field helpers ----
|
|
11
24
|
// IMPORTANT: input field names below MUST match the BoondManager API query parameter names
|
|
12
25
|
// exactly (e.g., perimeterManagers, resourceStates, opportunityStates). buildSearchQuery
|
|
13
26
|
// passes them through as `key[]=value` for arrays. See https://doc.boondmanager.com/api-externe/
|
|
14
|
-
const pageField = z
|
|
15
|
-
|
|
27
|
+
const pageField = z
|
|
28
|
+
.number()
|
|
29
|
+
.int()
|
|
30
|
+
.min(1)
|
|
31
|
+
.max(MAX_SEARCH_PAGE)
|
|
32
|
+
.default(1)
|
|
33
|
+
.describe(`Numéro de page (défaut: 1, max: ${MAX_SEARCH_PAGE})`);
|
|
34
|
+
const pageSizeField = z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(MAX_PAGE_SIZE)
|
|
39
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
16
40
|
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`);
|
|
17
41
|
const sortField = z.string().optional().describe("Champ de tri (ex: lastName, firstName, updateDate)");
|
|
18
42
|
const orderField = z.enum(["asc", "desc"]).optional().describe("Ordre de tri (asc/desc)");
|
|
@@ -20,29 +44,58 @@ const intArray = (doc) => z.array(z.number().int()).optional().describe(doc);
|
|
|
20
44
|
const strArray = (doc) => z.array(z.string()).optional().describe(doc);
|
|
21
45
|
// Shared "perimeter" filters available on every entity search (from RAML trait `searchable`).
|
|
22
46
|
// These are the CORRECT filters for "my team / my agency / my N-1" — NOT the old `mainManagers`.
|
|
23
|
-
const perimeterManagersField = intArray("IDs des managers (ressources). Conserve les entités dont le responsable est l'un de ces managers. "
|
|
24
|
-
|
|
47
|
+
const perimeterManagersField = intArray("IDs des managers (ressources). Conserve les entités dont le responsable est l'un de ces managers. " +
|
|
48
|
+
"Pour 'mon équipe / N-1 d'une personne X', passer [X_id]. Obtenir son propre ID via boond_application_current_user.");
|
|
25
49
|
const perimeterAgenciesField = intArray("IDs d'agences. Conserve les entités dont le responsable appartient à ces agences.");
|
|
26
50
|
const perimeterPolesField = intArray("IDs de pôles. Conserve les entités dont le responsable appartient à ces pôles.");
|
|
27
51
|
const perimeterBusinessUnitsField = intArray("IDs de business units. Conserve les entités dont le responsable appartient à ces BU.");
|
|
28
|
-
const perimeterDynamicField = z
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
const perimeterDynamicField = z
|
|
53
|
+
.array(z.enum(["data", "agencies", "poles", "businessUnits", "managers"]))
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("Périmètre dynamique relatif à l'utilisateur courant (raccourci sans avoir à connaître son propre ID). " +
|
|
56
|
+
"Valeurs : 'data' (mes propres données), 'managers' (mon équipe / mes N-1), 'agencies' (mes agences), " +
|
|
57
|
+
"'poles' (mes pôles), 'businessUnits' (mes BU). Combinable.");
|
|
58
|
+
const narrowPerimeterField = z
|
|
59
|
+
.boolean()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Si true, jointure ET entre les filtres `perimeter*` (au lieu de OU par défaut).");
|
|
62
|
+
const startDateField = z
|
|
63
|
+
.string()
|
|
64
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
65
|
+
.optional()
|
|
33
66
|
.describe("Date de début (YYYY-MM-DD), à utiliser avec `period`.");
|
|
34
|
-
const endDateField = z
|
|
67
|
+
const endDateField = z
|
|
68
|
+
.string()
|
|
69
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
70
|
+
.optional()
|
|
35
71
|
.describe("Date de fin (YYYY-MM-DD), à utiliser avec `period`.");
|
|
36
72
|
// ---- Resource search schema (collaborateurs internes) ----
|
|
37
73
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/resources/search.raml
|
|
38
|
-
export const ResourceSearchSchema = z
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
74
|
+
export const ResourceSearchSchema = z
|
|
75
|
+
.object({
|
|
76
|
+
keywords: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("Mots-clés (par défaut, recherche dans CV + dossier technique). Pour cibler un champ précis, " +
|
|
80
|
+
"fournir aussi `keywordsType` (ex: lastName, firstName, fullName, emails, title, titleSkills, phones, reference)."),
|
|
81
|
+
keywordsType: z
|
|
82
|
+
.enum([
|
|
83
|
+
"resumeTd",
|
|
84
|
+
"lastName",
|
|
85
|
+
"firstName",
|
|
86
|
+
"fullName",
|
|
87
|
+
"strictFullName",
|
|
88
|
+
"emails",
|
|
89
|
+
"title",
|
|
90
|
+
"titleSkills",
|
|
91
|
+
"phones",
|
|
92
|
+
"reference",
|
|
93
|
+
"resume",
|
|
94
|
+
"td",
|
|
95
|
+
])
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Champ ciblé par `keywords`. Défaut: 'resumeTd' (CV + dossier technique). " +
|
|
98
|
+
"Pour 'fullName' utiliser `keywords = 'NOM#PRENOM'`."),
|
|
46
99
|
perimeterManagers: perimeterManagersField,
|
|
47
100
|
perimeterAgencies: perimeterAgenciesField,
|
|
48
101
|
perimeterPoles: perimeterPolesField,
|
|
@@ -55,46 +108,84 @@ export const ResourceSearchSchema = z.object({
|
|
|
55
108
|
excludeResourceTypes: intArray("IDs de types de ressource à EXCLURE."),
|
|
56
109
|
activityAreas: strArray("IDs de secteurs d'activité (dictionnaire setting.activityArea)."),
|
|
57
110
|
expertiseAreas: strArray("IDs de domaines d'expertise (dictionnaire setting.expertiseArea)."),
|
|
58
|
-
tools: strArray("IDs d'outils/technos (dictionnaire setting.tool). Logique OU par défaut. "
|
|
59
|
-
|
|
111
|
+
tools: strArray("IDs d'outils/technos (dictionnaire setting.tool). Logique OU par défaut. " +
|
|
112
|
+
"Pour ET, ajouter '#AND#' en 1er élément: tools=['#AND#','12','34']."),
|
|
60
113
|
experiences: intArray("IDs de niveaux d'expérience (dictionnaire setting.experience)."),
|
|
61
114
|
trainings: strArray("IDs de formations (dictionnaire setting.training)."),
|
|
62
115
|
mobilityAreas: strArray("IDs de zones de mobilité (dictionnaire setting.mobilityArea)."),
|
|
63
116
|
languages: strArray("Langues parlées au format `langueId|niveauId` (dictionnaires setting.languageSpoken et setting.languageLevel). Ex: ['anglais|courant']."),
|
|
64
117
|
flags: intArray("IDs de tags (drapeaux) attachés à la ressource."),
|
|
65
|
-
period: z
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
118
|
+
period: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe("Champ temporel pour filtrer par période. Valeurs courantes: 'available' (disponibilité), " +
|
|
122
|
+
"'working' (en mission hors interne), 'workingAll', 'absent', 'idle', 'hired', 'left', " +
|
|
123
|
+
"'employed', 'unemployed', 'updated', 'arrival', 'birthday', 'seniority', 'present', " +
|
|
124
|
+
"'noAction'/'withActions'/'withoutActions'/'withAbsences'/'withoutAbsences'. " +
|
|
125
|
+
"À combiner avec `startDate` + `endDate`."),
|
|
70
126
|
startDate: startDateField,
|
|
71
127
|
endDate: endDateField,
|
|
72
128
|
providerCompanies: intArray("IDs de sociétés sous-traitantes (filtre pour ressources externes)."),
|
|
73
|
-
coordinates: z
|
|
74
|
-
|
|
75
|
-
|
|
129
|
+
coordinates: z
|
|
130
|
+
.string()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe("Coordonnées GPS 'latitude,longitude' pour recherche géographique. À combiner avec `geoDistance`."),
|
|
133
|
+
location: z
|
|
134
|
+
.string()
|
|
135
|
+
.optional()
|
|
136
|
+
.describe("Adresse texte (ville, etc.) pour recherche géographique. À combiner avec `geoDistance`."),
|
|
137
|
+
geoDistance: z
|
|
138
|
+
.number()
|
|
139
|
+
.int()
|
|
140
|
+
.min(5)
|
|
141
|
+
.max(200)
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("Rayon en km pour la recherche géographique (5-200). Requis si `coordinates` ou `location` est fourni."),
|
|
76
144
|
excludeManager: z.boolean().optional().describe("Si true, ne retourne que les ressources sans compte manager."),
|
|
77
|
-
shields: z
|
|
145
|
+
shields: z
|
|
146
|
+
.array(z.enum(["uncomplete", "minimum", "complete"]))
|
|
147
|
+
.optional()
|
|
78
148
|
.describe("Niveau de complétude des champs conditionnels."),
|
|
79
149
|
sort: sortField,
|
|
80
150
|
order: orderField,
|
|
81
151
|
page: pageField,
|
|
82
152
|
pageSize: pageSizeField,
|
|
83
|
-
})
|
|
153
|
+
})
|
|
154
|
+
.strict();
|
|
84
155
|
// ---- Candidate search schema ----
|
|
85
156
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/candidates/search.raml
|
|
86
|
-
export const CandidateSearchSchema = z
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
157
|
+
export const CandidateSearchSchema = z
|
|
158
|
+
.object({
|
|
159
|
+
keywords: z
|
|
160
|
+
.string()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe("Mots-clés (par défaut, recherche dans CV + dossier technique). Combinable avec `keywordsType`."),
|
|
163
|
+
keywordsType: z
|
|
164
|
+
.enum([
|
|
165
|
+
"resumeTd",
|
|
166
|
+
"lastName",
|
|
167
|
+
"firstName",
|
|
168
|
+
"fullName",
|
|
169
|
+
"strictFullName",
|
|
170
|
+
"emails",
|
|
171
|
+
"title",
|
|
172
|
+
"titleSkills",
|
|
173
|
+
"phones",
|
|
174
|
+
"reference",
|
|
175
|
+
"resume",
|
|
176
|
+
"td",
|
|
177
|
+
])
|
|
178
|
+
.optional()
|
|
179
|
+
.describe("Champ ciblé par `keywords` (défaut: 'resumeTd')."),
|
|
92
180
|
perimeterManagers: perimeterManagersField,
|
|
93
181
|
perimeterAgencies: perimeterAgenciesField,
|
|
94
182
|
perimeterPoles: perimeterPolesField,
|
|
95
183
|
perimeterBusinessUnits: perimeterBusinessUnitsField,
|
|
96
184
|
perimeterDynamic: perimeterDynamicField,
|
|
97
|
-
perimeterManagersType: z
|
|
185
|
+
perimeterManagersType: z
|
|
186
|
+
.enum(["main", "hr"])
|
|
187
|
+
.optional()
|
|
188
|
+
.describe("Type de responsable visé par `perimeterManagers`: 'main' (Main Manager) ou 'hr' (HR Manager)."),
|
|
98
189
|
narrowPerimeter: narrowPerimeterField,
|
|
99
190
|
candidateStates: intArray("IDs d'états de candidat (dictionnaire setting.state.candidate via boond_application_dictionary)."),
|
|
100
191
|
candidateTypes: intArray("IDs de types de candidat (dictionnaire setting.typeOf.resource)."),
|
|
@@ -110,31 +201,51 @@ export const CandidateSearchSchema = z.object({
|
|
|
110
201
|
evaluations: strArray("IDs d'évaluations."),
|
|
111
202
|
sources: strArray("IDs de sources de recrutement (dictionnaire setting.source)."),
|
|
112
203
|
flags: intArray("IDs de tags."),
|
|
113
|
-
period: z
|
|
114
|
-
|
|
204
|
+
period: z
|
|
205
|
+
.string()
|
|
206
|
+
.optional()
|
|
207
|
+
.describe("Filtre temporel : 'created', 'updated', 'available', " +
|
|
208
|
+
"'noAction'/'withActions'/'withoutActions'. À combiner avec `startDate` + `endDate`."),
|
|
115
209
|
startDate: startDateField,
|
|
116
210
|
endDate: endDateField,
|
|
117
211
|
providerCompanies: intArray("IDs de sociétés sous-traitantes."),
|
|
118
212
|
coordinates: z.string().optional().describe("Coordonnées GPS 'lat,lon'. Requiert `geoDistance`."),
|
|
119
213
|
location: z.string().optional().describe("Adresse texte. Requiert `geoDistance`."),
|
|
120
214
|
geoDistance: z.number().int().min(5).max(200).optional().describe("Rayon km (5-200)."),
|
|
121
|
-
shields: z
|
|
215
|
+
shields: z
|
|
216
|
+
.array(z.enum(["uncomplete", "minimum", "complete"]))
|
|
217
|
+
.optional()
|
|
122
218
|
.describe("Niveau de complétude."),
|
|
123
219
|
sort: sortField,
|
|
124
220
|
order: orderField,
|
|
125
221
|
page: pageField,
|
|
126
222
|
pageSize: pageSizeField,
|
|
127
|
-
})
|
|
223
|
+
})
|
|
224
|
+
.strict();
|
|
128
225
|
// ---- Contact search schema ----
|
|
129
226
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/contacts/search.raml
|
|
130
|
-
export const ContactSearchSchema = z
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
227
|
+
export const ContactSearchSchema = z
|
|
228
|
+
.object({
|
|
229
|
+
keywords: z
|
|
230
|
+
.string()
|
|
231
|
+
.optional()
|
|
232
|
+
.describe("Mots-clés (défaut: nom + prénom + société + fonction + périmètre technique). " +
|
|
233
|
+
"Combinable avec `keywordsType`."),
|
|
234
|
+
keywordsType: z
|
|
235
|
+
.enum([
|
|
236
|
+
"default",
|
|
237
|
+
"lastName",
|
|
238
|
+
"firstName",
|
|
239
|
+
"fullName",
|
|
240
|
+
"strictFullName",
|
|
241
|
+
"companyFullName",
|
|
242
|
+
"emails",
|
|
243
|
+
"phones",
|
|
244
|
+
"socialNetworks",
|
|
245
|
+
])
|
|
246
|
+
.optional()
|
|
247
|
+
.describe("Champ ciblé. Défaut: 'default'. Pour 'fullName' utiliser `keywords = 'NOM#PRENOM'`. " +
|
|
248
|
+
"Pour 'companyFullName' utiliser `keywords = 'CSOCid#NOM#PRENOM'`."),
|
|
138
249
|
perimeterManagers: perimeterManagersField,
|
|
139
250
|
perimeterAgencies: perimeterAgenciesField,
|
|
140
251
|
perimeterPoles: perimeterPolesField,
|
|
@@ -143,32 +254,44 @@ export const ContactSearchSchema = z.object({
|
|
|
143
254
|
narrowPerimeter: narrowPerimeterField,
|
|
144
255
|
states: intArray("IDs d'états de contact (dictionnaire setting.state.contact)."),
|
|
145
256
|
companyStates: intArray("IDs d'états des sociétés rattachées (dictionnaire setting.state.company)."),
|
|
146
|
-
typesOf: intArray("IDs de types de contact (dictionnaire setting.typeOf.contact). "
|
|
147
|
-
|
|
257
|
+
typesOf: intArray("IDs de types de contact (dictionnaire setting.typeOf.contact). " +
|
|
258
|
+
"⚠️ Le paramètre s'appelle `typesOf` (avec un 's'), PAS `typeOf`."),
|
|
148
259
|
origins: strArray("IDs d'origines (dictionnaire setting.origin)."),
|
|
149
260
|
activityAreas: strArray("IDs de secteurs d'activité de la société."),
|
|
150
261
|
expertiseAreas: strArray("IDs de domaines d'expertise de la société."),
|
|
151
262
|
tools: strArray("IDs d'outils. Logique OU par défaut, '#AND#' en 1er pour ET."),
|
|
152
263
|
influencers: intArray("IDs de contacts influenceurs."),
|
|
153
264
|
flags: intArray("IDs de tags."),
|
|
154
|
-
period: z
|
|
155
|
-
|
|
265
|
+
period: z
|
|
266
|
+
.string()
|
|
267
|
+
.optional()
|
|
268
|
+
.describe("Filtre temporel : 'created', 'updated', 'noAction'/'withActions'/'withoutActions'. " +
|
|
269
|
+
"À combiner avec `startDate` + `endDate`."),
|
|
156
270
|
startDate: startDateField,
|
|
157
271
|
endDate: endDateField,
|
|
158
|
-
completeness: strArray("Filtre par complétude des champs au format `fieldId:mode` (fieldId: email/phone/socialNetworks ; "
|
|
159
|
-
|
|
160
|
-
shields: z
|
|
272
|
+
completeness: strArray("Filtre par complétude des champs au format `fieldId:mode` (fieldId: email/phone/socialNetworks ; " +
|
|
273
|
+
"mode: empty/filled). Logique OU par défaut, '#AND#' en 1er pour ET. Ex: ['email:empty','phone:empty']."),
|
|
274
|
+
shields: z
|
|
275
|
+
.array(z.enum(["uncomplete", "minimum", "complete"]))
|
|
276
|
+
.optional()
|
|
161
277
|
.describe("Niveau de complétude."),
|
|
162
278
|
sort: sortField,
|
|
163
279
|
order: orderField,
|
|
164
280
|
page: pageField,
|
|
165
281
|
pageSize: pageSizeField,
|
|
166
|
-
})
|
|
282
|
+
})
|
|
283
|
+
.strict();
|
|
167
284
|
// ---- Company search schema ----
|
|
168
285
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/companies/search.raml
|
|
169
|
-
export const CompanySearchSchema = z
|
|
170
|
-
|
|
171
|
-
|
|
286
|
+
export const CompanySearchSchema = z
|
|
287
|
+
.object({
|
|
288
|
+
keywords: z
|
|
289
|
+
.string()
|
|
290
|
+
.optional()
|
|
291
|
+
.describe("Mots-clés (défaut: nom + ville + pays + expertise + informations). Combinable avec `keywordsType`."),
|
|
292
|
+
keywordsType: z
|
|
293
|
+
.enum(["default", "name", "phones", "emails", "socialNetworks"])
|
|
294
|
+
.optional()
|
|
172
295
|
.describe("Champ ciblé par `keywords`. Défaut: 'default'."),
|
|
173
296
|
perimeterManagers: perimeterManagersField,
|
|
174
297
|
perimeterAgencies: perimeterAgenciesField,
|
|
@@ -181,29 +304,41 @@ export const CompanySearchSchema = z.object({
|
|
|
181
304
|
origins: strArray("IDs d'origines (dictionnaire setting.origin)."),
|
|
182
305
|
influencers: intArray("IDs d'influenceurs."),
|
|
183
306
|
flags: intArray("IDs de tags."),
|
|
184
|
-
period: z
|
|
185
|
-
|
|
307
|
+
period: z
|
|
308
|
+
.string()
|
|
309
|
+
.optional()
|
|
310
|
+
.describe("Filtre temporel : 'created', 'updated', 'noAction'/'withActions'/'withoutActions'. " +
|
|
311
|
+
"À combiner avec `startDate` + `endDate`."),
|
|
186
312
|
startDate: startDateField,
|
|
187
313
|
endDate: endDateField,
|
|
188
|
-
shields: z
|
|
314
|
+
shields: z
|
|
315
|
+
.array(z.enum(["uncomplete", "minimum", "complete"]))
|
|
316
|
+
.optional()
|
|
189
317
|
.describe("Niveau de complétude."),
|
|
190
318
|
sort: sortField,
|
|
191
319
|
order: orderField,
|
|
192
320
|
page: pageField,
|
|
193
321
|
pageSize: pageSizeField,
|
|
194
|
-
})
|
|
322
|
+
})
|
|
323
|
+
.strict();
|
|
195
324
|
// ---- Opportunity search schema ----
|
|
196
325
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/opportunities/search.raml
|
|
197
|
-
export const OpportunitySearchSchema = z
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
326
|
+
export const OpportunitySearchSchema = z
|
|
327
|
+
.object({
|
|
328
|
+
keywords: z
|
|
329
|
+
.string()
|
|
330
|
+
.optional()
|
|
331
|
+
.describe("Mots-clés. Pour cibler par ID préfixé : 'AOnnn' (opportunité), 'CSOCnnn' (société), " +
|
|
332
|
+
"'CCONnnn' (contact), 'CANDnnn' (candidat), 'COMPnnn' (ressource), 'PRODnnn' (produit). " +
|
|
333
|
+
"Sinon recherche plein texte sur titre/société."),
|
|
201
334
|
perimeterManagers: perimeterManagersField,
|
|
202
335
|
perimeterAgencies: perimeterAgenciesField,
|
|
203
336
|
perimeterPoles: perimeterPolesField,
|
|
204
337
|
perimeterBusinessUnits: perimeterBusinessUnitsField,
|
|
205
338
|
perimeterDynamic: perimeterDynamicField,
|
|
206
|
-
perimeterManagersType: z
|
|
339
|
+
perimeterManagersType: z
|
|
340
|
+
.enum(["main", "hr"])
|
|
341
|
+
.optional()
|
|
207
342
|
.describe("Type de responsable visé par `perimeterManagers` (main/hr)."),
|
|
208
343
|
narrowPerimeter: narrowPerimeterField,
|
|
209
344
|
opportunityStates: intArray("IDs d'états d'opportunité (dictionnaire setting.state.opportunity)."),
|
|
@@ -216,23 +351,33 @@ export const OpportunitySearchSchema = z.object({
|
|
|
216
351
|
durations: intArray("IDs de durées (dictionnaire setting.duration)."),
|
|
217
352
|
origins: strArray("IDs d'origines."),
|
|
218
353
|
flags: intArray("IDs de tags."),
|
|
219
|
-
period: z
|
|
220
|
-
|
|
221
|
-
|
|
354
|
+
period: z
|
|
355
|
+
.string()
|
|
356
|
+
.optional()
|
|
357
|
+
.describe("Filtre temporel : 'created' (création), 'started', 'closingDate' (date de closing), " +
|
|
358
|
+
"'updated', 'updatedPositioning', 'noAction'/'withActions'/'withoutActions'. " +
|
|
359
|
+
"À combiner avec `startDate` + `endDate`."),
|
|
222
360
|
startDate: startDateField,
|
|
223
361
|
endDate: endDateField,
|
|
224
|
-
shields: z
|
|
362
|
+
shields: z
|
|
363
|
+
.array(z.enum(["uncomplete", "minimum", "complete"]))
|
|
364
|
+
.optional()
|
|
225
365
|
.describe("Niveau de complétude."),
|
|
226
366
|
sort: sortField,
|
|
227
367
|
order: orderField,
|
|
228
368
|
page: pageField,
|
|
229
369
|
pageSize: pageSizeField,
|
|
230
|
-
})
|
|
370
|
+
})
|
|
371
|
+
.strict();
|
|
231
372
|
// ---- Project search schema ----
|
|
232
373
|
// Source: https://doc.boondmanager.com/api-externe/raml-build/resources/projects/search.raml
|
|
233
|
-
export const ProjectSearchSchema = z
|
|
234
|
-
|
|
235
|
-
|
|
374
|
+
export const ProjectSearchSchema = z
|
|
375
|
+
.object({
|
|
376
|
+
keywords: z
|
|
377
|
+
.string()
|
|
378
|
+
.optional()
|
|
379
|
+
.describe("Mots-clés. Pour cibler par ID préfixé : 'PRJnnn' (projet), 'CSOCnnn' (société), " +
|
|
380
|
+
"'CCONnnn' (contact), 'AOnnn' (opportunité), 'COMPnnn' (ressource), 'CTRnnn' (contrat)."),
|
|
236
381
|
perimeterManagers: perimeterManagersField,
|
|
237
382
|
perimeterAgencies: perimeterAgenciesField,
|
|
238
383
|
perimeterPoles: perimeterPolesField,
|
|
@@ -245,26 +390,38 @@ export const ProjectSearchSchema = z.object({
|
|
|
245
390
|
expertiseAreas: strArray("IDs de domaines d'expertise."),
|
|
246
391
|
activityAreas: strArray("IDs de secteurs d'activité."),
|
|
247
392
|
flags: intArray("IDs de tags."),
|
|
248
|
-
period: z
|
|
249
|
-
|
|
393
|
+
period: z
|
|
394
|
+
.string()
|
|
395
|
+
.optional()
|
|
396
|
+
.describe("Filtre temporel : 'running' (en cours), 'created', 'started', 'stopped', 'closed', 'updated', " +
|
|
397
|
+
"'hasAdditionalDataOrPurchase'. À combiner avec `startDate` + `endDate`."),
|
|
250
398
|
startDate: startDateField,
|
|
251
399
|
endDate: endDateField,
|
|
252
400
|
sort: sortField,
|
|
253
401
|
order: orderField,
|
|
254
402
|
page: pageField,
|
|
255
403
|
pageSize: pageSizeField,
|
|
256
|
-
})
|
|
404
|
+
})
|
|
405
|
+
.strict();
|
|
257
406
|
// ID param schema
|
|
258
|
-
export const IdSchema = z
|
|
407
|
+
export const IdSchema = z
|
|
408
|
+
.object({
|
|
259
409
|
id: z.string().min(1).describe("Identifiant unique de l'entité BoondManager"),
|
|
260
|
-
})
|
|
410
|
+
})
|
|
411
|
+
.strict();
|
|
261
412
|
// ID + tab param schema
|
|
262
|
-
export const IdTabSchema = z
|
|
413
|
+
export const IdTabSchema = z
|
|
414
|
+
.object({
|
|
263
415
|
id: z.string().min(1).describe("Identifiant unique de l'entité"),
|
|
264
|
-
tab: z
|
|
265
|
-
|
|
416
|
+
tab: z
|
|
417
|
+
.string()
|
|
418
|
+
.optional()
|
|
419
|
+
.describe("Onglet spécifique à récupérer (information, technical, financial, actions, contracts, documents)"),
|
|
420
|
+
})
|
|
421
|
+
.strict();
|
|
266
422
|
// ---- Candidate schemas ----
|
|
267
|
-
export const CandidateCreateSchema = z
|
|
423
|
+
export const CandidateCreateSchema = z
|
|
424
|
+
.object({
|
|
268
425
|
firstName: z.string().min(1).describe("Prénom du candidat"),
|
|
269
426
|
lastName: z.string().min(1).describe("Nom de famille du candidat"),
|
|
270
427
|
email1: z.string().email().optional().describe("Email principal"),
|
|
@@ -275,8 +432,10 @@ export const CandidateCreateSchema = z.object({
|
|
|
275
432
|
state: z.number().int().optional().describe("État du candidat (0=en cours, 1=placé, 2=archivé...)"),
|
|
276
433
|
mainSkills: z.string().optional().describe("Compétences principales (texte libre)"),
|
|
277
434
|
note: z.string().optional().describe("Notes / commentaires"),
|
|
278
|
-
})
|
|
279
|
-
|
|
435
|
+
})
|
|
436
|
+
.strict();
|
|
437
|
+
export const CandidateUpdateSchema = z
|
|
438
|
+
.object({
|
|
280
439
|
id: z.string().min(1).describe("ID du candidat à modifier"),
|
|
281
440
|
firstName: z.string().optional().describe("Prénom"),
|
|
282
441
|
lastName: z.string().optional().describe("Nom"),
|
|
@@ -288,9 +447,11 @@ export const CandidateUpdateSchema = z.object({
|
|
|
288
447
|
state: z.number().int().optional().describe("État du candidat"),
|
|
289
448
|
mainSkills: z.string().optional().describe("Compétences principales"),
|
|
290
449
|
note: z.string().optional().describe("Notes"),
|
|
291
|
-
})
|
|
450
|
+
})
|
|
451
|
+
.strict();
|
|
292
452
|
// ---- Resource schemas ----
|
|
293
|
-
export const ResourceCreateSchema = z
|
|
453
|
+
export const ResourceCreateSchema = z
|
|
454
|
+
.object({
|
|
294
455
|
firstName: z.string().min(1).describe("Prénom de la ressource/collaborateur"),
|
|
295
456
|
lastName: z.string().min(1).describe("Nom de famille"),
|
|
296
457
|
email1: z.string().email().optional().describe("Email principal"),
|
|
@@ -300,8 +461,10 @@ export const ResourceCreateSchema = z.object({
|
|
|
300
461
|
title: z.string().optional().describe("Titre / poste"),
|
|
301
462
|
state: z.number().int().optional().describe("État de la ressource"),
|
|
302
463
|
note: z.string().optional().describe("Notes"),
|
|
303
|
-
})
|
|
304
|
-
|
|
464
|
+
})
|
|
465
|
+
.strict();
|
|
466
|
+
export const ResourceUpdateSchema = z
|
|
467
|
+
.object({
|
|
305
468
|
id: z.string().min(1).describe("ID de la ressource à modifier"),
|
|
306
469
|
firstName: z.string().optional().describe("Prénom"),
|
|
307
470
|
lastName: z.string().optional().describe("Nom"),
|
|
@@ -312,9 +475,11 @@ export const ResourceUpdateSchema = z.object({
|
|
|
312
475
|
title: z.string().optional().describe("Titre / poste"),
|
|
313
476
|
state: z.number().int().optional().describe("État"),
|
|
314
477
|
note: z.string().optional().describe("Notes"),
|
|
315
|
-
})
|
|
478
|
+
})
|
|
479
|
+
.strict();
|
|
316
480
|
// ---- Contact schemas ----
|
|
317
|
-
export const ContactCreateSchema = z
|
|
481
|
+
export const ContactCreateSchema = z
|
|
482
|
+
.object({
|
|
318
483
|
firstName: z.string().min(1).describe("Prénom du contact"),
|
|
319
484
|
lastName: z.string().min(1).describe("Nom de famille"),
|
|
320
485
|
email1: z.string().email().optional().describe("Email principal"),
|
|
@@ -324,8 +489,10 @@ export const ContactCreateSchema = z.object({
|
|
|
324
489
|
title: z.string().optional().describe("Titre / fonction"),
|
|
325
490
|
companyId: z.string().optional().describe("ID de la société associée"),
|
|
326
491
|
note: z.string().optional().describe("Notes"),
|
|
327
|
-
})
|
|
328
|
-
|
|
492
|
+
})
|
|
493
|
+
.strict();
|
|
494
|
+
export const ContactUpdateSchema = z
|
|
495
|
+
.object({
|
|
329
496
|
id: z.string().min(1).describe("ID du contact à modifier"),
|
|
330
497
|
firstName: z.string().optional().describe("Prénom"),
|
|
331
498
|
lastName: z.string().optional().describe("Nom"),
|
|
@@ -334,9 +501,11 @@ export const ContactUpdateSchema = z.object({
|
|
|
334
501
|
city: z.string().optional().describe("Ville"),
|
|
335
502
|
title: z.string().optional().describe("Titre / fonction"),
|
|
336
503
|
note: z.string().optional().describe("Notes"),
|
|
337
|
-
})
|
|
504
|
+
})
|
|
505
|
+
.strict();
|
|
338
506
|
// ---- Company schemas ----
|
|
339
|
-
export const CompanyCreateSchema = z
|
|
507
|
+
export const CompanyCreateSchema = z
|
|
508
|
+
.object({
|
|
340
509
|
name: z.string().min(1).describe("Nom de la société"),
|
|
341
510
|
email1: z.string().email().optional().describe("Email de la société"),
|
|
342
511
|
phone1: z.string().optional().describe("Téléphone"),
|
|
@@ -346,8 +515,10 @@ export const CompanyCreateSchema = z.object({
|
|
|
346
515
|
siret: z.string().optional().describe("Numéro SIRET"),
|
|
347
516
|
state: z.number().int().optional().describe("État de la société"),
|
|
348
517
|
note: z.string().optional().describe("Notes"),
|
|
349
|
-
})
|
|
350
|
-
|
|
518
|
+
})
|
|
519
|
+
.strict();
|
|
520
|
+
export const CompanyUpdateSchema = z
|
|
521
|
+
.object({
|
|
351
522
|
id: z.string().min(1).describe("ID de la société à modifier"),
|
|
352
523
|
name: z.string().optional().describe("Nom"),
|
|
353
524
|
email1: z.string().email().optional().describe("Email"),
|
|
@@ -358,9 +529,11 @@ export const CompanyUpdateSchema = z.object({
|
|
|
358
529
|
siret: z.string().optional().describe("Numéro SIRET"),
|
|
359
530
|
state: z.number().int().optional().describe("État"),
|
|
360
531
|
note: z.string().optional().describe("Notes"),
|
|
361
|
-
})
|
|
532
|
+
})
|
|
533
|
+
.strict();
|
|
362
534
|
// ---- Opportunity schemas ----
|
|
363
|
-
export const OpportunityCreateSchema = z
|
|
535
|
+
export const OpportunityCreateSchema = z
|
|
536
|
+
.object({
|
|
364
537
|
name: z.string().min(1).describe("Nom / titre de l'opportunité"),
|
|
365
538
|
companyId: z.string().optional().describe("ID de la société cliente"),
|
|
366
539
|
contactId: z.string().optional().describe("ID du contact associé"),
|
|
@@ -368,17 +541,21 @@ export const OpportunityCreateSchema = z.object({
|
|
|
368
541
|
startDate: z.string().optional().describe("Date de début prévue (YYYY-MM-DD)"),
|
|
369
542
|
endDate: z.string().optional().describe("Date de fin prévue (YYYY-MM-DD)"),
|
|
370
543
|
note: z.string().optional().describe("Notes / description"),
|
|
371
|
-
})
|
|
372
|
-
|
|
544
|
+
})
|
|
545
|
+
.strict();
|
|
546
|
+
export const OpportunityUpdateSchema = z
|
|
547
|
+
.object({
|
|
373
548
|
id: z.string().min(1).describe("ID de l'opportunité à modifier"),
|
|
374
549
|
name: z.string().optional().describe("Nom / titre"),
|
|
375
550
|
state: z.number().int().optional().describe("État"),
|
|
376
551
|
startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
|
|
377
552
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
378
553
|
note: z.string().optional().describe("Notes"),
|
|
379
|
-
})
|
|
554
|
+
})
|
|
555
|
+
.strict();
|
|
380
556
|
// ---- Action schemas ----
|
|
381
|
-
export const ActionSearchSchema = z
|
|
557
|
+
export const ActionSearchSchema = z
|
|
558
|
+
.object({
|
|
382
559
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
383
560
|
candidateId: z.string().optional().describe("Filtrer par ID candidat"),
|
|
384
561
|
resourceId: z.string().optional().describe("Filtrer par ID ressource"),
|
|
@@ -386,8 +563,10 @@ export const ActionSearchSchema = z.object({
|
|
|
386
563
|
companyId: z.string().optional().describe("Filtrer par ID société"),
|
|
387
564
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
388
565
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
389
|
-
})
|
|
390
|
-
|
|
566
|
+
})
|
|
567
|
+
.strict();
|
|
568
|
+
export const ActionCreateSchema = z
|
|
569
|
+
.object({
|
|
391
570
|
typeOf: z.string().min(1).describe("Type d'action (ex: call, email, meeting, note)"),
|
|
392
571
|
subject: z.string().optional().describe("Sujet de l'action"),
|
|
393
572
|
content: z.string().optional().describe("Contenu / description"),
|
|
@@ -397,25 +576,48 @@ export const ActionCreateSchema = z.object({
|
|
|
397
576
|
resourceId: z.string().optional().describe("ID de la ressource associée"),
|
|
398
577
|
contactId: z.string().optional().describe("ID du contact associé"),
|
|
399
578
|
companyId: z.string().optional().describe("ID de la société associée"),
|
|
400
|
-
})
|
|
579
|
+
})
|
|
580
|
+
.strict();
|
|
401
581
|
// ---- Timesheet schemas ----
|
|
402
|
-
export const ResourceTimesheetSchema = z
|
|
582
|
+
export const ResourceTimesheetSchema = z
|
|
583
|
+
.object({
|
|
403
584
|
resourceId: z.string().min(1).describe("ID de la ressource"),
|
|
404
585
|
month: z.number().int().min(1).max(12).optional().describe("Mois (1-12). Si omis, mois courant."),
|
|
405
586
|
year: z.number().int().min(2000).optional().describe("Année (ex: 2025). Si omis, année courante."),
|
|
406
|
-
})
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
587
|
+
})
|
|
588
|
+
.strict();
|
|
589
|
+
// `/times-reports` requires `startMonth` and `endMonth` in YYYY-MM form. Passing
|
|
590
|
+
// YYYY-MM-DD or omitting them surfaces a 422 "Missing required attribute" from
|
|
591
|
+
// the API, so the schema enforces both at the boundary.
|
|
592
|
+
export const TimesheetSearchSchema = z
|
|
593
|
+
.object({
|
|
594
|
+
startMonth: z
|
|
595
|
+
.string()
|
|
596
|
+
.regex(/^\d{4}-\d{2}$/)
|
|
597
|
+
.describe("Mois de début au format YYYY-MM (ex: '2025-01'). Requis."),
|
|
598
|
+
endMonth: z
|
|
599
|
+
.string()
|
|
600
|
+
.regex(/^\d{4}-\d{2}$/)
|
|
601
|
+
.describe("Mois de fin au format YYYY-MM (ex: '2025-03'). Requis."),
|
|
602
|
+
keywords: z.string().optional().describe("Mots-clés (préfixes 'TPS', 'COMP'...)."),
|
|
410
603
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
411
|
-
pageSize: z
|
|
604
|
+
pageSize: z
|
|
605
|
+
.number()
|
|
606
|
+
.int()
|
|
607
|
+
.min(1)
|
|
608
|
+
.max(MAX_PAGE_SIZE)
|
|
609
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
412
610
|
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
413
|
-
})
|
|
414
|
-
|
|
611
|
+
})
|
|
612
|
+
.strict();
|
|
613
|
+
export const TimesheetGetSchema = z
|
|
614
|
+
.object({
|
|
415
615
|
id: z.string().min(1).describe("Identifiant unique de la feuille de temps"),
|
|
416
|
-
})
|
|
616
|
+
})
|
|
617
|
+
.strict();
|
|
417
618
|
// ---- Project schemas ----
|
|
418
|
-
export const ProjectCreateSchema = z
|
|
619
|
+
export const ProjectCreateSchema = z
|
|
620
|
+
.object({
|
|
419
621
|
name: z.string().min(1).describe("Nom du projet / mission"),
|
|
420
622
|
companyId: z.string().optional().describe("ID de la société cliente"),
|
|
421
623
|
contactId: z.string().optional().describe("ID du contact associé"),
|
|
@@ -424,17 +626,21 @@ export const ProjectCreateSchema = z.object({
|
|
|
424
626
|
startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
|
|
425
627
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
426
628
|
note: z.string().optional().describe("Notes / description du projet"),
|
|
427
|
-
})
|
|
428
|
-
|
|
629
|
+
})
|
|
630
|
+
.strict();
|
|
631
|
+
export const ProjectUpdateSchema = z
|
|
632
|
+
.object({
|
|
429
633
|
id: z.string().min(1).describe("ID du projet à modifier"),
|
|
430
634
|
name: z.string().optional().describe("Nom du projet"),
|
|
431
635
|
state: z.number().int().optional().describe("État du projet"),
|
|
432
636
|
startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
|
|
433
637
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
434
638
|
note: z.string().optional().describe("Notes"),
|
|
435
|
-
})
|
|
639
|
+
})
|
|
640
|
+
.strict();
|
|
436
641
|
// ---- Invoice schemas ----
|
|
437
|
-
export const InvoiceCreateSchema = z
|
|
642
|
+
export const InvoiceCreateSchema = z
|
|
643
|
+
.object({
|
|
438
644
|
reference: z.string().optional().describe("Référence de la facture"),
|
|
439
645
|
companyId: z.string().optional().describe("ID de la société facturée"),
|
|
440
646
|
projectId: z.string().optional().describe("ID du projet associé"),
|
|
@@ -444,8 +650,10 @@ export const InvoiceCreateSchema = z.object({
|
|
|
444
650
|
amountExcludingTax: z.number().optional().describe("Montant HT"),
|
|
445
651
|
taxRate: z.number().optional().describe("Taux de TVA (%)"),
|
|
446
652
|
note: z.string().optional().describe("Notes / commentaires"),
|
|
447
|
-
})
|
|
448
|
-
|
|
653
|
+
})
|
|
654
|
+
.strict();
|
|
655
|
+
export const InvoiceUpdateSchema = z
|
|
656
|
+
.object({
|
|
449
657
|
id: z.string().min(1).describe("ID de la facture à modifier"),
|
|
450
658
|
reference: z.string().optional().describe("Référence de la facture"),
|
|
451
659
|
state: z.number().int().optional().describe("État de la facture"),
|
|
@@ -454,19 +662,26 @@ export const InvoiceUpdateSchema = z.object({
|
|
|
454
662
|
amountExcludingTax: z.number().optional().describe("Montant HT"),
|
|
455
663
|
taxRate: z.number().optional().describe("Taux de TVA (%)"),
|
|
456
664
|
note: z.string().optional().describe("Notes"),
|
|
457
|
-
})
|
|
458
|
-
|
|
665
|
+
})
|
|
666
|
+
.strict();
|
|
667
|
+
export const InvoiceSearchSchema = z
|
|
668
|
+
.object({
|
|
459
669
|
keywords: z.string().optional().describe("Mots-clés de recherche (référence, société...)"),
|
|
460
670
|
companyId: z.string().optional().describe("Filtrer par ID société"),
|
|
461
671
|
projectId: z.string().optional().describe("Filtrer par ID projet"),
|
|
462
672
|
startDate: z.string().optional().describe("Date de début de période (YYYY-MM-DD)"),
|
|
463
673
|
endDate: z.string().optional().describe("Date de fin de période (YYYY-MM-DD)"),
|
|
464
|
-
period: z
|
|
674
|
+
period: z
|
|
675
|
+
.string()
|
|
676
|
+
.optional()
|
|
677
|
+
.describe("Type de période (created, updated, expectedPayment, performedPayment, period)"),
|
|
465
678
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
466
679
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
467
|
-
})
|
|
680
|
+
})
|
|
681
|
+
.strict();
|
|
468
682
|
// ---- Order schemas (Bons de commande) ----
|
|
469
|
-
export const OrderCreateSchema = z
|
|
683
|
+
export const OrderCreateSchema = z
|
|
684
|
+
.object({
|
|
470
685
|
reference: z.string().optional().describe("Référence du bon de commande"),
|
|
471
686
|
companyId: z.string().optional().describe("ID de la société"),
|
|
472
687
|
projectId: z.string().optional().describe("ID du projet associé"),
|
|
@@ -474,24 +689,30 @@ export const OrderCreateSchema = z.object({
|
|
|
474
689
|
orderDate: z.string().optional().describe("Date du bon de commande (YYYY-MM-DD)"),
|
|
475
690
|
amountExcludingTax: z.number().optional().describe("Montant HT"),
|
|
476
691
|
note: z.string().optional().describe("Notes / commentaires"),
|
|
477
|
-
})
|
|
478
|
-
|
|
692
|
+
})
|
|
693
|
+
.strict();
|
|
694
|
+
export const OrderUpdateSchema = z
|
|
695
|
+
.object({
|
|
479
696
|
id: z.string().min(1).describe("ID du bon de commande à modifier"),
|
|
480
697
|
reference: z.string().optional().describe("Référence"),
|
|
481
698
|
state: z.number().int().optional().describe("État"),
|
|
482
699
|
orderDate: z.string().optional().describe("Date (YYYY-MM-DD)"),
|
|
483
700
|
amountExcludingTax: z.number().optional().describe("Montant HT"),
|
|
484
701
|
note: z.string().optional().describe("Notes"),
|
|
485
|
-
})
|
|
486
|
-
|
|
702
|
+
})
|
|
703
|
+
.strict();
|
|
704
|
+
export const OrderSearchSchema = z
|
|
705
|
+
.object({
|
|
487
706
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
488
707
|
companyId: z.string().optional().describe("Filtrer par ID société"),
|
|
489
708
|
projectId: z.string().optional().describe("Filtrer par ID projet"),
|
|
490
709
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
491
710
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
492
|
-
})
|
|
711
|
+
})
|
|
712
|
+
.strict();
|
|
493
713
|
// ---- Delivery schemas (Livraisons / CRA) ----
|
|
494
|
-
export const DeliverySearchSchema = z
|
|
714
|
+
export const DeliverySearchSchema = z
|
|
715
|
+
.object({
|
|
495
716
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
496
717
|
projectId: z.string().optional().describe("Filtrer par ID projet"),
|
|
497
718
|
companyId: z.string().optional().describe("Filtrer par ID société"),
|
|
@@ -499,33 +720,41 @@ export const DeliverySearchSchema = z.object({
|
|
|
499
720
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
500
721
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
501
722
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
502
|
-
})
|
|
723
|
+
})
|
|
724
|
+
.strict();
|
|
503
725
|
// ---- Absence schemas ----
|
|
504
|
-
export const AbsenceCreateSchema = z
|
|
726
|
+
export const AbsenceCreateSchema = z
|
|
727
|
+
.object({
|
|
505
728
|
resourceId: z.string().min(1).describe("ID de la ressource en absence"),
|
|
506
729
|
typeOf: z.string().min(1).describe("Type d'absence (congé payé, RTT, maladie, sans solde...)"),
|
|
507
730
|
startDate: z.string().min(1).describe("Date de début (YYYY-MM-DD)"),
|
|
508
731
|
endDate: z.string().min(1).describe("Date de fin (YYYY-MM-DD)"),
|
|
509
732
|
state: z.number().int().optional().describe("État de la demande (0=en attente, 1=validé, 2=refusé...)"),
|
|
510
733
|
note: z.string().optional().describe("Commentaire / motif"),
|
|
511
|
-
})
|
|
512
|
-
|
|
734
|
+
})
|
|
735
|
+
.strict();
|
|
736
|
+
export const AbsenceUpdateSchema = z
|
|
737
|
+
.object({
|
|
513
738
|
id: z.string().min(1).describe("ID de l'absence à modifier"),
|
|
514
739
|
startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
|
|
515
740
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
516
741
|
state: z.number().int().optional().describe("État de la demande"),
|
|
517
742
|
note: z.string().optional().describe("Commentaire / motif"),
|
|
518
|
-
})
|
|
519
|
-
|
|
743
|
+
})
|
|
744
|
+
.strict();
|
|
745
|
+
export const AbsenceSearchSchema = z
|
|
746
|
+
.object({
|
|
520
747
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
521
748
|
resourceId: z.string().optional().describe("Filtrer par ID ressource"),
|
|
522
749
|
startDate: z.string().optional().describe("Date de début de période (YYYY-MM-DD)"),
|
|
523
750
|
endDate: z.string().optional().describe("Date de fin de période (YYYY-MM-DD)"),
|
|
524
751
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
525
752
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
526
|
-
})
|
|
753
|
+
})
|
|
754
|
+
.strict();
|
|
527
755
|
// ---- Expense schemas (Notes de frais) ----
|
|
528
|
-
export const ExpenseCreateSchema = z
|
|
756
|
+
export const ExpenseCreateSchema = z
|
|
757
|
+
.object({
|
|
529
758
|
resourceId: z.string().min(1).describe("ID de la ressource"),
|
|
530
759
|
projectId: z.string().optional().describe("ID du projet associé"),
|
|
531
760
|
typeOf: z.string().optional().describe("Type de frais (transport, repas, hébergement...)"),
|
|
@@ -534,14 +763,18 @@ export const ExpenseCreateSchema = z.object({
|
|
|
534
763
|
currency: z.string().optional().describe("Devise (EUR, USD...)"),
|
|
535
764
|
state: z.number().int().optional().describe("État de la note de frais"),
|
|
536
765
|
note: z.string().optional().describe("Description / justification"),
|
|
537
|
-
})
|
|
538
|
-
|
|
766
|
+
})
|
|
767
|
+
.strict();
|
|
768
|
+
export const ExpenseUpdateSchema = z
|
|
769
|
+
.object({
|
|
539
770
|
id: z.string().min(1).describe("ID de la note de frais à modifier"),
|
|
540
771
|
amount: z.number().optional().describe("Montant"),
|
|
541
772
|
state: z.number().int().optional().describe("État"),
|
|
542
773
|
note: z.string().optional().describe("Description"),
|
|
543
|
-
})
|
|
544
|
-
|
|
774
|
+
})
|
|
775
|
+
.strict();
|
|
776
|
+
export const ExpenseSearchSchema = z
|
|
777
|
+
.object({
|
|
545
778
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
546
779
|
resourceId: z.string().optional().describe("Filtrer par ID ressource"),
|
|
547
780
|
projectId: z.string().optional().describe("Filtrer par ID projet"),
|
|
@@ -549,17 +782,21 @@ export const ExpenseSearchSchema = z.object({
|
|
|
549
782
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
550
783
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
551
784
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
552
|
-
})
|
|
785
|
+
})
|
|
786
|
+
.strict();
|
|
553
787
|
// ---- Product schemas ----
|
|
554
|
-
export const ProductCreateSchema = z
|
|
788
|
+
export const ProductCreateSchema = z
|
|
789
|
+
.object({
|
|
555
790
|
name: z.string().min(1).describe("Nom du produit"),
|
|
556
791
|
reference: z.string().optional().describe("Référence du produit"),
|
|
557
792
|
unitPrice: z.number().optional().describe("Prix unitaire HT"),
|
|
558
793
|
taxRate: z.number().optional().describe("Taux de TVA (%)"),
|
|
559
794
|
state: z.number().int().optional().describe("État du produit"),
|
|
560
795
|
note: z.string().optional().describe("Description du produit"),
|
|
561
|
-
})
|
|
562
|
-
|
|
796
|
+
})
|
|
797
|
+
.strict();
|
|
798
|
+
export const ProductUpdateSchema = z
|
|
799
|
+
.object({
|
|
563
800
|
id: z.string().min(1).describe("ID du produit à modifier"),
|
|
564
801
|
name: z.string().optional().describe("Nom du produit"),
|
|
565
802
|
reference: z.string().optional().describe("Référence"),
|
|
@@ -567,9 +804,11 @@ export const ProductUpdateSchema = z.object({
|
|
|
567
804
|
taxRate: z.number().optional().describe("Taux de TVA (%)"),
|
|
568
805
|
state: z.number().int().optional().describe("État"),
|
|
569
806
|
note: z.string().optional().describe("Description"),
|
|
570
|
-
})
|
|
807
|
+
})
|
|
808
|
+
.strict();
|
|
571
809
|
// ---- Positioning schemas ----
|
|
572
|
-
export const PositioningCreateSchema = z
|
|
810
|
+
export const PositioningCreateSchema = z
|
|
811
|
+
.object({
|
|
573
812
|
candidateId: z.string().optional().describe("ID du candidat positionné"),
|
|
574
813
|
resourceId: z.string().optional().describe("ID de la ressource positionnée"),
|
|
575
814
|
projectId: z.string().optional().describe("ID du projet"),
|
|
@@ -578,8 +817,10 @@ export const PositioningCreateSchema = z.object({
|
|
|
578
817
|
startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
|
|
579
818
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
580
819
|
note: z.string().optional().describe("Notes / commentaires"),
|
|
581
|
-
})
|
|
582
|
-
|
|
820
|
+
})
|
|
821
|
+
.strict();
|
|
822
|
+
export const PositioningSearchSchema = z
|
|
823
|
+
.object({
|
|
583
824
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
584
825
|
candidateId: z.string().optional().describe("Filtrer par ID candidat"),
|
|
585
826
|
resourceId: z.string().optional().describe("Filtrer par ID ressource"),
|
|
@@ -587,9 +828,11 @@ export const PositioningSearchSchema = z.object({
|
|
|
587
828
|
opportunityId: z.string().optional().describe("Filtrer par ID opportunité"),
|
|
588
829
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
589
830
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
590
|
-
})
|
|
831
|
+
})
|
|
832
|
+
.strict();
|
|
591
833
|
// ---- Payment schemas ----
|
|
592
|
-
export const PaymentSearchSchema = z
|
|
834
|
+
export const PaymentSearchSchema = z
|
|
835
|
+
.object({
|
|
593
836
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
594
837
|
invoiceId: z.string().optional().describe("Filtrer par ID facture"),
|
|
595
838
|
companyId: z.string().optional().describe("Filtrer par ID société"),
|
|
@@ -597,16 +840,136 @@ export const PaymentSearchSchema = z.object({
|
|
|
597
840
|
endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
|
|
598
841
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
599
842
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
600
|
-
})
|
|
843
|
+
})
|
|
844
|
+
.strict();
|
|
601
845
|
// ---- Advantage schemas ----
|
|
602
|
-
export const AdvantageSearchSchema = z
|
|
846
|
+
export const AdvantageSearchSchema = z
|
|
847
|
+
.object({
|
|
603
848
|
keywords: z.string().optional().describe("Mots-clés de recherche"),
|
|
604
849
|
resourceId: z.string().optional().describe("Filtrer par ID ressource"),
|
|
605
850
|
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
606
851
|
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE).describe("Résultats par page"),
|
|
607
|
-
})
|
|
852
|
+
})
|
|
853
|
+
.strict();
|
|
608
854
|
// ---- Application schemas ----
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
855
|
+
// ---- Validation schemas ----
|
|
856
|
+
// `/validations` requires `startMonth` + `endMonth` (YYYY-MM). Optional filters
|
|
857
|
+
// from the official RAML follow.
|
|
858
|
+
export const ValidationSearchSchema = z
|
|
859
|
+
.object({
|
|
860
|
+
startMonth: z
|
|
861
|
+
.string()
|
|
862
|
+
.regex(/^\d{4}-\d{2}$/)
|
|
863
|
+
.describe("Mois de début YYYY-MM. Requis."),
|
|
864
|
+
endMonth: z
|
|
865
|
+
.string()
|
|
866
|
+
.regex(/^\d{4}-\d{2}$/)
|
|
867
|
+
.describe("Mois de fin YYYY-MM. Requis."),
|
|
868
|
+
keywords: z
|
|
869
|
+
.string()
|
|
870
|
+
.optional()
|
|
871
|
+
.describe("Mots-clés. Préfixes acceptés : 'TPS' (CRA), 'EXP' (frais), 'ABS' (absence), 'COMP' (ressource)."),
|
|
872
|
+
documentTypes: z
|
|
873
|
+
.array(z.enum(["absencesReport", "timesReport", "expensesReport"]))
|
|
874
|
+
.optional()
|
|
875
|
+
.describe("Types de documents à valider."),
|
|
876
|
+
resourceTypes: z
|
|
877
|
+
.array(z.number().int())
|
|
878
|
+
.optional()
|
|
879
|
+
.describe("IDs de types de ressource (dictionnaire setting.typeOf.resource)."),
|
|
880
|
+
validationStates: z
|
|
881
|
+
.array(z.enum(["waitingForValidation", "validated", "rejected"]))
|
|
882
|
+
.optional()
|
|
883
|
+
.describe("États de validation."),
|
|
884
|
+
validationAlerts: z.boolean().optional().describe("Filtrer sur les validations avec alertes."),
|
|
885
|
+
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
886
|
+
pageSize: z
|
|
887
|
+
.number()
|
|
888
|
+
.int()
|
|
889
|
+
.min(1)
|
|
890
|
+
.max(MAX_PAGE_SIZE)
|
|
891
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
892
|
+
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
893
|
+
})
|
|
894
|
+
.strict();
|
|
895
|
+
// ---- Notification schemas ----
|
|
896
|
+
// `/notifications` requires the singular `category` (activity/thread/corporate)
|
|
897
|
+
// per the official RAML. Optional `state` filters read/unread; `parentType`
|
|
898
|
+
// narrows by entity module.
|
|
899
|
+
export const NotificationSearchSchema = z
|
|
900
|
+
.object({
|
|
901
|
+
category: z
|
|
902
|
+
.enum(["activity", "thread", "corporate"])
|
|
903
|
+
.describe("Catégorie (requis): 'activity' (notifications d'activité), 'thread' (messages), 'corporate' (annonces)."),
|
|
904
|
+
state: z.enum(["new", "read"]).optional().describe("Filtrer par état de lecture."),
|
|
905
|
+
parentType: z
|
|
906
|
+
.array(z.string())
|
|
907
|
+
.optional()
|
|
908
|
+
.describe("Types de modules parents (ex: 'contract', 'global', 'project'...)."),
|
|
909
|
+
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
910
|
+
pageSize: z
|
|
911
|
+
.number()
|
|
912
|
+
.int()
|
|
913
|
+
.min(1)
|
|
914
|
+
.max(MAX_PAGE_SIZE)
|
|
915
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
916
|
+
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
917
|
+
})
|
|
918
|
+
.strict();
|
|
919
|
+
// ---- Reporting schemas ----
|
|
920
|
+
// `/reporting-companies` and `/reporting-resources` require `startDate` +
|
|
921
|
+
// `endDate` (YYYY-MM-DD); the others tolerate omission but still benefit from
|
|
922
|
+
// a period filter.
|
|
923
|
+
export const ReportingDateRequiredSchema = z
|
|
924
|
+
.object({
|
|
925
|
+
startDate: z
|
|
926
|
+
.string()
|
|
927
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
928
|
+
.describe("Date de début YYYY-MM-DD. Requis."),
|
|
929
|
+
endDate: z
|
|
930
|
+
.string()
|
|
931
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
932
|
+
.describe("Date de fin YYYY-MM-DD. Requis."),
|
|
933
|
+
keywords: z.string().optional().describe("Mots-clés."),
|
|
934
|
+
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
935
|
+
pageSize: z
|
|
936
|
+
.number()
|
|
937
|
+
.int()
|
|
938
|
+
.min(1)
|
|
939
|
+
.max(MAX_PAGE_SIZE)
|
|
940
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
941
|
+
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
942
|
+
})
|
|
943
|
+
.strict();
|
|
944
|
+
export const ReportingDateOptionalSchema = z
|
|
945
|
+
.object({
|
|
946
|
+
startDate: z
|
|
947
|
+
.string()
|
|
948
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
949
|
+
.optional()
|
|
950
|
+
.describe("Date de début YYYY-MM-DD."),
|
|
951
|
+
endDate: z
|
|
952
|
+
.string()
|
|
953
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
954
|
+
.optional()
|
|
955
|
+
.describe("Date de fin YYYY-MM-DD."),
|
|
956
|
+
keywords: z.string().optional().describe("Mots-clés."),
|
|
957
|
+
page: z.number().int().min(1).max(MAX_SEARCH_PAGE).default(1).describe(`Numéro de page (max: ${MAX_SEARCH_PAGE})`),
|
|
958
|
+
pageSize: z
|
|
959
|
+
.number()
|
|
960
|
+
.int()
|
|
961
|
+
.min(1)
|
|
962
|
+
.max(MAX_PAGE_SIZE)
|
|
963
|
+
.default(DEFAULT_PAGE_SIZE)
|
|
964
|
+
.describe(`Nombre de résultats par page (max: ${MAX_PAGE_SIZE}, défaut: ${DEFAULT_PAGE_SIZE})`),
|
|
965
|
+
})
|
|
966
|
+
.strict();
|
|
967
|
+
export const DictionaryGetSchema = z
|
|
968
|
+
.object({
|
|
969
|
+
dictionaryType: z
|
|
970
|
+
.string()
|
|
971
|
+
.min(1)
|
|
972
|
+
.describe("Type de dictionnaire (ex: typeOf/actions, typeOf/absences, states/candidates, states/resources, states/opportunities, states/projects, states/invoices, countries, currencies, languages...)"),
|
|
973
|
+
})
|
|
974
|
+
.strict();
|
|
612
975
|
//# sourceMappingURL=index.js.map
|