@goxtechnologies/connectwise-psa-mcp 1.1.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 (147) hide show
  1. package/data/connectwise_api.db +0 -0
  2. package/data/manage.json +298179 -0
  3. package/dist/index.d.ts +10 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +116 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/operations/analytics-extended.d.ts +6 -0
  8. package/dist/operations/analytics-extended.d.ts.map +1 -0
  9. package/dist/operations/analytics-extended.js +825 -0
  10. package/dist/operations/analytics-extended.js.map +1 -0
  11. package/dist/operations/analytics-msp-assets.d.ts +3 -0
  12. package/dist/operations/analytics-msp-assets.d.ts.map +1 -0
  13. package/dist/operations/analytics-msp-assets.js +180 -0
  14. package/dist/operations/analytics-msp-assets.js.map +1 -0
  15. package/dist/operations/analytics-msp-clients.d.ts +3 -0
  16. package/dist/operations/analytics-msp-clients.d.ts.map +1 -0
  17. package/dist/operations/analytics-msp-clients.js +198 -0
  18. package/dist/operations/analytics-msp-clients.js.map +1 -0
  19. package/dist/operations/analytics-msp-comms.d.ts +3 -0
  20. package/dist/operations/analytics-msp-comms.d.ts.map +1 -0
  21. package/dist/operations/analytics-msp-comms.js +127 -0
  22. package/dist/operations/analytics-msp-comms.js.map +1 -0
  23. package/dist/operations/analytics-msp-contracts.d.ts +3 -0
  24. package/dist/operations/analytics-msp-contracts.d.ts.map +1 -0
  25. package/dist/operations/analytics-msp-contracts.js +91 -0
  26. package/dist/operations/analytics-msp-contracts.js.map +1 -0
  27. package/dist/operations/analytics-msp-financial.d.ts +3 -0
  28. package/dist/operations/analytics-msp-financial.d.ts.map +1 -0
  29. package/dist/operations/analytics-msp-financial.js +300 -0
  30. package/dist/operations/analytics-msp-financial.js.map +1 -0
  31. package/dist/operations/analytics-msp-procurement.d.ts +3 -0
  32. package/dist/operations/analytics-msp-procurement.d.ts.map +1 -0
  33. package/dist/operations/analytics-msp-procurement.js +78 -0
  34. package/dist/operations/analytics-msp-procurement.js.map +1 -0
  35. package/dist/operations/analytics-msp-projects.d.ts +3 -0
  36. package/dist/operations/analytics-msp-projects.d.ts.map +1 -0
  37. package/dist/operations/analytics-msp-projects.js +190 -0
  38. package/dist/operations/analytics-msp-projects.js.map +1 -0
  39. package/dist/operations/analytics-msp-sales.d.ts +3 -0
  40. package/dist/operations/analytics-msp-sales.d.ts.map +1 -0
  41. package/dist/operations/analytics-msp-sales.js +99 -0
  42. package/dist/operations/analytics-msp-sales.js.map +1 -0
  43. package/dist/operations/analytics-msp-schedule.d.ts +3 -0
  44. package/dist/operations/analytics-msp-schedule.d.ts.map +1 -0
  45. package/dist/operations/analytics-msp-schedule.js +339 -0
  46. package/dist/operations/analytics-msp-schedule.js.map +1 -0
  47. package/dist/operations/analytics-msp-team.d.ts +3 -0
  48. package/dist/operations/analytics-msp-team.d.ts.map +1 -0
  49. package/dist/operations/analytics-msp-team.js +195 -0
  50. package/dist/operations/analytics-msp-team.js.map +1 -0
  51. package/dist/operations/analytics-msp-tickets.d.ts +3 -0
  52. package/dist/operations/analytics-msp-tickets.d.ts.map +1 -0
  53. package/dist/operations/analytics-msp-tickets.js +578 -0
  54. package/dist/operations/analytics-msp-tickets.js.map +1 -0
  55. package/dist/operations/analytics-msp-time.d.ts +3 -0
  56. package/dist/operations/analytics-msp-time.d.ts.map +1 -0
  57. package/dist/operations/analytics-msp-time.js +485 -0
  58. package/dist/operations/analytics-msp-time.js.map +1 -0
  59. package/dist/operations/analytics-msp-utils.d.ts +49 -0
  60. package/dist/operations/analytics-msp-utils.d.ts.map +1 -0
  61. package/dist/operations/analytics-msp-utils.js +157 -0
  62. package/dist/operations/analytics-msp-utils.js.map +1 -0
  63. package/dist/operations/analytics.d.ts +9 -0
  64. package/dist/operations/analytics.d.ts.map +1 -0
  65. package/dist/operations/analytics.js +742 -0
  66. package/dist/operations/analytics.js.map +1 -0
  67. package/dist/operations/executor.d.ts +10 -0
  68. package/dist/operations/executor.d.ts.map +1 -0
  69. package/dist/operations/executor.js +243 -0
  70. package/dist/operations/executor.js.map +1 -0
  71. package/dist/operations/registry.d.ts +16 -0
  72. package/dist/operations/registry.d.ts.map +1 -0
  73. package/dist/operations/registry.js +847 -0
  74. package/dist/operations/registry.js.map +1 -0
  75. package/dist/services/api-database.d.ts +38 -0
  76. package/dist/services/api-database.d.ts.map +1 -0
  77. package/dist/services/api-database.js +191 -0
  78. package/dist/services/api-database.js.map +1 -0
  79. package/dist/services/cache.d.ts +12 -0
  80. package/dist/services/cache.d.ts.map +1 -0
  81. package/dist/services/cache.js +32 -0
  82. package/dist/services/cache.js.map +1 -0
  83. package/dist/services/connectwise-api.d.ts +43 -0
  84. package/dist/services/connectwise-api.d.ts.map +1 -0
  85. package/dist/services/connectwise-api.js +198 -0
  86. package/dist/services/connectwise-api.js.map +1 -0
  87. package/dist/services/db-builder.d.ts +11 -0
  88. package/dist/services/db-builder.d.ts.map +1 -0
  89. package/dist/services/db-builder.js +237 -0
  90. package/dist/services/db-builder.js.map +1 -0
  91. package/dist/services/fast-memory.d.ts +39 -0
  92. package/dist/services/fast-memory.d.ts.map +1 -0
  93. package/dist/services/fast-memory.js +147 -0
  94. package/dist/services/fast-memory.js.map +1 -0
  95. package/dist/services/load-env.d.ts +15 -0
  96. package/dist/services/load-env.d.ts.map +1 -0
  97. package/dist/services/load-env.js +59 -0
  98. package/dist/services/load-env.js.map +1 -0
  99. package/dist/tools/batch.d.ts +9 -0
  100. package/dist/tools/batch.d.ts.map +1 -0
  101. package/dist/tools/batch.js +159 -0
  102. package/dist/tools/batch.js.map +1 -0
  103. package/dist/tools/composite.d.ts +9 -0
  104. package/dist/tools/composite.d.ts.map +1 -0
  105. package/dist/tools/composite.js +353 -0
  106. package/dist/tools/composite.js.map +1 -0
  107. package/dist/tools/discovery.d.ts +9 -0
  108. package/dist/tools/discovery.d.ts.map +1 -0
  109. package/dist/tools/discovery.js +245 -0
  110. package/dist/tools/discovery.js.map +1 -0
  111. package/dist/tools/execution.d.ts +9 -0
  112. package/dist/tools/execution.d.ts.map +1 -0
  113. package/dist/tools/execution.js +130 -0
  114. package/dist/tools/execution.js.map +1 -0
  115. package/dist/tools/memory.d.ts +9 -0
  116. package/dist/tools/memory.d.ts.map +1 -0
  117. package/dist/tools/memory.js +152 -0
  118. package/dist/tools/memory.js.map +1 -0
  119. package/dist/tools/operations.d.ts +9 -0
  120. package/dist/tools/operations.d.ts.map +1 -0
  121. package/dist/tools/operations.js +214 -0
  122. package/dist/tools/operations.js.map +1 -0
  123. package/dist/tools/pagination.d.ts +9 -0
  124. package/dist/tools/pagination.d.ts.map +1 -0
  125. package/dist/tools/pagination.js +133 -0
  126. package/dist/tools/pagination.js.map +1 -0
  127. package/dist/tools/validation.d.ts +9 -0
  128. package/dist/tools/validation.d.ts.map +1 -0
  129. package/dist/tools/validation.js +705 -0
  130. package/dist/tools/validation.js.map +1 -0
  131. package/dist/types/index.d.ts +145 -0
  132. package/dist/types/index.d.ts.map +1 -0
  133. package/dist/types/index.js +3 -0
  134. package/dist/types/index.js.map +1 -0
  135. package/dist/types/operations.d.ts +30 -0
  136. package/dist/types/operations.d.ts.map +1 -0
  137. package/dist/types/operations.js +3 -0
  138. package/dist/types/operations.js.map +1 -0
  139. package/dist/utils/conditions.d.ts +20 -0
  140. package/dist/utils/conditions.d.ts.map +1 -0
  141. package/dist/utils/conditions.js +78 -0
  142. package/dist/utils/conditions.js.map +1 -0
  143. package/dist/utils/formatters.d.ts +35 -0
  144. package/dist/utils/formatters.d.ts.map +1 -0
  145. package/dist/utils/formatters.js +337 -0
  146. package/dist/utils/formatters.js.map +1 -0
  147. package/package.json +46 -0
@@ -0,0 +1,578 @@
1
+ // ConnectWise PSA MCP Server — MSP Analytics: Ticket & Service Metrics
2
+ // Implements 8 MSP analytics handlers focused on ticket volume, aging, SLA,
3
+ // backlog trend, escalation, touch counts, and response/resolution times.
4
+ import { getAPI } from '../services/connectwise-api.js';
5
+ import { num, nested, daysAgo, daysSince, round2, groupByDate, groupByField, pct, hoursDisplay, daysDisplay, mdTable, settledWarning, } from './analytics-msp-utils.js';
6
+ export const mspTicketHandlers = {};
7
+ function reg(name, handler) { mspTicketHandlers[name] = handler; }
8
+ // ---------------------------------------------------------------------------
9
+ // Helpers
10
+ // ---------------------------------------------------------------------------
11
+ /** Returns the hours difference between two ISO date strings. */
12
+ function hoursBetween(from, to) {
13
+ if (!from || !to)
14
+ return 0;
15
+ return (new Date(to).getTime() - new Date(from).getTime()) / 3_600_000;
16
+ }
17
+ /** Returns the days difference between two ISO date strings. */
18
+ function daysBetween(from, to) {
19
+ return hoursBetween(from, to) / 24;
20
+ }
21
+ /** SLA target hours keyed by priority sort value (1=P1..4=P4). */
22
+ const SLA_HOURS = { 1: 4, 2: 8, 3: 24, 4: 72 };
23
+ /** Maps a priority name string to its numeric sort value. */
24
+ function prioritySort(name) {
25
+ const n = name.toLowerCase();
26
+ if (n.includes('1') || n.includes('critical'))
27
+ return 1;
28
+ if (n.includes('2') || n.includes('high'))
29
+ return 2;
30
+ if (n.includes('3') || n.includes('medium'))
31
+ return 3;
32
+ return 4;
33
+ }
34
+ /** Formats a decimal hours value as hours or days depending on magnitude. */
35
+ function resolutionDisplay(hours) {
36
+ if (hours < 1)
37
+ return `${round2(hours * 60)}m`;
38
+ if (hours < 48)
39
+ return hoursDisplay(hours);
40
+ return daysDisplay(round2(hours / 24));
41
+ }
42
+ // ---------------------------------------------------------------------------
43
+ // 1. ticket_volume_by_company
44
+ // ---------------------------------------------------------------------------
45
+ reg('ticket_volume_by_company', async (params) => {
46
+ const api = getAPI();
47
+ const days = num(params['days'], 30);
48
+ const cutoff = daysAgo(days);
49
+ const [opened, closed] = await Promise.all([
50
+ api.paginatedFetch('/service/tickets', `dateEntered>=[${cutoff}]`, 'id,company/name,dateEntered,closedFlag,closedDate', 5000),
51
+ api.paginatedFetch('/service/tickets', `closedDate>=[${cutoff}]`, 'id,company/name,dateEntered,closedFlag,closedDate', 5000),
52
+ ]);
53
+ if (opened.items.length === 0 && closed.items.length === 0) {
54
+ return `No ticket activity found in the last ${days} days.`;
55
+ }
56
+ // Group opened tickets by company
57
+ const openedByCompany = groupByField(opened.items, 'company/name');
58
+ // Group closed tickets by company (use a Set of IDs to avoid double-counting tickets
59
+ // that were both opened and closed in the period)
60
+ const closedByCompany = groupByField(closed.items, 'company/name');
61
+ // Collect all company names
62
+ const companies = new Set([
63
+ ...openedByCompany.keys(),
64
+ ...closedByCompany.keys(),
65
+ ]);
66
+ const rows = [];
67
+ for (const company of companies) {
68
+ const openedTickets = openedByCompany.get(company) ?? [];
69
+ const closedTickets = closedByCompany.get(company) ?? [];
70
+ const openedCount = openedTickets.length;
71
+ const closedCount = closedTickets.length;
72
+ const net = openedCount - closedCount;
73
+ // Avg age: computed over still-open tickets in the opened set
74
+ const stillOpen = openedTickets.filter(t => !t['closedFlag']);
75
+ const totalAgeDays = stillOpen.reduce((acc, t) => acc + daysSince(String(t['dateEntered'] ?? '')), 0);
76
+ rows.push({ company, openedCount, closedCount, net, totalAgeDays, openCount: stillOpen.length });
77
+ }
78
+ rows.sort((a, b) => b.openedCount - a.openedCount);
79
+ const tableRows = rows.map(r => [
80
+ r.company,
81
+ String(r.openedCount),
82
+ String(r.closedCount),
83
+ r.net >= 0 ? `+${r.net}` : String(r.net),
84
+ r.openCount > 0 ? daysDisplay(round2(r.totalAgeDays / r.openCount)) : 'N/A',
85
+ ]);
86
+ const totalOpened = rows.reduce((s, r) => s + r.openedCount, 0);
87
+ const totalClosed = rows.reduce((s, r) => s + r.closedCount, 0);
88
+ return [
89
+ `## Ticket Volume by Company (last ${days} days)`,
90
+ ``,
91
+ `**Total Opened:** ${totalOpened} | **Total Closed:** ${totalClosed} | **Net:** ${totalOpened - totalClosed >= 0 ? '+' : ''}${totalOpened - totalClosed}`,
92
+ ``,
93
+ mdTable(['Company', 'Opened', 'Closed', 'Net', 'Avg Age (Open)'], tableRows),
94
+ ].join('\n');
95
+ });
96
+ // ---------------------------------------------------------------------------
97
+ // 2. ticket_aging_summary
98
+ // ---------------------------------------------------------------------------
99
+ reg('ticket_aging_summary', async (params) => {
100
+ const api = getAPI();
101
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
102
+ const conditions = board
103
+ ? `closedFlag=false AND board/name="${board}"`
104
+ : 'closedFlag=false';
105
+ const result = await api.paginatedFetch('/service/tickets', conditions, 'id,dateEntered,summary,company/name', 5000);
106
+ if (result.items.length === 0) {
107
+ return board
108
+ ? `No open tickets found on board "${board}".`
109
+ : 'No open tickets found.';
110
+ }
111
+ const buckets = [
112
+ { label: '0–7d', min: 0, max: 7, tickets: [] },
113
+ { label: '7–14d', min: 7, max: 14, tickets: [] },
114
+ { label: '14–30d', min: 14, max: 30, tickets: [] },
115
+ { label: '30–60d', min: 30, max: 60, tickets: [] },
116
+ { label: '60+d', min: 60, max: Infinity, tickets: [] },
117
+ ];
118
+ for (const t of result.items) {
119
+ const age = daysSince(String(t['dateEntered'] ?? ''));
120
+ const bucket = buckets.find(b => age >= b.min && age < b.max);
121
+ if (bucket)
122
+ bucket.tickets.push(t);
123
+ }
124
+ const total = result.items.length;
125
+ const tableRows = buckets.map(b => {
126
+ const oldest = b.tickets.reduce((prev, t) => {
127
+ if (!prev)
128
+ return t;
129
+ return daysSince(String(t['dateEntered'] ?? '')) >
130
+ daysSince(String(prev['dateEntered'] ?? ''))
131
+ ? t
132
+ : prev;
133
+ }, null);
134
+ const oldestLabel = oldest
135
+ ? `#${oldest['id']} (${daysDisplay(daysSince(String(oldest['dateEntered'] ?? '')))})`
136
+ : 'N/A';
137
+ return [
138
+ b.label,
139
+ String(b.tickets.length),
140
+ pct(b.tickets.length, total),
141
+ oldestLabel,
142
+ ];
143
+ });
144
+ const title = board
145
+ ? `## Ticket Aging Summary — Board: ${board}`
146
+ : '## Ticket Aging Summary';
147
+ return [
148
+ title,
149
+ ``,
150
+ `**Total Open Tickets:** ${total}`,
151
+ ``,
152
+ mdTable(['Age Bucket', 'Count', '%', 'Oldest Ticket'], tableRows),
153
+ ].join('\n');
154
+ });
155
+ // ---------------------------------------------------------------------------
156
+ // 3. sla_compliance_report
157
+ // ---------------------------------------------------------------------------
158
+ reg('sla_compliance_report', async (params) => {
159
+ const api = getAPI();
160
+ const days = num(params['days'], 30);
161
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
162
+ const cutoff = daysAgo(days);
163
+ let conditions = `closedFlag=true AND closedDate>=[${cutoff}]`;
164
+ if (board)
165
+ conditions += ` AND board/name="${board}"`;
166
+ const result = await api.paginatedFetch('/service/tickets', conditions, 'id,dateEntered,closedDate,resolvedDate,priority/name,priority/id', 5000);
167
+ if (result.items.length === 0) {
168
+ return `No closed tickets found in the last ${days} days${board ? ` on board "${board}"` : ''}.`;
169
+ }
170
+ const stats = new Map();
171
+ for (const t of result.items) {
172
+ const priorityName = nested(t, 'priority', 'name');
173
+ const sort = prioritySort(priorityName);
174
+ const slaHours = SLA_HOURS[sort] ?? 72;
175
+ if (!stats.has(sort)) {
176
+ stats.set(sort, {
177
+ label: priorityName !== 'N/A' ? priorityName : `P${sort}`,
178
+ sort,
179
+ total: 0,
180
+ met: 0,
181
+ missed: 0,
182
+ indeterminate: 0,
183
+ slaHours,
184
+ });
185
+ }
186
+ const entry = stats.get(sort);
187
+ entry.total++;
188
+ // Use resolvedDate if available, fall back to closedDate
189
+ const resolvedIso = String(t['resolvedDate'] ?? t['closedDate'] ?? '');
190
+ const enteredIso = String(t['dateEntered'] ?? '');
191
+ const elapsed = hoursBetween(enteredIso, resolvedIso);
192
+ if (elapsed > 0 && elapsed <= slaHours) {
193
+ entry.met++;
194
+ }
195
+ else if (elapsed > slaHours) {
196
+ entry.missed++;
197
+ }
198
+ else {
199
+ // elapsed <= 0: missing or invalid timestamp — data quality issue
200
+ entry.indeterminate++;
201
+ }
202
+ }
203
+ const sorted = [...stats.values()].sort((a, b) => a.sort - b.sort);
204
+ const totalIndeterminate = sorted.reduce((acc, s) => acc + s.indeterminate, 0);
205
+ const hasIndeterminate = totalIndeterminate > 0;
206
+ const headers = hasIndeterminate
207
+ ? ['Priority', 'SLA Target', 'Total', 'Met SLA', 'Missed', 'Indeterminate', 'Compliance %']
208
+ : ['Priority', 'SLA Target', 'Total', 'Met SLA', 'Missed', 'Compliance %'];
209
+ const tableRows = sorted.map(s => {
210
+ const row = [
211
+ s.label,
212
+ `SLA: ${s.slaHours}h`,
213
+ String(s.total),
214
+ String(s.met),
215
+ String(s.missed),
216
+ ];
217
+ if (hasIndeterminate)
218
+ row.push(String(s.indeterminate));
219
+ row.push(pct(s.met, s.total));
220
+ return row;
221
+ });
222
+ const totalMet = sorted.reduce((acc, s) => acc + s.met, 0);
223
+ const totalAll = sorted.reduce((acc, s) => acc + s.total, 0);
224
+ const title = board
225
+ ? `## SLA Compliance Report — Board: ${board} (last ${days} days)`
226
+ : `## SLA Compliance Report (last ${days} days)`;
227
+ const summaryParts = [
228
+ `**Total Tickets:** ${totalAll}`,
229
+ `**Met SLA:** ${totalMet}`,
230
+ `**Overall Compliance:** ${pct(totalMet, totalAll)}`,
231
+ ];
232
+ if (hasIndeterminate)
233
+ summaryParts.push(`**Indeterminate:** ${totalIndeterminate}`);
234
+ return [
235
+ title,
236
+ ``,
237
+ summaryParts.join(' | '),
238
+ ``,
239
+ mdTable(headers, tableRows),
240
+ ``,
241
+ `*SLA targets: P1=4h, P2=8h, P3=24h, P4=72h*`,
242
+ ...(hasIndeterminate ? [`*Indeterminate: elapsed <= 0 — missing or invalid timestamp data.*`] : []),
243
+ ].join('\n');
244
+ });
245
+ // ---------------------------------------------------------------------------
246
+ // 4. backlog_trend
247
+ // ---------------------------------------------------------------------------
248
+ reg('backlog_trend', async (params) => {
249
+ const api = getAPI();
250
+ const days = num(params['days'], 30);
251
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
252
+ const cutoff = daysAgo(days);
253
+ let openedCond = `dateEntered>=[${cutoff}]`;
254
+ let closedCond = `closedDate>=[${cutoff}]`;
255
+ if (board) {
256
+ openedCond += ` AND board/name="${board}"`;
257
+ closedCond += ` AND board/name="${board}"`;
258
+ }
259
+ const [openedResult, closedResult] = await Promise.all([
260
+ api.paginatedFetch('/service/tickets', openedCond, 'id,dateEntered', 5000),
261
+ api.paginatedFetch('/service/tickets', closedCond, 'id,closedDate', 5000),
262
+ ]);
263
+ if (openedResult.items.length === 0 && closedResult.items.length === 0) {
264
+ return `No ticket activity found in the last ${days} days${board ? ` on board "${board}"` : ''}.`;
265
+ }
266
+ // Build per-day maps
267
+ const openedByDay = groupByDate(openedResult.items, 'dateEntered');
268
+ const closedByDay = groupByDate(closedResult.items, 'closedDate');
269
+ // Generate all dates in range
270
+ const allDates = new Set([
271
+ ...openedByDay.keys(),
272
+ ...closedByDay.keys(),
273
+ ]);
274
+ const sortedDates = [...allDates].sort();
275
+ let running = 0;
276
+ const tableRows = [];
277
+ for (const date of sortedDates) {
278
+ const newCount = (openedByDay.get(date) ?? []).length;
279
+ const closedCount = (closedByDay.get(date) ?? []).length;
280
+ const netChange = newCount - closedCount;
281
+ running += netChange;
282
+ tableRows.push([
283
+ date,
284
+ String(newCount),
285
+ String(closedCount),
286
+ netChange >= 0 ? `+${netChange}` : String(netChange),
287
+ String(running),
288
+ ]);
289
+ }
290
+ const title = board
291
+ ? `## Backlog Trend — Board: ${board} (last ${days} days)`
292
+ : `## Backlog Trend (last ${days} days)`;
293
+ return [
294
+ title,
295
+ ``,
296
+ `**Period:** ${sortedDates[0] ?? 'N/A'} to ${sortedDates[sortedDates.length - 1] ?? 'N/A'} | **Running Net:** ${running >= 0 ? '+' : ''}${running}`,
297
+ ``,
298
+ mdTable(['Date', 'New', 'Closed', 'Net Change', 'Net Change (Cumulative)'], tableRows),
299
+ ].join('\n');
300
+ });
301
+ // ---------------------------------------------------------------------------
302
+ // 5. escalation_frequency
303
+ // ---------------------------------------------------------------------------
304
+ reg('escalation_frequency', async (params) => {
305
+ const api = getAPI();
306
+ const days = num(params['days'], 30);
307
+ const cutoff = daysAgo(days);
308
+ // Fetch open tickets that have been updated significantly after entry —
309
+ // a pragmatic proxy for tickets that received escalation attention.
310
+ // We look for open tickets updated after creation and sort by staleness gap.
311
+ const result = await api.paginatedFetch('/service/tickets', `closedFlag=false AND dateEntered>=[${cutoff}]`, 'id,summary,priority/name,status/name,company/name,dateEntered,_info/lastUpdated', 2000);
312
+ if (result.items.length === 0) {
313
+ return `No open tickets found in the last ${days} days.`;
314
+ }
315
+ const candidates = [];
316
+ for (const t of result.items) {
317
+ const entered = String(t['dateEntered'] ?? '');
318
+ const lastUpdated = nested(t, '_info', 'lastUpdated');
319
+ // Gap between creation and last update in days (longer gap = more churn)
320
+ const gapDays = lastUpdated !== 'N/A'
321
+ ? round2(daysBetween(entered, lastUpdated))
322
+ : 0;
323
+ // Threshold: only surface tickets with meaningful update gaps (> 1 day)
324
+ if (gapDays > 1) {
325
+ candidates.push({
326
+ id: String(t['id'] ?? ''),
327
+ summary: String(t['summary'] ?? '').substring(0, 60),
328
+ priority: nested(t, 'priority', 'name'),
329
+ status: nested(t, 'status', 'name'),
330
+ company: nested(t, 'company', 'name'),
331
+ updateGapDays: gapDays,
332
+ });
333
+ }
334
+ }
335
+ if (candidates.length === 0) {
336
+ return `No escalation candidates detected in the last ${days} days (no open tickets with update gaps > 1 day).`;
337
+ }
338
+ candidates.sort((a, b) => b.updateGapDays - a.updateGapDays);
339
+ const tableRows = candidates.slice(0, 50).map(c => [
340
+ `#${c.id}`,
341
+ c.summary,
342
+ c.priority,
343
+ c.status,
344
+ daysDisplay(c.updateGapDays),
345
+ c.company,
346
+ ]);
347
+ return [
348
+ `## Escalation Frequency (last ${days} days)`,
349
+ ``,
350
+ `**Candidates with activity gap > 1 day:** ${candidates.length}`,
351
+ ``,
352
+ `*Sorted by days between ticket creation and last update — longer gaps indicate repeated touches or escalation churn.*`,
353
+ ``,
354
+ mdTable(['Ticket #', 'Summary', 'Priority', 'Status', 'Update Gap', 'Company'], tableRows),
355
+ ].join('\n');
356
+ });
357
+ // ---------------------------------------------------------------------------
358
+ // 6. ticket_touch_count
359
+ // ---------------------------------------------------------------------------
360
+ reg('ticket_touch_count', async (params) => {
361
+ const api = getAPI();
362
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
363
+ const conditions = board
364
+ ? `closedFlag=false AND board/name="${board}"`
365
+ : 'closedFlag=false';
366
+ const ticketsResult = await api.paginatedFetch('/service/tickets', conditions, 'id,summary,company/name,dateEntered', 2000);
367
+ if (ticketsResult.items.length === 0) {
368
+ return board
369
+ ? `No open tickets found on board "${board}".`
370
+ : 'No open tickets found.';
371
+ }
372
+ // Limit to top 50 tickets by age (oldest first) to avoid excessive API calls
373
+ const sortedTickets = ticketsResult.items
374
+ .slice()
375
+ .sort((a, b) => daysSince(String(b['dateEntered'] ?? '')) - daysSince(String(a['dateEntered'] ?? '')))
376
+ .slice(0, 50);
377
+ const touchData = await Promise.allSettled(sortedTickets.map(async (t) => {
378
+ const ticketId = String(t['id'] ?? '');
379
+ const timeEntries = await api.paginatedFetch(`/service/tickets/${ticketId}/timeentries`, undefined, 'id,actualHours,dateEntered', 500);
380
+ const touches = timeEntries.items.length;
381
+ const totalHours = timeEntries.items.reduce((acc, e) => acc + num(e['actualHours']), 0);
382
+ // Most recent time entry date
383
+ const lastTouch = timeEntries.items
384
+ .map(e => String(e['dateEntered'] ?? ''))
385
+ .filter(Boolean)
386
+ .sort()
387
+ .pop() ?? 'N/A';
388
+ return {
389
+ id: ticketId,
390
+ summary: String(t['summary'] ?? '').substring(0, 55),
391
+ company: nested(t, 'company', 'name'),
392
+ touches,
393
+ totalHours: round2(totalHours),
394
+ lastTouch: lastTouch !== 'N/A' ? lastTouch.substring(0, 10) : 'N/A',
395
+ };
396
+ }));
397
+ const rows = touchData
398
+ .filter((r) => r.status === 'fulfilled')
399
+ .map(r => r.value)
400
+ .sort((a, b) => b.touches - a.touches);
401
+ if (rows.length === 0) {
402
+ return 'Unable to retrieve time entry data for open tickets.';
403
+ }
404
+ const tableRows = rows.map(r => [
405
+ `#${r.id}`,
406
+ r.summary,
407
+ String(r.touches),
408
+ hoursDisplay(r.totalHours),
409
+ r.lastTouch,
410
+ r.company,
411
+ ]);
412
+ const title = board
413
+ ? `## Ticket Touch Count — Board: ${board}`
414
+ : '## Ticket Touch Count (Open Tickets)';
415
+ return [
416
+ title,
417
+ ``,
418
+ `**Tickets Analyzed:** ${rows.length} | **Total Touches:** ${rows.reduce((s, r) => s + r.touches, 0)} | **Total Hours:** ${hoursDisplay(rows.reduce((s, r) => s + r.totalHours, 0))}`,
419
+ ``,
420
+ mdTable(['Ticket #', 'Summary', 'Touches', 'Total Hours', 'Last Touch', 'Company'], tableRows),
421
+ ].join('\n') + settledWarning(touchData, 'sub-requests');
422
+ });
423
+ // ---------------------------------------------------------------------------
424
+ // 7. first_response_metrics
425
+ // ---------------------------------------------------------------------------
426
+ reg('first_response_metrics', async (params) => {
427
+ const api = getAPI();
428
+ const days = num(params['days'], 30);
429
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
430
+ const cutoff = daysAgo(days);
431
+ let conditions = `closedFlag=true AND closedDate>=[${cutoff}]`;
432
+ if (board)
433
+ conditions += ` AND board/name="${board}"`;
434
+ const ticketsResult = await api.paginatedFetch('/service/tickets', conditions, 'id,dateEntered,priority/name', 2000);
435
+ if (ticketsResult.items.length === 0) {
436
+ return `No closed tickets found in the last ${days} days${board ? ` on board "${board}"` : ''}.`;
437
+ }
438
+ // For a representative sample, fetch first notes for up to 100 tickets
439
+ const sample = ticketsResult.items.slice(0, 100);
440
+ const responseSamples = await Promise.allSettled(sample.map(async (t) => {
441
+ const ticketId = String(t['id'] ?? '');
442
+ const entered = String(t['dateEntered'] ?? '');
443
+ if (!entered)
444
+ return null;
445
+ // Fetch notes for this ticket, ordered by date (first note = first response)
446
+ const notesResult = await api.paginatedFetch(`/service/tickets/${ticketId}/notes`, undefined, 'id,dateCreated', 50);
447
+ const firstNote = notesResult.items
448
+ .map(n => String(n['dateCreated'] ?? ''))
449
+ .filter(Boolean)
450
+ .sort()[0];
451
+ if (!firstNote)
452
+ return null;
453
+ const responseHours = hoursBetween(entered, firstNote);
454
+ if (responseHours < 0)
455
+ return null;
456
+ const priorityName = nested(t, 'priority', 'name');
457
+ return {
458
+ prioritySort: prioritySort(priorityName),
459
+ priorityName: priorityName !== 'N/A' ? priorityName : 'Unknown',
460
+ responseHours,
461
+ };
462
+ }));
463
+ // Group valid samples by priority
464
+ const byPriority = new Map();
465
+ for (const result of responseSamples) {
466
+ if (result.status !== 'fulfilled' || result.value === null)
467
+ continue;
468
+ const s = result.value;
469
+ if (!byPriority.has(s.prioritySort))
470
+ byPriority.set(s.prioritySort, []);
471
+ byPriority.get(s.prioritySort).push(s);
472
+ }
473
+ if (byPriority.size === 0) {
474
+ return 'No first-response data could be computed (no notes found on sampled tickets).';
475
+ }
476
+ const sorted = [...byPriority.entries()].sort(([a], [b]) => a - b);
477
+ const tableRows = sorted.map(([, samples]) => {
478
+ const label = samples[0]?.priorityName ?? 'Unknown';
479
+ const hours = samples.map(s => s.responseHours);
480
+ const syntheticItems = hours.map(h => ({ h }));
481
+ // Use utility functions via synthetic items
482
+ const avgH = hours.reduce((a, b) => a + b, 0) / hours.length;
483
+ const sortedH = hours.slice().sort((a, b) => a - b);
484
+ const mid = Math.floor(sortedH.length / 2);
485
+ const medH = sortedH.length % 2 === 0
486
+ ? ((sortedH[mid - 1] ?? 0) + (sortedH[mid] ?? 0)) / 2
487
+ : (sortedH[mid] ?? 0);
488
+ const p90idx = Math.ceil(0.9 * sortedH.length) - 1;
489
+ const p90H = sortedH[Math.max(0, Math.min(p90idx, sortedH.length - 1))] ?? 0;
490
+ return [
491
+ label,
492
+ resolutionDisplay(avgH),
493
+ resolutionDisplay(medH),
494
+ resolutionDisplay(p90H),
495
+ String(samples.length),
496
+ ];
497
+ });
498
+ const title = board
499
+ ? `## First Response Metrics — Board: ${board} (last ${days} days)`
500
+ : `## First Response Metrics (last ${days} days)`;
501
+ return [
502
+ title,
503
+ ``,
504
+ `**Sample Size:** ${sample.length} tickets`,
505
+ ``,
506
+ mdTable(['Priority', 'Avg Response', 'Median', 'P90', 'Count'], tableRows),
507
+ ].join('\n') + settledWarning(responseSamples, 'sub-requests');
508
+ });
509
+ // ---------------------------------------------------------------------------
510
+ // 8. ticket_resolution_metrics
511
+ // ---------------------------------------------------------------------------
512
+ reg('ticket_resolution_metrics', async (params) => {
513
+ const api = getAPI();
514
+ const days = num(params['days'], 30);
515
+ const board = typeof params['board'] === 'string' ? params['board'] : '';
516
+ const cutoff = daysAgo(days);
517
+ let conditions = `closedFlag=true AND closedDate>=[${cutoff}]`;
518
+ if (board)
519
+ conditions += ` AND board/name="${board}"`;
520
+ const result = await api.paginatedFetch('/service/tickets', conditions, 'id,dateEntered,closedDate,priority/name', 5000);
521
+ if (result.items.length === 0) {
522
+ return `No closed tickets found in the last ${days} days${board ? ` on board "${board}"` : ''}.`;
523
+ }
524
+ // Build per-priority collections of resolution hours
525
+ const byPriority = new Map();
526
+ for (const t of result.items) {
527
+ const entered = String(t['dateEntered'] ?? '');
528
+ const closed = String(t['closedDate'] ?? '');
529
+ if (!entered || !closed)
530
+ continue;
531
+ const resolutionHours = hoursBetween(entered, closed);
532
+ if (resolutionHours < 0)
533
+ continue;
534
+ const priorityName = nested(t, 'priority', 'name');
535
+ const sort = prioritySort(priorityName);
536
+ const label = priorityName !== 'N/A' ? priorityName : `P${sort}`;
537
+ if (!byPriority.has(sort))
538
+ byPriority.set(sort, { label, hours: [] });
539
+ byPriority.get(sort).hours.push(resolutionHours);
540
+ }
541
+ if (byPriority.size === 0) {
542
+ return `No resolution time data could be computed for tickets in the last ${days} days.`;
543
+ }
544
+ const sorted = [...byPriority.entries()].sort(([a], [b]) => a - b);
545
+ const tableRows = sorted.map(([, entry]) => {
546
+ const { label, hours } = entry;
547
+ const sortedH = hours.slice().sort((a, b) => a - b);
548
+ const count = sortedH.length;
549
+ const avgH = hours.reduce((a, b) => a + b, 0) / count;
550
+ const mid = Math.floor(count / 2);
551
+ const medH = count % 2 === 0
552
+ ? ((sortedH[mid - 1] ?? 0) + (sortedH[mid] ?? 0)) / 2
553
+ : (sortedH[mid] ?? 0);
554
+ const p90idx = Math.ceil(0.9 * count) - 1;
555
+ const p90H = sortedH[Math.max(0, Math.min(p90idx, count - 1))] ?? 0;
556
+ return [
557
+ label,
558
+ resolutionDisplay(avgH),
559
+ resolutionDisplay(medH),
560
+ resolutionDisplay(p90H),
561
+ String(count),
562
+ ];
563
+ });
564
+ const totalCount = sorted.reduce((s, [, e]) => s + e.hours.length, 0);
565
+ const allHours = sorted.flatMap(([, e]) => e.hours);
566
+ const overallAvg = allHours.reduce((a, b) => a + b, 0) / allHours.length;
567
+ const title = board
568
+ ? `## Ticket Resolution Metrics — Board: ${board} (last ${days} days)`
569
+ : `## Ticket Resolution Metrics (last ${days} days)`;
570
+ return [
571
+ title,
572
+ ``,
573
+ `**Tickets Analyzed:** ${totalCount} | **Overall Avg Resolution:** ${resolutionDisplay(overallAvg)}`,
574
+ ``,
575
+ mdTable(['Priority', 'Avg Resolution', 'Median', 'P90', 'Count'], tableRows),
576
+ ].join('\n');
577
+ });
578
+ //# sourceMappingURL=analytics-msp-tickets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-msp-tickets.js","sourceRoot":"","sources":["../../src/operations/analytics-msp-tickets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type MspHandler } from './analytics-msp-utils.js';
2
+ export declare const mspTimeHandlers: Record<string, MspHandler>;
3
+ //# sourceMappingURL=analytics-msp-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-msp-time.d.ts","sourceRoot":"","sources":["../../src/operations/analytics-msp-time.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,UAAU,EAehB,MAAM,0BAA0B,CAAC;AAElC,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAM,CAAC"}