boondmanager-mcp-server 2.15.2 → 2.17.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.
Files changed (272) hide show
  1. package/LICENSE +1 -1
  2. package/NOTICE +16 -2
  3. package/README.md +60 -15
  4. package/dist/config/access-policy.d.ts.map +1 -1
  5. package/dist/config/access-policy.js +6 -18
  6. package/dist/config/access-policy.js.map +1 -1
  7. package/dist/config/dictionary-overrides.d.ts.map +1 -1
  8. package/dist/config/dictionary-overrides.js +2 -12
  9. package/dist/config/dictionary-overrides.js.map +1 -1
  10. package/dist/config/env.d.ts +63 -0
  11. package/dist/config/env.d.ts.map +1 -0
  12. package/dist/config/env.js +116 -0
  13. package/dist/config/env.js.map +1 -0
  14. package/dist/config/profiles.d.ts +22 -8
  15. package/dist/config/profiles.d.ts.map +1 -1
  16. package/dist/config/profiles.js +48 -4
  17. package/dist/config/profiles.js.map +1 -1
  18. package/dist/constants.d.ts +13 -2
  19. package/dist/constants.d.ts.map +1 -1
  20. package/dist/constants.js +25 -1
  21. package/dist/constants.js.map +1 -1
  22. package/dist/icons.d.ts.map +1 -1
  23. package/dist/icons.js +6 -1
  24. package/dist/icons.js.map +1 -1
  25. package/dist/index.js +33 -15
  26. package/dist/index.js.map +1 -1
  27. package/dist/instructions.d.ts +1 -1
  28. package/dist/instructions.d.ts.map +1 -1
  29. package/dist/instructions.js +6 -6
  30. package/dist/instructions.js.map +1 -1
  31. package/dist/prompts/index.d.ts +19 -1
  32. package/dist/prompts/index.d.ts.map +1 -1
  33. package/dist/prompts/index.js +495 -25
  34. package/dist/prompts/index.js.map +1 -1
  35. package/dist/prompts/periods.d.ts +45 -0
  36. package/dist/prompts/periods.d.ts.map +1 -0
  37. package/dist/prompts/periods.js +154 -0
  38. package/dist/prompts/periods.js.map +1 -0
  39. package/dist/resources/index.d.ts +14 -0
  40. package/dist/resources/index.d.ts.map +1 -1
  41. package/dist/resources/index.js +285 -0
  42. package/dist/resources/index.js.map +1 -1
  43. package/dist/resources/templates.d.ts +1 -1
  44. package/dist/resources/templates.d.ts.map +1 -1
  45. package/dist/resources/templates.js +2 -0
  46. package/dist/resources/templates.js.map +1 -1
  47. package/dist/schema-dialect.js.map +1 -1
  48. package/dist/schemas/filter-aliases.d.ts +1 -1
  49. package/dist/schemas/filter-aliases.d.ts.map +1 -1
  50. package/dist/schemas/filter-aliases.js +101 -2
  51. package/dist/schemas/filter-aliases.js.map +1 -1
  52. package/dist/schemas/index.d.ts +987 -161
  53. package/dist/schemas/index.d.ts.map +1 -1
  54. package/dist/schemas/index.js +853 -323
  55. package/dist/schemas/index.js.map +1 -1
  56. package/dist/server.d.ts.map +1 -1
  57. package/dist/server.js +10 -3
  58. package/dist/server.js.map +1 -1
  59. package/dist/services/boond-client.d.ts +29 -213
  60. package/dist/services/boond-client.d.ts.map +1 -1
  61. package/dist/services/boond-client.js +29 -1168
  62. package/dist/services/boond-client.js.map +1 -1
  63. package/dist/services/dictionary.d.ts +27 -3
  64. package/dist/services/dictionary.d.ts.map +1 -1
  65. package/dist/services/dictionary.js +60 -23
  66. package/dist/services/dictionary.js.map +1 -1
  67. package/dist/services/document-text.d.ts +32 -0
  68. package/dist/services/document-text.d.ts.map +1 -0
  69. package/dist/services/document-text.js +120 -0
  70. package/dist/services/document-text.js.map +1 -0
  71. package/dist/services/format/detail.d.ts +16 -0
  72. package/dist/services/format/detail.d.ts.map +1 -0
  73. package/dist/services/format/detail.js +36 -0
  74. package/dist/services/format/detail.js.map +1 -0
  75. package/dist/services/format/html.d.ts +19 -0
  76. package/dist/services/format/html.d.ts.map +1 -0
  77. package/dist/services/format/html.js +87 -0
  78. package/dist/services/format/html.js.map +1 -0
  79. package/dist/services/format/list.d.ts +3 -0
  80. package/dist/services/format/list.d.ts.map +1 -0
  81. package/dist/services/format/list.js +44 -0
  82. package/dist/services/format/list.js.map +1 -0
  83. package/dist/services/format/summary.d.ts +16 -0
  84. package/dist/services/format/summary.d.ts.map +1 -0
  85. package/dist/services/format/summary.js +172 -0
  86. package/dist/services/format/summary.js.map +1 -0
  87. package/dist/services/format/tab.d.ts +9 -0
  88. package/dist/services/format/tab.d.ts.map +1 -0
  89. package/dist/services/format/tab.js +32 -0
  90. package/dist/services/format/tab.js.map +1 -0
  91. package/dist/services/http/auth.d.ts +44 -0
  92. package/dist/services/http/auth.d.ts.map +1 -0
  93. package/dist/services/http/auth.js +146 -0
  94. package/dist/services/http/auth.js.map +1 -0
  95. package/dist/services/http/download.d.ts +60 -0
  96. package/dist/services/http/download.d.ts.map +1 -0
  97. package/dist/services/http/download.js +160 -0
  98. package/dist/services/http/download.js.map +1 -0
  99. package/dist/services/http/errors.d.ts +45 -0
  100. package/dist/services/http/errors.d.ts.map +1 -0
  101. package/dist/services/http/errors.js +188 -0
  102. package/dist/services/http/errors.js.map +1 -0
  103. package/dist/services/http/rate-limit.d.ts +40 -0
  104. package/dist/services/http/rate-limit.d.ts.map +1 -0
  105. package/dist/services/http/rate-limit.js +92 -0
  106. package/dist/services/http/rate-limit.js.map +1 -0
  107. package/dist/services/http/retry.d.ts +46 -0
  108. package/dist/services/http/retry.d.ts.map +1 -0
  109. package/dist/services/http/retry.js +101 -0
  110. package/dist/services/http/retry.js.map +1 -0
  111. package/dist/services/http/transport.d.ts +73 -0
  112. package/dist/services/http/transport.d.ts.map +1 -0
  113. package/dist/services/http/transport.js +272 -0
  114. package/dist/services/http/transport.js.map +1 -0
  115. package/dist/services/logger.d.ts +53 -2
  116. package/dist/services/logger.d.ts.map +1 -1
  117. package/dist/services/logger.js +82 -21
  118. package/dist/services/logger.js.map +1 -1
  119. package/dist/services/oauth.d.ts +12 -0
  120. package/dist/services/oauth.d.ts.map +1 -1
  121. package/dist/services/oauth.js +21 -8
  122. package/dist/services/oauth.js.map +1 -1
  123. package/dist/services/rate-limiter.d.ts +9 -2
  124. package/dist/services/rate-limiter.d.ts.map +1 -1
  125. package/dist/services/rate-limiter.js +18 -6
  126. package/dist/services/rate-limiter.js.map +1 -1
  127. package/dist/services/request-context.d.ts +47 -0
  128. package/dist/services/request-context.d.ts.map +1 -0
  129. package/dist/services/request-context.js +112 -0
  130. package/dist/services/request-context.js.map +1 -0
  131. package/dist/services/search.d.ts +26 -0
  132. package/dist/services/search.d.ts.map +1 -0
  133. package/dist/services/search.js +98 -0
  134. package/dist/services/search.js.map +1 -0
  135. package/dist/services/update-checker.d.ts.map +1 -1
  136. package/dist/services/update-checker.js +15 -8
  137. package/dist/services/update-checker.js.map +1 -1
  138. package/dist/tools/absences.d.ts +9 -0
  139. package/dist/tools/absences.d.ts.map +1 -1
  140. package/dist/tools/absences.js +65 -20
  141. package/dist/tools/absences.js.map +1 -1
  142. package/dist/tools/actions.d.ts.map +1 -1
  143. package/dist/tools/actions.js +11 -27
  144. package/dist/tools/actions.js.map +1 -1
  145. package/dist/tools/advantages.d.ts +2 -0
  146. package/dist/tools/advantages.d.ts.map +1 -1
  147. package/dist/tools/advantages.js +66 -13
  148. package/dist/tools/advantages.js.map +1 -1
  149. package/dist/tools/alerts.d.ts +18 -0
  150. package/dist/tools/alerts.d.ts.map +1 -0
  151. package/dist/tools/alerts.js +82 -0
  152. package/dist/tools/alerts.js.map +1 -0
  153. package/dist/tools/application.d.ts +2 -1
  154. package/dist/tools/application.d.ts.map +1 -1
  155. package/dist/tools/application.js +9 -3
  156. package/dist/tools/application.js.map +1 -1
  157. package/dist/tools/contacts.d.ts.map +1 -1
  158. package/dist/tools/contacts.js +3 -7
  159. package/dist/tools/contacts.js.map +1 -1
  160. package/dist/tools/contracts.d.ts +22 -0
  161. package/dist/tools/contracts.d.ts.map +1 -1
  162. package/dist/tools/contracts.js +185 -52
  163. package/dist/tools/contracts.js.map +1 -1
  164. package/dist/tools/crud-factory.d.ts +33 -2
  165. package/dist/tools/crud-factory.d.ts.map +1 -1
  166. package/dist/tools/crud-factory.js +42 -15
  167. package/dist/tools/crud-factory.js.map +1 -1
  168. package/dist/tools/deliveries.d.ts +3 -0
  169. package/dist/tools/deliveries.d.ts.map +1 -1
  170. package/dist/tools/deliveries.js +50 -94
  171. package/dist/tools/deliveries.js.map +1 -1
  172. package/dist/tools/description-builders.d.ts +0 -1
  173. package/dist/tools/description-builders.d.ts.map +1 -1
  174. package/dist/tools/description-builders.js +46 -3
  175. package/dist/tools/description-builders.js.map +1 -1
  176. package/dist/tools/documents.d.ts.map +1 -1
  177. package/dist/tools/documents.js +73 -21
  178. package/dist/tools/documents.js.map +1 -1
  179. package/dist/tools/expenses.d.ts.map +1 -1
  180. package/dist/tools/expenses.js +2 -11
  181. package/dist/tools/expenses.js.map +1 -1
  182. package/dist/tools/find.d.ts +61 -0
  183. package/dist/tools/find.d.ts.map +1 -0
  184. package/dist/tools/find.js +221 -0
  185. package/dist/tools/find.js.map +1 -0
  186. package/dist/tools/flags.d.ts +5 -0
  187. package/dist/tools/flags.d.ts.map +1 -1
  188. package/dist/tools/flags.js +116 -1
  189. package/dist/tools/flags.js.map +1 -1
  190. package/dist/tools/forms.d.ts +5 -0
  191. package/dist/tools/forms.d.ts.map +1 -0
  192. package/dist/tools/forms.js +64 -0
  193. package/dist/tools/forms.js.map +1 -0
  194. package/dist/tools/groupments.d.ts +5 -0
  195. package/dist/tools/groupments.d.ts.map +1 -0
  196. package/dist/tools/groupments.js +68 -0
  197. package/dist/tools/groupments.js.map +1 -0
  198. package/dist/tools/inactivities.d.ts +5 -0
  199. package/dist/tools/inactivities.d.ts.map +1 -0
  200. package/dist/tools/inactivities.js +59 -0
  201. package/dist/tools/inactivities.js.map +1 -0
  202. package/dist/tools/index.d.ts +4 -0
  203. package/dist/tools/index.d.ts.map +1 -1
  204. package/dist/tools/index.js +4 -0
  205. package/dist/tools/index.js.map +1 -1
  206. package/dist/tools/invoices.d.ts.map +1 -1
  207. package/dist/tools/invoices.js +27 -2
  208. package/dist/tools/invoices.js.map +1 -1
  209. package/dist/tools/linked-entity-filters.d.ts +48 -0
  210. package/dist/tools/linked-entity-filters.d.ts.map +1 -0
  211. package/dist/tools/linked-entity-filters.js +64 -0
  212. package/dist/tools/linked-entity-filters.js.map +1 -0
  213. package/dist/tools/notifications.d.ts.map +1 -1
  214. package/dist/tools/notifications.js +0 -5
  215. package/dist/tools/notifications.js.map +1 -1
  216. package/dist/tools/orders.d.ts.map +1 -1
  217. package/dist/tools/orders.js +33 -4
  218. package/dist/tools/orders.js.map +1 -1
  219. package/dist/tools/parameter-disclosure.js.map +1 -1
  220. package/dist/tools/payments.d.ts +3 -0
  221. package/dist/tools/payments.d.ts.map +1 -1
  222. package/dist/tools/payments.js +43 -109
  223. package/dist/tools/payments.js.map +1 -1
  224. package/dist/tools/positionings.d.ts.map +1 -1
  225. package/dist/tools/positionings.js +9 -39
  226. package/dist/tools/positionings.js.map +1 -1
  227. package/dist/tools/projects.d.ts.map +1 -1
  228. package/dist/tools/projects.js +5 -12
  229. package/dist/tools/projects.js.map +1 -1
  230. package/dist/tools/provider-invoices.d.ts +2 -0
  231. package/dist/tools/provider-invoices.d.ts.map +1 -1
  232. package/dist/tools/provider-invoices.js +30 -111
  233. package/dist/tools/provider-invoices.js.map +1 -1
  234. package/dist/tools/purchases.d.ts +2 -0
  235. package/dist/tools/purchases.d.ts.map +1 -1
  236. package/dist/tools/purchases.js +50 -104
  237. package/dist/tools/purchases.js.map +1 -1
  238. package/dist/tools/registration-decorators.d.ts +28 -0
  239. package/dist/tools/registration-decorators.d.ts.map +1 -1
  240. package/dist/tools/registration-decorators.js +107 -0
  241. package/dist/tools/registration-decorators.js.map +1 -1
  242. package/dist/tools/resources.d.ts.map +1 -1
  243. package/dist/tools/resources.js +27 -5
  244. package/dist/tools/resources.js.map +1 -1
  245. package/dist/tools/rights.d.ts +101 -0
  246. package/dist/tools/rights.d.ts.map +1 -0
  247. package/dist/tools/rights.js +75 -0
  248. package/dist/tools/rights.js.map +1 -0
  249. package/dist/tools/tab-tools.js +3 -3
  250. package/dist/tools/tab-tools.js.map +1 -1
  251. package/dist/tools/timesheets.d.ts +29 -0
  252. package/dist/tools/timesheets.d.ts.map +1 -1
  253. package/dist/tools/timesheets.js +196 -126
  254. package/dist/tools/timesheets.js.map +1 -1
  255. package/dist/tools/todolists.d.ts +2 -0
  256. package/dist/tools/todolists.d.ts.map +1 -1
  257. package/dist/tools/todolists.js +64 -1
  258. package/dist/tools/todolists.js.map +1 -1
  259. package/dist/tools/validations.d.ts +9 -0
  260. package/dist/tools/validations.d.ts.map +1 -1
  261. package/dist/tools/validations.js +86 -9
  262. package/dist/tools/validations.js.map +1 -1
  263. package/dist/tools/workflows.js +1 -1
  264. package/dist/tools/workflows.js.map +1 -1
  265. package/dist/transports/http.d.ts +116 -0
  266. package/dist/transports/http.d.ts.map +1 -1
  267. package/dist/transports/http.js +422 -92
  268. package/dist/transports/http.js.map +1 -1
  269. package/dist/types.d.ts +3 -3
  270. package/dist/types.d.ts.map +1 -1
  271. package/manifest.json +7 -7
  272. package/package.json +14 -10
@@ -1,105 +1,209 @@
1
- import { ResourceTimesheetSchema, TimesheetSearchSchema, TimesheetGetSchema } from "../schemas/index.js";
2
- import { apiRequest, apiSearch, buildSearchQuery, formatDetailResponse } from "../services/boond-client.js";
3
- import { progressReporterFrom } from "../services/progress.js";
4
- import { buildJsonApiBody } from "./crud-factory.js";
5
- import { CHARACTER_LIMIT } from "../constants.js";
6
- import { z } from "zod";
1
+ import { ResourceTimesheetSchema, TimesheetCreateSchema, TimesheetDefaultSchema, TimesheetSearchSchema, TimesheetUpdateSchema, } from "../schemas/index.js";
2
+ import { apiRequest, formatListResponse } from "../services/boond-client.js";
3
+ import { buildJsonApiBody, registerCreateTool, registerGetTool, registerSearchTool, registerUpdateTool, } from "./crud-factory.js";
7
4
  import { composeDescription } from "./description-builders.js";
8
- const TimesheetCreateSchema = z
9
- .object({
10
- resourceId: z.string().min(1).describe("ID de la ressource"),
11
- projectId: z.string().optional().describe("ID du projet"),
12
- term: z
13
- .string()
14
- .regex(/^\d{4}-\d{2}$/)
15
- .describe("Mois au format YYYY-MM"),
16
- startDate: z.string().optional().describe("Date de début (YYYY-MM-DD)"),
17
- endDate: z.string().optional().describe("Date de fin (YYYY-MM-DD)"),
18
- totalDays: z.number().optional().describe("Total jours"),
19
- totalHours: z.number().optional().describe("Total heures"),
20
- state: z.string().optional().describe("État de la feuille de temps"),
21
- note: z.string().optional().describe("Notes"),
22
- })
23
- .strict();
24
- function formatTimesheetSummary(response) {
25
- const data = Array.isArray(response.data) ? response.data : [response.data];
26
- if (data.length === 0) {
27
- return "Aucune feuille de temps trouvée.";
5
+ /**
6
+ * One CRA line, as the API stores it: nested `workUnitType`, `project`,
7
+ * `delivery`, `batch` objects around the flat ids the schema takes. A missing
8
+ * project / delivery / batch is sent as `null`, which is how the API itself
9
+ * represents an absence line (`GET /times-reports/{id}` → `"project": null`).
10
+ */
11
+ export function buildTimeLine(line) {
12
+ const { workUnitTypeReference, projectId, deliveryId, batchId, ...rest } = line;
13
+ return {
14
+ ...Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined)),
15
+ workUnitType: { reference: workUnitTypeReference },
16
+ project: projectId === undefined ? null : { id: projectId },
17
+ delivery: deliveryId === undefined ? null : { id: deliveryId },
18
+ batch: batchId === undefined ? null : { id: batchId },
19
+ };
20
+ }
21
+ /** Build the `/times-reports` payload: convenience ids → relationships, lines → nested objects. */
22
+ export function buildTimesheetBody(params) {
23
+ const { id, resourceId, agencyId, regularTimes, exceptionalTimes, ...attrs } = params;
24
+ const attributes = { ...attrs };
25
+ if (regularTimes !== undefined)
26
+ attributes.regularTimes = regularTimes.map(buildTimeLine);
27
+ if (exceptionalTimes !== undefined) {
28
+ attributes.exceptionalTimes = exceptionalTimes.map(buildTimeLine);
28
29
  }
29
- const lines = data.map((item) => {
30
- const attrs = item.attributes;
31
- const parts = [`[timesreport #${item.id}]`];
32
- if (attrs.startDate)
33
- parts.push(`Du: ${attrs.startDate}`);
34
- if (attrs.endDate)
35
- parts.push(`Au: ${attrs.endDate}`);
36
- if (attrs.state !== undefined)
37
- parts.push(`Statut: ${attrs.state}`);
38
- if (attrs.totalDays !== undefined)
39
- parts.push(`Jours: ${attrs.totalDays}`);
40
- if (attrs.totalHours !== undefined)
41
- parts.push(`Heures: ${attrs.totalHours}`);
42
- return parts.join(" | ");
30
+ return buildJsonApiBody("timesreport", attributes, id, {
31
+ resource: resourceId ? { id: String(resourceId), type: "resource" } : undefined,
32
+ agency: agencyId ? { id: String(agencyId), type: "agency" } : undefined,
43
33
  });
44
- const total = response.meta?.totals?.rows;
45
- let result = lines.join("\n");
46
- if (total !== undefined) {
47
- result = `Total: ${total} feuille(s) de temps\n\n${result}`;
34
+ }
35
+ /**
36
+ * Render `/times-reports/default` down to what a caller needs to write lines.
37
+ *
38
+ * The response is the only place the work-unit-type codes are published — on
39
+ * the included **resource** (`workUnitTypesAllowed`), not on the agency and not
40
+ * in `/application/dictionary` — together with the (project, delivery) pairs
41
+ * chargeable that month and the `plannedTimes` derived from the deliveries'
42
+ * planning, which are the lines a filled CRA usually repeats.
43
+ */
44
+ export function formatTimesheetDefaults(response) {
45
+ const entity = Array.isArray(response.data) ? response.data[0] : response.data;
46
+ if (!entity)
47
+ return "Aucune donnée par défaut retournée pour cette ressource / ce mois.";
48
+ const attrs = entity.attributes ?? {};
49
+ const included = response.included ?? [];
50
+ const byType = (type) => included.filter((i) => i.type === type);
51
+ const resourceRef = entity.relationships?.resource?.data;
52
+ const agencyRef = entity.relationships?.agency?.data;
53
+ const resource = byType("resource").find((r) => r.id === resourceRef?.id) ?? byType("resource")[0];
54
+ const agency = byType("agency").find((a) => a.id === agencyRef?.id) ?? byType("agency")[0];
55
+ const resourceAttrs = resource?.attributes ?? {};
56
+ const agencyAttrs = agency?.attributes ?? {};
57
+ const lines = [
58
+ `CRA — ressource #${resource?.id ?? resourceRef?.id ?? "?"}${resourceAttrs.firstName || resourceAttrs.lastName ? ` (${[resourceAttrs.firstName, resourceAttrs.lastName].filter(Boolean).join(" ")})` : ""}, mois ${String(attrs.term ?? "?")}`,
59
+ `Agence: #${agency?.id ?? "?"}${agencyAttrs.name ? ` (${String(agencyAttrs.name)})` : ""} | Unité d'œuvre: ${String(attrs.workUnitRate ?? agencyAttrs.workUnitRate ?? "?")} | Calendrier: ${String(agencyAttrs.calendar ?? "?")}`,
60
+ ];
61
+ const types = resourceAttrs.workUnitTypesAllowed ?? [];
62
+ lines.push("", `Types d'unité d'œuvre autorisés (${types.length}) — utiliser \`reference\` comme \`workUnitTypeReference\` :`);
63
+ lines.push(...(types.length
64
+ ? types.map((t) => ` reference=${t.reference} | ${t.name ?? ""} | ${t.activityType ?? ""}`)
65
+ : [" (aucun type publié pour cette ressource)"]));
66
+ const projects = byType("project");
67
+ lines.push("", `Imputations possibles (${projects.length}) — \`projectId\` / \`deliveryId\` :`);
68
+ if (projects.length === 0) {
69
+ lines.push(" (aucune imputation disponible pour cette ressource sur ce mois — seules des absences peuvent être saisies)");
70
+ }
71
+ else {
72
+ for (const p of projects) {
73
+ const ref = p.attributes?.reference ?? p.attributes?.title ?? "";
74
+ const refs = (name) => (p.relationships?.[name]?.data ?? []).map((d) => `#${d.id}`);
75
+ const deliveryIds = refs("deliveries");
76
+ const batchIds = refs("batches");
77
+ const parts = [
78
+ ` projectId=${p.id}`,
79
+ String(ref),
80
+ `deliveryId ∈ ${deliveryIds.length ? deliveryIds.join(", ") : "(aucune prestation — imputation impossible)"}`,
81
+ ];
82
+ if (batchIds.length)
83
+ parts.push(`batchId ∈ ${batchIds.join(", ")}`);
84
+ lines.push(parts.join(" | "));
85
+ }
86
+ }
87
+ const planned = attrs.plannedTimes ?? [];
88
+ const totalPlanned = planned.reduce((n, t) => n + (Number(t.duration) || 0), 0);
89
+ lines.push("", `Planning prévu (${planned.length} ligne(s), ${totalPlanned} unité(s)) — base de saisie à confirmer jour par jour :`);
90
+ if (planned.length === 0) {
91
+ lines.push(" (aucune ligne planifiée)");
92
+ }
93
+ else {
94
+ const byKey = new Map();
95
+ for (const t of planned) {
96
+ const key = `projectId=${t.project?.id ?? "-"} | deliveryId=${t.delivery?.id ?? "-"} | workUnitTypeReference=${t.workUnitType?.reference ?? "-"} (${t.workUnitType?.name ?? ""})`;
97
+ const day = t.startDate ?? "";
98
+ const cur = byKey.get(key) ?? { count: 0, duration: 0, first: day, last: day };
99
+ cur.count += 1;
100
+ cur.duration += Number(t.duration) || 0;
101
+ if (day && (cur.first === "" || day < cur.first))
102
+ cur.first = day;
103
+ if (day && day > cur.last)
104
+ cur.last = day;
105
+ byKey.set(key, cur);
106
+ }
107
+ for (const [key, v] of byKey)
108
+ lines.push(` ${key} : ${v.count} jour(s), ${v.duration} unité(s), du ${v.first} au ${v.last}`);
48
109
  }
49
- if (result.length > CHARACTER_LIMIT) {
50
- result = result.substring(0, CHARACTER_LIMIT) + "\n\n[Résultats tronqués...]";
110
+ const absences = attrs.absencesTimes ?? [];
111
+ if (absences.length) {
112
+ lines.push("", `Absences déjà posées sur le mois (${absences.length}) — ne pas les ressaisir :`);
113
+ for (const t of absences)
114
+ lines.push(` ${t.startDate ?? "?"} | ${t.duration ?? "?"} | ${t.workUnitType?.name ?? ""} (reference=${t.workUnitType?.reference ?? "?"})`);
51
115
  }
52
- return result;
116
+ return lines.join("\n");
117
+ }
118
+ /**
119
+ * One line per times report. The rows carry no name / title, so the generic
120
+ * summary would print a bare `[timesreport #id]`; this names the window, the
121
+ * state and the totals instead. Truncation, the `shown/total` banner and the
122
+ * `fields` projection come from `formatListResponse` (#243) — this file used
123
+ * to carry its own formatter that cut mid-line and crashed on `data: null`.
124
+ */
125
+ export function timesheetSummary(item) {
126
+ const attrs = item.attributes ?? {};
127
+ const parts = [`[timesreport #${item.id}]`];
128
+ if (attrs.term)
129
+ parts.push(`Mois: ${attrs.term}`);
130
+ if (attrs.startDate)
131
+ parts.push(`Du: ${attrs.startDate}`);
132
+ if (attrs.endDate)
133
+ parts.push(`Au: ${attrs.endDate}`);
134
+ if (attrs.state !== undefined)
135
+ parts.push(`Statut: ${attrs.state}`);
136
+ if (attrs.totalDays !== undefined)
137
+ parts.push(`Jours: ${attrs.totalDays}`);
138
+ if (attrs.totalHours !== undefined)
139
+ parts.push(`Heures: ${attrs.totalHours}`);
140
+ return parts.join(" | ");
53
141
  }
142
+ const OPTS = {
143
+ entityName: "feuille de temps",
144
+ entityNamePlural: "feuilles de temps",
145
+ apiPath: "/times-reports",
146
+ prefix: "boond_timesheets",
147
+ };
54
148
  export function registerTimesheetTools(server) {
55
- server.registerTool("boond_timesheets_create", {
56
- title: "Créer une feuille de temps",
149
+ server.registerTool("boond_timesheets_default", {
150
+ title: "Référentiels de saisie d'un CRA",
57
151
  description: composeDescription({
58
- purpose: "Crée la feuille de temps (CRA) d'un mois pour une ressource.",
59
- when: "pour ouvrir le CRA d'un couple (ressource, mois) qui n'existe pas encore.",
60
- instead: "`boond_timesheets_search` d'abord : l'API ne déduplique pas, et deux CRA peuvent coexister sur le même mois.",
152
+ purpose: "Renvoie ce qu'il faut savoir avant d'écrire le CRA d'une ressource sur un mois : types d'unité d'œuvre autorisés, couples projet/prestation imputables, planning prévu et absences déjà posées.",
153
+ when: "AVANT `boond_timesheets_create` / `boond_timesheets_update` — les codes `workUnitTypeReference` ne sont publiés nulle part ailleurs (ni dans `boond_application_dictionary`, ni sur `boond_agencies_get`).",
154
+ instead: "aucun autre outil ne donne ces codes ; `boond_timesheets_get` pour relire un CRA existant.",
61
155
  behaviour: [
62
- "`term` est le mois au format `YYYY-MM` — un CRA couvre un mois entier, pas une journée.",
63
- "Écriture non idempotente.",
156
+ "Lecture seule (`GET /times-reports/default`). La réponse brute est réduite : les types viennent de la ressource incluse (`workUnitTypesAllowed`), les imputations des projets inclus, le planning de `plannedTimes`.",
157
+ "Une ressource sans imputation ce mois-là ne peut saisir que des absences.",
64
158
  ],
65
- returns: "confirmation et fiche du CRA créé.",
159
+ returns: "texte : agence, types d'unité d'œuvre (reference | libellé | activityType), imputations `projectId` / `deliveryId` (et `batchId`), planning prévu agrégé par imputation, absences déjà posées.",
66
160
  }),
67
- inputSchema: TimesheetCreateSchema,
161
+ inputSchema: TimesheetDefaultSchema,
68
162
  annotations: {
69
- readOnlyHint: false,
163
+ readOnlyHint: true,
70
164
  destructiveHint: false,
71
- idempotentHint: false,
165
+ idempotentHint: true,
72
166
  openWorldHint: false,
73
167
  },
74
168
  }, async (params) => {
75
- const { resourceId, projectId, ...attrs } = params;
76
- const body = buildJsonApiBody("timesreport", attrs);
77
- const relationships = {};
78
- if (resourceId)
79
- relationships.resource = { data: { id: resourceId, type: "resource" } };
80
- if (projectId)
81
- relationships.project = { data: { id: projectId, type: "project" } };
82
- if (Object.keys(relationships).length > 0) {
83
- body.data.relationships = relationships;
84
- }
85
- const response = await apiRequest("/times-reports", "POST", body);
86
- const text = formatDetailResponse(response);
87
- const entity = Array.isArray(response.data) ? response.data[0] : response.data;
88
- return {
89
- content: [
90
- { type: "text", text: `✅ Feuille de temps créée avec succès.\nID: ${entity?.id}\n\n${text}` },
169
+ const query = { resource: params.resourceId, term: params.term };
170
+ if (params.agencyId)
171
+ query.agency = params.agencyId;
172
+ const response = await apiRequest("/times-reports/default", "GET", undefined, query);
173
+ return { content: [{ type: "text", text: formatTimesheetDefaults(response) }] };
174
+ });
175
+ registerCreateTool(server, OPTS, TimesheetCreateSchema, buildTimesheetBody, {
176
+ title: "Créer une feuille de temps",
177
+ description: composeDescription({
178
+ purpose: "Crée la feuille de temps (CRA) d'un mois pour une ressource, avec ses lignes jour par jour.",
179
+ when: "pour ouvrir le CRA d'un couple (ressource, mois) qui n'existe pas encore, après `boond_timesheets_default`.",
180
+ instead: "`boond_timesheets_search` (`startMonth`/`endMonth` + `resourceId`) d'abord : l'API ne déduplique pas, deux CRA peuvent coexister sur le même mois ; `boond_timesheets_update` si le CRA existe déjà.",
181
+ behaviour: [
182
+ "Un CRA est un conteneur mensuel (`term` + `resource`) ; les lignes vont dans `regularTimes[]` (production et absences) et `exceptionalTimes[]` — chaque ligne = un jour, une durée, un type d'unité d'œuvre, et pour la production un couple `projectId` / `deliveryId` imputable.",
183
+ "`state` n'est pas un champ d'écriture : il est piloté par le workflow de validation (`boond_validations_search`).",
184
+ "Écriture non idempotente. Modèle d'écriture établi en lecture depuis l'API (forme des CRA existants et de `/times-reports/default`), pas encore éprouvé en écriture sur un tenant de test — voir CLAUDE.md.",
91
185
  ],
92
- };
186
+ returns: "confirmation, ID créé (`structuredContent.id`) et fiche du CRA.",
187
+ }),
188
+ });
189
+ registerUpdateTool(server, OPTS, TimesheetUpdateSchema, buildTimesheetBody, {
190
+ method: "PUT",
191
+ title: "Modifier une feuille de temps",
192
+ description: composeDescription({
193
+ purpose: "Met à jour un CRA existant : commentaires, clôture, ou remplacement complet de ses lignes.",
194
+ when: "pour compléter ou corriger le CRA d'un mois déjà ouvert (trouvé via `boond_timesheets_search`).",
195
+ instead: "`boond_timesheets_create` si aucun CRA n'existe encore pour ce couple (ressource, mois).",
196
+ behaviour: [
197
+ "Mise à jour partielle sur les champs simples, MAIS `regularTimes` / `exceptionalTimes` **remplacent le tableau entier** : relire le CRA (`boond_timesheets_get`), fusionner, renvoyer la liste complète — envoyer une seule ligne efface le mois.",
198
+ "`state` n'est pas un champ d'écriture (workflow de validation).",
199
+ ],
200
+ returns: "confirmation et fiche du CRA mis à jour.",
201
+ }),
93
202
  });
94
203
  // Get timesheets for a specific resource
95
204
  server.registerTool("boond_resources_timesheets", {
96
205
  title: "Feuilles de temps d'une ressource",
97
- description: `Récupère les feuilles de temps (times reports) d'une ressource par son ID, avec filtre optionnel par mois/année.
98
-
99
- Args:
100
- - resourceId (string): ID de la ressource
101
- - month (number, optional): Mois (1-12), défaut: mois courant
102
- - year (number, optional): Année (ex: 2025), défaut: année courante
206
+ description: `Récupère les feuilles de temps (times reports) d'une ressource par son ID, avec filtre optionnel par mois/année (défaut : mois courant).
103
207
 
104
208
  Returns: Liste des feuilles de temps de la ressource avec jours/heures et statut.`,
105
209
  inputSchema: ResourceTimesheetSchema,
@@ -116,63 +220,29 @@ Returns: Liste des feuilles de temps de la ressource avec jours/heures et statut
116
220
  if (params.year !== undefined)
117
221
  queryParams["year"] = params.year;
118
222
  const response = await apiRequest(`/resources/${params.resourceId}/times-reports`, "GET", undefined, queryParams);
119
- const text = formatTimesheetSummary(response);
223
+ const text = formatListResponse(response, "feuille de temps", undefined, timesheetSummary);
120
224
  return {
121
225
  content: [{ type: "text", text }],
122
226
  };
123
227
  });
124
- // Search all timesheets
125
- server.registerTool("boond_timesheets_search", {
228
+ // Search all timesheets — the factory hands `timesheetSummary` to the list
229
+ // formatter and to `structuredContent` alike (#243).
230
+ registerSearchTool(server, OPTS, {
231
+ schema: TimesheetSearchSchema,
232
+ summaryFn: timesheetSummary,
126
233
  title: "Rechercher des feuilles de temps",
127
- description: `Recherche des feuilles de temps (CRA mensuels) dans BoondManager.
234
+ description: `Recherche des feuilles de temps (CRA mensuels) dans BoondManager, par mois, ressource, état de validation (\`validationStates\` : waitingForValidation / validated / rejected) et périmètre (\`perimeter*\`).
128
235
 
129
236
  ⚠️ \`startMonth\` et \`endMonth\` (format YYYY-MM) sont requis par l'API — passer YYYY-MM-DD ou les omettre renvoie un 422.
130
237
 
131
- Args:
132
- - startMonth (string, requis): Mois de début YYYY-MM (ex: '2025-01')
133
- - endMonth (string, requis): Mois de fin YYYY-MM (ex: '2025-03')
134
- - keywords (string, optional): Mots-clés
135
- - page (number): Numéro de page (défaut: 1)
136
- - pageSize (number): Résultats par page (défaut: 30)
137
-
138
- Returns: Liste des feuilles de temps correspondantes.`,
139
- inputSchema: TimesheetSearchSchema,
140
- annotations: {
141
- readOnlyHint: true,
142
- destructiveHint: false,
143
- idempotentHint: true,
144
- openWorldHint: true,
145
- },
146
- }, async (params, extra) => {
147
- const query = buildSearchQuery(params);
148
- const response = await apiSearch("/times-reports", query, progressReporterFrom(extra));
149
- const text = formatTimesheetSummary(response);
150
- return {
151
- content: [{ type: "text", text }],
152
- };
238
+ Returns: Liste des feuilles de temps correspondantes (une ligne par CRA : mois, période, statut, totaux).`,
153
239
  });
154
- // Get a specific timesheet by ID
155
- server.registerTool("boond_timesheets_get", {
240
+ registerGetTool(server, OPTS, {
241
+ withTab: false,
156
242
  title: "Détails d'une feuille de temps",
157
- description: `Récupère les informations détaillées d'une feuille de temps par son ID.
158
-
159
- Args:
160
- - id (string): Identifiant unique de la feuille de temps
243
+ description: `Récupère les informations détaillées d'une feuille de temps (CRA mensuel) par son ID.
161
244
 
162
245
  Returns: Données JSON complètes de la feuille de temps (jours, heures, statut, détails).`,
163
- inputSchema: TimesheetGetSchema,
164
- annotations: {
165
- readOnlyHint: true,
166
- destructiveHint: false,
167
- idempotentHint: true,
168
- openWorldHint: false,
169
- },
170
- }, async (params) => {
171
- const response = await apiRequest(`/times-reports/${params.id}`);
172
- const text = formatDetailResponse(response);
173
- return {
174
- content: [{ type: "text", text }],
175
- };
176
246
  });
177
247
  }
178
248
  //# sourceMappingURL=timesheets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"timesheets.js","sourceRoot":"","sources":["../../src/tools/timesheets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timesheets.js","sourceRoot":"","sources":["../../src/tools/timesheets.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /** `/todolists` payload (issue #254): `agencyIds` → `agencies` relationship, the rest as attributes (`models.todolist`). */
3
+ export declare function buildTodolistBody(params: Record<string, unknown>): unknown;
2
4
  export declare function registerTodolistTools(server: McpServer): void;
3
5
  //# sourceMappingURL=todolists.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"todolists.d.ts","sourceRoot":"","sources":["../../src/tools/todolists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAG7D"}
1
+ {"version":3,"file":"todolists.d.ts","sourceRoot":"","sources":["../../src/tools/todolists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCzE,4HAA4H;AAC5H,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO1E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6C7D"}
@@ -1,12 +1,75 @@
1
- import { registerSearchTool, registerGetTool } from "./crud-factory.js";
1
+ import { TasksGetSchema, TodolistCreateSchema } from "../schemas/index.js";
2
+ import { apiRequest, formatTabResponse } from "../services/boond-client.js";
3
+ import { buildJsonApiBody, registerCreateTool, registerGetTool, registerSearchTool } from "./crud-factory.js";
4
+ import { composeDescription } from "./description-builders.js";
2
5
  const OPTS = {
3
6
  entityName: "todolist",
4
7
  entityNamePlural: "todolists",
5
8
  apiPath: "/todolists",
6
9
  prefix: "boond_todolists",
7
10
  };
11
+ /** API collection of each entity `tasks.raml` covers (14). */
12
+ const TASK_ENTITY_PATH = {
13
+ candidate: "/candidates",
14
+ resource: "/resources",
15
+ contact: "/contacts",
16
+ company: "/companies",
17
+ opportunity: "/opportunities",
18
+ project: "/projects",
19
+ order: "/orders",
20
+ product: "/products",
21
+ purchase: "/purchases",
22
+ positioning: "/positionings",
23
+ invoice: "/invoices",
24
+ contract: "/contracts",
25
+ delivery: "/deliveries",
26
+ payment: "/payments",
27
+ form: "/forms",
28
+ };
29
+ /** `/todolists` payload (issue #254): `agencyIds` → `agencies` relationship, the rest as attributes (`models.todolist`). */
30
+ export function buildTodolistBody(params) {
31
+ const { agencyIds, ...attrs } = params;
32
+ const body = buildJsonApiBody("todolist", attrs);
33
+ if (Array.isArray(agencyIds) && agencyIds.length > 0) {
34
+ body.data.relationships = { agencies: { data: agencyIds.map((id) => ({ id: String(id), type: "agency" })) } };
35
+ }
36
+ return body;
37
+ }
8
38
  export function registerTodolistTools(server) {
9
39
  registerSearchTool(server, OPTS);
10
40
  registerGetTool(server, OPTS, { withTab: false });
41
+ // Issue #254: `POST /todolists` is documented (todolists/search.raml), its
42
+ // body is not — built from `models.todolist`, not exercised.
43
+ registerCreateTool(server, OPTS, TodolistCreateSchema, buildTodolistBody, {
44
+ title: "Créer une todolist",
45
+ description: composeDescription({
46
+ purpose: "Crée une todolist (modèle de tâches) avec ses tâches ordonnées, applicable à un type de fiche.",
47
+ when: "pour définir une checklist réutilisable (onboarding consultant, préparation de facturation…).",
48
+ instead: "`boond_todolists_search` d'abord : l'API ne déduplique pas les titres.",
49
+ behaviour: [
50
+ "Corps déduit de `models.todolist` (`title`, `profile`, `profileTypesOf`, `profileStates`, `tasks[]`, relation `agencies`) — non éprouvé sur un tenant de test.",
51
+ "Les tâches d'une fiche (`boond_tasks_get`) ne se créent pas ici : aucune route de création de tâche n'est documentée.",
52
+ ],
53
+ returns: "confirmation et ID de la todolist (`structuredContent.id`).",
54
+ }),
55
+ });
56
+ // Issue #254: `GET /{entity}/{id}/tasks` exists on 14 entities (tasks.raml);
57
+ // one parameterised tool rather than 14 tabs. No write: the RAML documents
58
+ // only `get`, and no `/tasks` collection exists (404 on the doc site).
59
+ server.registerTool("boond_tasks_get", {
60
+ title: "Tâches d'un enregistrement",
61
+ description: composeDescription({
62
+ purpose: "Liste les tâches (todolist instanciée) d'un candidat, d'une ressource, d'un contact, d'une société, d'une opportunité, d'un projet, d'une commande, d'un produit, d'un achat, d'un positionnement, d'une facture, d'un contrat, d'une prestation ou d'un paiement.",
63
+ when: "pour voir où en est la checklist d'une fiche (tâches faites / à faire, validées par qui).",
64
+ instead: "`boond_actions_search` pour les rappels datés — une tâche est un item de checklist, une action un événement daté. Aucune route de création de tâche n'est documentée par l'API.",
65
+ returns: "les tâches (`description`, `state`, `row`, `validatedAt`, `validatedBy`, sous-tâches). Lecture seule.",
66
+ }),
67
+ inputSchema: TasksGetSchema,
68
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
69
+ }, async (params) => {
70
+ const { entity, id } = params;
71
+ const response = await apiRequest(`${TASK_ENTITY_PATH[entity]}/${id}/tasks`);
72
+ return { content: [{ type: "text", text: formatTabResponse(response) }] };
73
+ });
11
74
  }
12
75
  //# sourceMappingURL=todolists.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"todolists.js","sourceRoot":"","sources":["../../src/tools/todolists.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAExE,MAAM,IAAI,GAAG;IACX,UAAU,EAAE,UAAU;IACtB,gBAAgB,EAAE,WAAW;IAC7B,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,iBAAiB;CAC1B,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"todolists.js","sourceRoot":"","sources":["../../src/tools/todolists.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,12 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ export declare const ValidationDecisionOutputSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ decided: z.ZodBoolean;
6
+ state: z.ZodOptional<z.ZodString>;
7
+ documentType: z.ZodOptional<z.ZodString>;
8
+ documentId: z.ZodOptional<z.ZodString>;
9
+ reason: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>;
2
11
  export declare function registerValidationTools(server: McpServer): void;
3
12
  //# sourceMappingURL=validations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validations.d.ts","sourceRoot":"","sources":["../../src/tools/validations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0D/D"}
1
+ {"version":3,"file":"validations.d.ts","sourceRoot":"","sources":["../../src/tools/validations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,8BAA8B;;;;;;;iBAUzC,CAAC;AAcH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoH/D"}