@t4dhg/mcp-factorial 3.2.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -4
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +175 -286
- package/dist/api.js.map +1 -1
- package/dist/endpoints.d.ts +51 -0
- package/dist/endpoints.d.ts.map +1 -0
- package/dist/endpoints.js +63 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +22 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js +106 -257
- package/dist/index.js.map +1 -1
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +2 -1
- package/dist/pagination.js.map +1 -1
- package/dist/tool-utils.d.ts +59 -0
- package/dist/tool-utils.d.ts.map +1 -0
- package/dist/tool-utils.js +71 -0
- package/dist/tool-utils.js.map +1 -0
- package/dist/utils.d.ts +33 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +48 -0
- package/dist/utils.js.map +1 -0
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -7,6 +7,9 @@ import { fetchList, fetchOne, postOne, patchOne, deleteOne, postAction } from '.
|
|
|
7
7
|
import { cache, cached, CACHE_TTL, CacheManager } from './cache.js';
|
|
8
8
|
import { buildPaginationParams, paginateResponse, sliceForPagination, } from './pagination.js';
|
|
9
9
|
import { AuditAction, auditedOperation } from './audit.js';
|
|
10
|
+
import { validateId } from './utils.js';
|
|
11
|
+
import { ENDPOINTS, endpointWithId, endpointWithAction } from './endpoints.js';
|
|
12
|
+
import { NotFoundError } from './errors.js';
|
|
10
13
|
// ============================================================================
|
|
11
14
|
// Employee endpoints
|
|
12
15
|
// ============================================================================
|
|
@@ -19,7 +22,7 @@ export async function listEmployees(options) {
|
|
|
19
22
|
// For filtered requests, we need to fetch all and filter client-side
|
|
20
23
|
// because the API doesn't reliably filter
|
|
21
24
|
if (options?.team_id || options?.location_id) {
|
|
22
|
-
const allEmployees = await cached('employees:all', () => fetchList(
|
|
25
|
+
const allEmployees = await cached('employees:all', () => fetchList(ENDPOINTS.employees), CACHE_TTL.employees);
|
|
23
26
|
let filtered = allEmployees;
|
|
24
27
|
if (options.team_id) {
|
|
25
28
|
filtered = filtered.filter(e => e.team_ids?.includes(options.team_id));
|
|
@@ -30,7 +33,7 @@ export async function listEmployees(options) {
|
|
|
30
33
|
return sliceForPagination(filtered, params);
|
|
31
34
|
}
|
|
32
35
|
// Without filters, use pagination directly
|
|
33
|
-
const employees = await cached(cacheKey, () => fetchList(
|
|
36
|
+
const employees = await cached(cacheKey, () => fetchList(ENDPOINTS.employees, { params }), CACHE_TTL.employees);
|
|
34
37
|
return paginateResponse(employees, params.page, params.limit);
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
@@ -41,12 +44,10 @@ export async function listEmployees(options) {
|
|
|
41
44
|
* if the direct endpoint fails or returns no data.
|
|
42
45
|
*/
|
|
43
46
|
export async function getEmployee(id) {
|
|
44
|
-
|
|
45
|
-
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
46
|
-
}
|
|
47
|
+
validateId(id, 'employee');
|
|
47
48
|
// Try the direct endpoint first
|
|
48
49
|
try {
|
|
49
|
-
const employee = await cached(`employee:${id}`, () => fetchOne(
|
|
50
|
+
const employee = await cached(`employee:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.employees, id)), CACHE_TTL.employees);
|
|
50
51
|
// If we got a valid employee, return it
|
|
51
52
|
if (employee) {
|
|
52
53
|
return employee;
|
|
@@ -55,13 +56,13 @@ export async function getEmployee(id) {
|
|
|
55
56
|
catch (error) {
|
|
56
57
|
// If direct fetch fails with NotFoundError, try fallback
|
|
57
58
|
// (other errors will be re-thrown below)
|
|
58
|
-
if (!(error instanceof
|
|
59
|
+
if (!(error instanceof NotFoundError)) {
|
|
59
60
|
throw error;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
// Fallback: Fetch all employees and filter (same approach as searchEmployees)
|
|
63
64
|
// This works around Factorial API limitations with the individual employee endpoint
|
|
64
|
-
const allEmployees = await cached('employees:all', () => fetchList(
|
|
65
|
+
const allEmployees = await cached('employees:all', () => fetchList(ENDPOINTS.employees), CACHE_TTL.employees);
|
|
65
66
|
const employee = allEmployees.find(emp => emp.id === id);
|
|
66
67
|
if (!employee) {
|
|
67
68
|
throw new Error(`Employee with ID ${id} not found.`);
|
|
@@ -75,7 +76,7 @@ export async function searchEmployees(query) {
|
|
|
75
76
|
if (!query || query.trim().length < 2) {
|
|
76
77
|
throw new Error('Search query must be at least 2 characters long.');
|
|
77
78
|
}
|
|
78
|
-
const allEmployees = await cached('employees:all', () => fetchList(
|
|
79
|
+
const allEmployees = await cached('employees:all', () => fetchList(ENDPOINTS.employees), CACHE_TTL.employees);
|
|
79
80
|
const lowerQuery = query.toLowerCase().trim();
|
|
80
81
|
return allEmployees.filter(emp => emp.full_name?.toLowerCase().includes(lowerQuery) ||
|
|
81
82
|
emp.email?.toLowerCase().includes(lowerQuery) ||
|
|
@@ -91,17 +92,15 @@ export async function searchEmployees(query) {
|
|
|
91
92
|
export async function listTeams(options) {
|
|
92
93
|
const params = buildPaginationParams(options);
|
|
93
94
|
const cacheKey = CacheManager.key('teams', options);
|
|
94
|
-
const teams = await cached(cacheKey, () => fetchList(
|
|
95
|
+
const teams = await cached(cacheKey, () => fetchList(ENDPOINTS.teams), CACHE_TTL.teams);
|
|
95
96
|
return sliceForPagination(teams, params);
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
99
|
* Get a specific team by ID
|
|
99
100
|
*/
|
|
100
101
|
export async function getTeam(id) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
return cached(`team:${id}`, () => fetchOne(`/teams/teams/${id}`), CACHE_TTL.teams);
|
|
102
|
+
validateId(id, 'team');
|
|
103
|
+
return cached(`team:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.teams, id)), CACHE_TTL.teams);
|
|
105
104
|
}
|
|
106
105
|
// ============================================================================
|
|
107
106
|
// Location endpoints
|
|
@@ -112,17 +111,15 @@ export async function getTeam(id) {
|
|
|
112
111
|
export async function listLocations(options) {
|
|
113
112
|
const params = buildPaginationParams(options);
|
|
114
113
|
const cacheKey = CacheManager.key('locations', options);
|
|
115
|
-
const locations = await cached(cacheKey, () => fetchList(
|
|
114
|
+
const locations = await cached(cacheKey, () => fetchList(ENDPOINTS.locations), CACHE_TTL.locations);
|
|
116
115
|
return sliceForPagination(locations, params);
|
|
117
116
|
}
|
|
118
117
|
/**
|
|
119
118
|
* Get a specific location by ID
|
|
120
119
|
*/
|
|
121
120
|
export async function getLocation(id) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
return cached(`location:${id}`, () => fetchOne(`/locations/locations/${id}`), CACHE_TTL.locations);
|
|
121
|
+
validateId(id, 'location');
|
|
122
|
+
return cached(`location:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.locations, id)), CACHE_TTL.locations);
|
|
126
123
|
}
|
|
127
124
|
// ============================================================================
|
|
128
125
|
// Contract endpoints
|
|
@@ -131,13 +128,13 @@ export async function getLocation(id) {
|
|
|
131
128
|
* List contracts, optionally filtered by employee ID
|
|
132
129
|
*/
|
|
133
130
|
export async function listContracts(employeeId, options) {
|
|
134
|
-
if (employeeId !== undefined
|
|
135
|
-
|
|
131
|
+
if (employeeId !== undefined) {
|
|
132
|
+
validateId(employeeId, 'employee');
|
|
136
133
|
}
|
|
137
134
|
const params = buildPaginationParams(options);
|
|
138
135
|
// Note: The API doesn't reliably filter by employee_id query param,
|
|
139
136
|
// so we fetch all contracts and filter client-side
|
|
140
|
-
const allContracts = await cached('contracts:all', () => fetchList(
|
|
137
|
+
const allContracts = await cached('contracts:all', () => fetchList(ENDPOINTS.contracts), CACHE_TTL.contracts);
|
|
141
138
|
const filtered = employeeId !== undefined
|
|
142
139
|
? allContracts.filter(c => c.employee_id === employeeId)
|
|
143
140
|
: allContracts;
|
|
@@ -163,32 +160,28 @@ export async function listLeaves(options) {
|
|
|
163
160
|
queryParams.start_on_gte = options.start_on_gte;
|
|
164
161
|
if (options?.start_on_lte)
|
|
165
162
|
queryParams.start_on_lte = options.start_on_lte;
|
|
166
|
-
const leaves = await fetchList(
|
|
163
|
+
const leaves = await fetchList(ENDPOINTS.leaves, { params: queryParams });
|
|
167
164
|
return paginateResponse(leaves, params.page, params.limit);
|
|
168
165
|
}
|
|
169
166
|
/**
|
|
170
167
|
* Get a specific leave by ID
|
|
171
168
|
*/
|
|
172
169
|
export async function getLeave(id) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
return fetchOne(`/timeoff/leaves/${id}`);
|
|
170
|
+
validateId(id, 'leave');
|
|
171
|
+
return fetchOne(endpointWithId(ENDPOINTS.leaves, id));
|
|
177
172
|
}
|
|
178
173
|
/**
|
|
179
174
|
* List all leave types
|
|
180
175
|
*/
|
|
181
176
|
export async function listLeaveTypes() {
|
|
182
|
-
return cached('leave-types:all', () => fetchList(
|
|
177
|
+
return cached('leave-types:all', () => fetchList(ENDPOINTS.leaveTypes), CACHE_TTL.leaves);
|
|
183
178
|
}
|
|
184
179
|
/**
|
|
185
180
|
* Get a specific leave type by ID
|
|
186
181
|
*/
|
|
187
182
|
export async function getLeaveType(id) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
return fetchOne(`/timeoff/leave-types/${id}`);
|
|
183
|
+
validateId(id, 'leave type');
|
|
184
|
+
return fetchOne(endpointWithId(ENDPOINTS.leaveTypes, id));
|
|
192
185
|
}
|
|
193
186
|
/**
|
|
194
187
|
* List allowances with optional filtering by employee
|
|
@@ -201,7 +194,7 @@ export async function listAllowances(options) {
|
|
|
201
194
|
};
|
|
202
195
|
if (options?.employee_id)
|
|
203
196
|
queryParams.employee_id = options.employee_id;
|
|
204
|
-
const allowances = await fetchList(
|
|
197
|
+
const allowances = await fetchList(ENDPOINTS.allowances, { params: queryParams });
|
|
205
198
|
return paginateResponse(allowances, params.page, params.limit);
|
|
206
199
|
}
|
|
207
200
|
// ============================================================================
|
|
@@ -222,17 +215,15 @@ export async function listShifts(options) {
|
|
|
222
215
|
queryParams.clock_in_gte = options.clock_in_gte;
|
|
223
216
|
if (options?.clock_in_lte)
|
|
224
217
|
queryParams.clock_in_lte = options.clock_in_lte;
|
|
225
|
-
const shifts = await fetchList(
|
|
218
|
+
const shifts = await fetchList(ENDPOINTS.shifts, { params: queryParams });
|
|
226
219
|
return paginateResponse(shifts, params.page, params.limit);
|
|
227
220
|
}
|
|
228
221
|
/**
|
|
229
222
|
* Get a specific shift by ID
|
|
230
223
|
*/
|
|
231
224
|
export async function getShift(id) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
return fetchOne(`/attendance/shifts/${id}`);
|
|
225
|
+
validateId(id, 'shift');
|
|
226
|
+
return fetchOne(endpointWithId(ENDPOINTS.shifts, id));
|
|
236
227
|
}
|
|
237
228
|
// ============================================================================
|
|
238
229
|
// Document endpoints (Read-only)
|
|
@@ -241,16 +232,14 @@ export async function getShift(id) {
|
|
|
241
232
|
* List all folders
|
|
242
233
|
*/
|
|
243
234
|
export async function listFolders() {
|
|
244
|
-
return cached('folders:all', () => fetchList(
|
|
235
|
+
return cached('folders:all', () => fetchList(ENDPOINTS.folders), CACHE_TTL.default);
|
|
245
236
|
}
|
|
246
237
|
/**
|
|
247
238
|
* Get a specific folder by ID
|
|
248
239
|
*/
|
|
249
240
|
export async function getFolder(id) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
return fetchOne(`/documents/folders/${id}`);
|
|
241
|
+
validateId(id, 'folder');
|
|
242
|
+
return fetchOne(endpointWithId(ENDPOINTS.folders, id));
|
|
254
243
|
}
|
|
255
244
|
/**
|
|
256
245
|
* List documents with optional filtering by folder
|
|
@@ -271,20 +260,18 @@ export async function listDocuments(options) {
|
|
|
271
260
|
const baseParams = new URLSearchParams(queryParams).toString();
|
|
272
261
|
const fullParams = baseParams ? `${baseParams}&${employeeIdsParam}` : employeeIdsParam;
|
|
273
262
|
// Make request with custom query string
|
|
274
|
-
const documents = await fetchList(
|
|
263
|
+
const documents = await fetchList(`${ENDPOINTS.documents}?${fullParams}`);
|
|
275
264
|
return paginateResponse(documents, params.page, params.limit);
|
|
276
265
|
}
|
|
277
|
-
const documents = await fetchList(
|
|
266
|
+
const documents = await fetchList(ENDPOINTS.documents, { params: queryParams });
|
|
278
267
|
return paginateResponse(documents, params.page, params.limit);
|
|
279
268
|
}
|
|
280
269
|
/**
|
|
281
270
|
* Get a specific document by ID
|
|
282
271
|
*/
|
|
283
272
|
export async function getDocument(id) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
return fetchOne(`/documents/documents/${id}`);
|
|
273
|
+
validateId(id, 'document');
|
|
274
|
+
return fetchOne(endpointWithId(ENDPOINTS.documents, id));
|
|
288
275
|
}
|
|
289
276
|
// ============================================================================
|
|
290
277
|
// Job Catalog endpoints
|
|
@@ -293,31 +280,27 @@ export async function getDocument(id) {
|
|
|
293
280
|
* List all job roles
|
|
294
281
|
*/
|
|
295
282
|
export async function listJobRoles() {
|
|
296
|
-
return cached('job-roles:all', () => fetchList(
|
|
283
|
+
return cached('job-roles:all', () => fetchList(ENDPOINTS.jobRoles), CACHE_TTL.default);
|
|
297
284
|
}
|
|
298
285
|
/**
|
|
299
286
|
* Get a specific job role by ID
|
|
300
287
|
*/
|
|
301
288
|
export async function getJobRole(id) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
return fetchOne(`/job_catalog/roles/${id}`);
|
|
289
|
+
validateId(id, 'job role');
|
|
290
|
+
return fetchOne(endpointWithId(ENDPOINTS.jobRoles, id));
|
|
306
291
|
}
|
|
307
292
|
/**
|
|
308
293
|
* List all job levels
|
|
309
294
|
*/
|
|
310
295
|
export async function listJobLevels() {
|
|
311
|
-
return cached('job-levels:all', () => fetchList(
|
|
296
|
+
return cached('job-levels:all', () => fetchList(ENDPOINTS.jobLevels), CACHE_TTL.default);
|
|
312
297
|
}
|
|
313
298
|
/**
|
|
314
299
|
* Get a specific job level by ID
|
|
315
300
|
*/
|
|
316
301
|
export async function getJobLevel(id) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
return fetchOne(`/job_catalog/levels/${id}`);
|
|
302
|
+
validateId(id, 'job level');
|
|
303
|
+
return fetchOne(endpointWithId(ENDPOINTS.jobLevels, id));
|
|
321
304
|
}
|
|
322
305
|
// ============================================================================
|
|
323
306
|
// Cache utilities
|
|
@@ -342,7 +325,7 @@ export function invalidateCache(resourceType) {
|
|
|
342
325
|
*/
|
|
343
326
|
export async function createEmployee(input) {
|
|
344
327
|
return auditedOperation(AuditAction.CREATE, 'employee', undefined, async () => {
|
|
345
|
-
const employee = await postOne(
|
|
328
|
+
const employee = await postOne(ENDPOINTS.employees, input);
|
|
346
329
|
cache.invalidatePrefix('employees');
|
|
347
330
|
return employee;
|
|
348
331
|
}, Object.fromEntries(Object.entries(input).map(([k, v]) => [k, { to: v }])));
|
|
@@ -351,11 +334,9 @@ export async function createEmployee(input) {
|
|
|
351
334
|
* Update an existing employee
|
|
352
335
|
*/
|
|
353
336
|
export async function updateEmployee(id, input) {
|
|
354
|
-
|
|
355
|
-
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
356
|
-
}
|
|
337
|
+
validateId(id, 'employee');
|
|
357
338
|
return auditedOperation(AuditAction.UPDATE, 'employee', id, async () => {
|
|
358
|
-
const employee = await patchOne(
|
|
339
|
+
const employee = await patchOne(endpointWithId(ENDPOINTS.employees, id), input);
|
|
359
340
|
cache.invalidate(`employee:${id}`);
|
|
360
341
|
cache.invalidatePrefix('employees');
|
|
361
342
|
return employee;
|
|
@@ -365,11 +346,9 @@ export async function updateEmployee(id, input) {
|
|
|
365
346
|
* Terminate an employee (soft delete)
|
|
366
347
|
*/
|
|
367
348
|
export async function terminateEmployee(id, terminatedOn, reason) {
|
|
368
|
-
|
|
369
|
-
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
370
|
-
}
|
|
349
|
+
validateId(id, 'employee');
|
|
371
350
|
return auditedOperation(AuditAction.TERMINATE, 'employee', id, async () => {
|
|
372
|
-
const employee = await patchOne(
|
|
351
|
+
const employee = await patchOne(endpointWithId(ENDPOINTS.employees, id), {
|
|
373
352
|
terminated_on: terminatedOn,
|
|
374
353
|
});
|
|
375
354
|
cache.invalidate(`employee:${id}`);
|
|
@@ -385,7 +364,7 @@ export async function terminateEmployee(id, terminatedOn, reason) {
|
|
|
385
364
|
*/
|
|
386
365
|
export async function createTeam(input) {
|
|
387
366
|
return auditedOperation(AuditAction.CREATE, 'team', undefined, async () => {
|
|
388
|
-
const team = await postOne(
|
|
367
|
+
const team = await postOne(ENDPOINTS.teams, input);
|
|
389
368
|
cache.invalidatePrefix('teams');
|
|
390
369
|
return team;
|
|
391
370
|
});
|
|
@@ -394,11 +373,9 @@ export async function createTeam(input) {
|
|
|
394
373
|
* Update an existing team
|
|
395
374
|
*/
|
|
396
375
|
export async function updateTeam(id, input) {
|
|
397
|
-
|
|
398
|
-
throw new Error('Invalid team ID. Please provide a positive number.');
|
|
399
|
-
}
|
|
376
|
+
validateId(id, 'team');
|
|
400
377
|
return auditedOperation(AuditAction.UPDATE, 'team', id, async () => {
|
|
401
|
-
const team = await patchOne(
|
|
378
|
+
const team = await patchOne(endpointWithId(ENDPOINTS.teams, id), input);
|
|
402
379
|
cache.invalidate(`team:${id}`);
|
|
403
380
|
cache.invalidatePrefix('teams');
|
|
404
381
|
return team;
|
|
@@ -408,11 +385,9 @@ export async function updateTeam(id, input) {
|
|
|
408
385
|
* Delete a team
|
|
409
386
|
*/
|
|
410
387
|
export async function deleteTeam(id) {
|
|
411
|
-
|
|
412
|
-
throw new Error('Invalid team ID. Please provide a positive number.');
|
|
413
|
-
}
|
|
388
|
+
validateId(id, 'team');
|
|
414
389
|
return auditedOperation(AuditAction.DELETE, 'team', id, async () => {
|
|
415
|
-
await deleteOne(
|
|
390
|
+
await deleteOne(endpointWithId(ENDPOINTS.teams, id));
|
|
416
391
|
cache.invalidate(`team:${id}`);
|
|
417
392
|
cache.invalidatePrefix('teams');
|
|
418
393
|
});
|
|
@@ -425,7 +400,7 @@ export async function deleteTeam(id) {
|
|
|
425
400
|
*/
|
|
426
401
|
export async function createLocation(input) {
|
|
427
402
|
return auditedOperation(AuditAction.CREATE, 'location', undefined, async () => {
|
|
428
|
-
const location = await postOne(
|
|
403
|
+
const location = await postOne(ENDPOINTS.locations, input);
|
|
429
404
|
cache.invalidatePrefix('locations');
|
|
430
405
|
return location;
|
|
431
406
|
});
|
|
@@ -434,11 +409,9 @@ export async function createLocation(input) {
|
|
|
434
409
|
* Update an existing location
|
|
435
410
|
*/
|
|
436
411
|
export async function updateLocation(id, input) {
|
|
437
|
-
|
|
438
|
-
throw new Error('Invalid location ID. Please provide a positive number.');
|
|
439
|
-
}
|
|
412
|
+
validateId(id, 'location');
|
|
440
413
|
return auditedOperation(AuditAction.UPDATE, 'location', id, async () => {
|
|
441
|
-
const location = await patchOne(
|
|
414
|
+
const location = await patchOne(endpointWithId(ENDPOINTS.locations, id), input);
|
|
442
415
|
cache.invalidate(`location:${id}`);
|
|
443
416
|
cache.invalidatePrefix('locations');
|
|
444
417
|
return location;
|
|
@@ -448,11 +421,9 @@ export async function updateLocation(id, input) {
|
|
|
448
421
|
* Delete a location
|
|
449
422
|
*/
|
|
450
423
|
export async function deleteLocation(id) {
|
|
451
|
-
|
|
452
|
-
throw new Error('Invalid location ID. Please provide a positive number.');
|
|
453
|
-
}
|
|
424
|
+
validateId(id, 'location');
|
|
454
425
|
return auditedOperation(AuditAction.DELETE, 'location', id, async () => {
|
|
455
|
-
await deleteOne(
|
|
426
|
+
await deleteOne(endpointWithId(ENDPOINTS.locations, id));
|
|
456
427
|
cache.invalidate(`location:${id}`);
|
|
457
428
|
cache.invalidatePrefix('locations');
|
|
458
429
|
});
|
|
@@ -465,7 +436,7 @@ export async function deleteLocation(id) {
|
|
|
465
436
|
*/
|
|
466
437
|
export async function createLeave(input) {
|
|
467
438
|
return auditedOperation(AuditAction.CREATE, 'leave', undefined, async () => {
|
|
468
|
-
const leave = await postOne(
|
|
439
|
+
const leave = await postOne(ENDPOINTS.leaves, input);
|
|
469
440
|
return leave;
|
|
470
441
|
});
|
|
471
442
|
}
|
|
@@ -473,11 +444,9 @@ export async function createLeave(input) {
|
|
|
473
444
|
* Update a leave request
|
|
474
445
|
*/
|
|
475
446
|
export async function updateLeave(id, input) {
|
|
476
|
-
|
|
477
|
-
throw new Error('Invalid leave ID. Please provide a positive number.');
|
|
478
|
-
}
|
|
447
|
+
validateId(id, 'leave');
|
|
479
448
|
return auditedOperation(AuditAction.UPDATE, 'leave', id, async () => {
|
|
480
|
-
const leave = await patchOne(
|
|
449
|
+
const leave = await patchOne(endpointWithId(ENDPOINTS.leaves, id), input);
|
|
481
450
|
return leave;
|
|
482
451
|
});
|
|
483
452
|
}
|
|
@@ -485,22 +454,18 @@ export async function updateLeave(id, input) {
|
|
|
485
454
|
* Cancel a leave request
|
|
486
455
|
*/
|
|
487
456
|
export async function cancelLeave(id) {
|
|
488
|
-
|
|
489
|
-
throw new Error('Invalid leave ID. Please provide a positive number.');
|
|
490
|
-
}
|
|
457
|
+
validateId(id, 'leave');
|
|
491
458
|
return auditedOperation(AuditAction.DELETE, 'leave', id, async () => {
|
|
492
|
-
await deleteOne(
|
|
459
|
+
await deleteOne(endpointWithId(ENDPOINTS.leaves, id));
|
|
493
460
|
});
|
|
494
461
|
}
|
|
495
462
|
/**
|
|
496
463
|
* Approve a leave request
|
|
497
464
|
*/
|
|
498
465
|
export async function approveLeave(id, input) {
|
|
499
|
-
|
|
500
|
-
throw new Error('Invalid leave ID. Please provide a positive number.');
|
|
501
|
-
}
|
|
466
|
+
validateId(id, 'leave');
|
|
502
467
|
return auditedOperation(AuditAction.APPROVE, 'leave', id, async () => {
|
|
503
|
-
const leave = await postAction(
|
|
468
|
+
const leave = await postAction(endpointWithAction(ENDPOINTS.leaves, id, 'approve'), input || {});
|
|
504
469
|
return leave;
|
|
505
470
|
});
|
|
506
471
|
}
|
|
@@ -508,11 +473,9 @@ export async function approveLeave(id, input) {
|
|
|
508
473
|
* Reject a leave request
|
|
509
474
|
*/
|
|
510
475
|
export async function rejectLeave(id, input) {
|
|
511
|
-
|
|
512
|
-
throw new Error('Invalid leave ID. Please provide a positive number.');
|
|
513
|
-
}
|
|
476
|
+
validateId(id, 'leave');
|
|
514
477
|
return auditedOperation(AuditAction.REJECT, 'leave', id, async () => {
|
|
515
|
-
const leave = await postAction(
|
|
478
|
+
const leave = await postAction(endpointWithAction(ENDPOINTS.leaves, id, 'reject'), input || {});
|
|
516
479
|
return leave;
|
|
517
480
|
});
|
|
518
481
|
}
|
|
@@ -524,7 +487,7 @@ export async function rejectLeave(id, input) {
|
|
|
524
487
|
*/
|
|
525
488
|
export async function createShift(input) {
|
|
526
489
|
return auditedOperation(AuditAction.CREATE, 'shift', undefined, async () => {
|
|
527
|
-
const shift = await postOne(
|
|
490
|
+
const shift = await postOne(ENDPOINTS.shifts, input);
|
|
528
491
|
return shift;
|
|
529
492
|
});
|
|
530
493
|
}
|
|
@@ -532,11 +495,9 @@ export async function createShift(input) {
|
|
|
532
495
|
* Update a shift
|
|
533
496
|
*/
|
|
534
497
|
export async function updateShift(id, input) {
|
|
535
|
-
|
|
536
|
-
throw new Error('Invalid shift ID. Please provide a positive number.');
|
|
537
|
-
}
|
|
498
|
+
validateId(id, 'shift');
|
|
538
499
|
return auditedOperation(AuditAction.UPDATE, 'shift', id, async () => {
|
|
539
|
-
const shift = await patchOne(
|
|
500
|
+
const shift = await patchOne(endpointWithId(ENDPOINTS.shifts, id), input);
|
|
540
501
|
return shift;
|
|
541
502
|
});
|
|
542
503
|
}
|
|
@@ -544,11 +505,9 @@ export async function updateShift(id, input) {
|
|
|
544
505
|
* Delete a shift
|
|
545
506
|
*/
|
|
546
507
|
export async function deleteShift(id) {
|
|
547
|
-
|
|
548
|
-
throw new Error('Invalid shift ID. Please provide a positive number.');
|
|
549
|
-
}
|
|
508
|
+
validateId(id, 'shift');
|
|
550
509
|
return auditedOperation(AuditAction.DELETE, 'shift', id, async () => {
|
|
551
|
-
await deleteOne(
|
|
510
|
+
await deleteOne(endpointWithId(ENDPOINTS.shifts, id));
|
|
552
511
|
});
|
|
553
512
|
}
|
|
554
513
|
// ============================================================================
|
|
@@ -559,17 +518,15 @@ export async function deleteShift(id) {
|
|
|
559
518
|
*/
|
|
560
519
|
export async function listProjects(options) {
|
|
561
520
|
const params = buildPaginationParams(options);
|
|
562
|
-
const projects = await cached(CacheManager.key('projects', options), () => fetchList(
|
|
521
|
+
const projects = await cached(CacheManager.key('projects', options), () => fetchList(ENDPOINTS.projects), CACHE_TTL.default);
|
|
563
522
|
return sliceForPagination(projects, params);
|
|
564
523
|
}
|
|
565
524
|
/**
|
|
566
525
|
* Get a specific project by ID
|
|
567
526
|
*/
|
|
568
527
|
export async function getProject(id) {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
572
|
-
return cached(`project:${id}`, () => fetchOne(`/project_management/projects/${id}`), CACHE_TTL.default);
|
|
528
|
+
validateId(id, 'project');
|
|
529
|
+
return cached(`project:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.projects, id)), CACHE_TTL.default);
|
|
573
530
|
}
|
|
574
531
|
/**
|
|
575
532
|
* List project tasks
|
|
@@ -579,7 +536,7 @@ export async function listProjectTasks(projectId, options) {
|
|
|
579
536
|
const queryParams = {};
|
|
580
537
|
if (projectId)
|
|
581
538
|
queryParams.project_ids = projectId;
|
|
582
|
-
const tasks = await fetchList(
|
|
539
|
+
const tasks = await fetchList(ENDPOINTS.projectTasks, {
|
|
583
540
|
params: queryParams,
|
|
584
541
|
});
|
|
585
542
|
return sliceForPagination(tasks, params);
|
|
@@ -588,10 +545,8 @@ export async function listProjectTasks(projectId, options) {
|
|
|
588
545
|
* Get a specific project task by ID
|
|
589
546
|
*/
|
|
590
547
|
export async function getProjectTask(id) {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
594
|
-
return fetchOne(`/project_management/project_tasks/${id}`);
|
|
548
|
+
validateId(id, 'task');
|
|
549
|
+
return fetchOne(endpointWithId(ENDPOINTS.projectTasks, id));
|
|
595
550
|
}
|
|
596
551
|
/**
|
|
597
552
|
* List project workers
|
|
@@ -601,7 +556,7 @@ export async function listProjectWorkers(projectId, options) {
|
|
|
601
556
|
const queryParams = {};
|
|
602
557
|
if (projectId)
|
|
603
558
|
queryParams.project_ids = projectId;
|
|
604
|
-
const workers = await fetchList(
|
|
559
|
+
const workers = await fetchList(ENDPOINTS.projectWorkers, {
|
|
605
560
|
params: queryParams,
|
|
606
561
|
});
|
|
607
562
|
return sliceForPagination(workers, params);
|
|
@@ -610,10 +565,8 @@ export async function listProjectWorkers(projectId, options) {
|
|
|
610
565
|
* Get a specific project worker by ID
|
|
611
566
|
*/
|
|
612
567
|
export async function getProjectWorker(id) {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
return fetchOne(`/project_management/project_workers/${id}`);
|
|
568
|
+
validateId(id, 'project worker');
|
|
569
|
+
return fetchOne(endpointWithId(ENDPOINTS.projectWorkers, id));
|
|
617
570
|
}
|
|
618
571
|
/**
|
|
619
572
|
* List time records
|
|
@@ -623,7 +576,7 @@ export async function listTimeRecords(projectWorkerId, options) {
|
|
|
623
576
|
const queryParams = {};
|
|
624
577
|
if (projectWorkerId)
|
|
625
578
|
queryParams.project_workers_ids = projectWorkerId;
|
|
626
|
-
const records = await fetchList(
|
|
579
|
+
const records = await fetchList(ENDPOINTS.timeRecords, {
|
|
627
580
|
params: queryParams,
|
|
628
581
|
});
|
|
629
582
|
return sliceForPagination(records, params);
|
|
@@ -632,10 +585,8 @@ export async function listTimeRecords(projectWorkerId, options) {
|
|
|
632
585
|
* Get a specific time record by ID
|
|
633
586
|
*/
|
|
634
587
|
export async function getTimeRecord(id) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
return fetchOne(`/project_management/time_records/${id}`);
|
|
588
|
+
validateId(id, 'time record');
|
|
589
|
+
return fetchOne(endpointWithId(ENDPOINTS.timeRecords, id));
|
|
639
590
|
}
|
|
640
591
|
// ============================================================================
|
|
641
592
|
// Projects & Time Tracking - WRITE endpoints
|
|
@@ -645,7 +596,7 @@ export async function getTimeRecord(id) {
|
|
|
645
596
|
*/
|
|
646
597
|
export async function createProject(input) {
|
|
647
598
|
return auditedOperation(AuditAction.CREATE, 'project', undefined, async () => {
|
|
648
|
-
const project = await postOne(
|
|
599
|
+
const project = await postOne(ENDPOINTS.projects, input);
|
|
649
600
|
cache.invalidatePrefix('projects');
|
|
650
601
|
return project;
|
|
651
602
|
});
|
|
@@ -654,11 +605,9 @@ export async function createProject(input) {
|
|
|
654
605
|
* Update a project
|
|
655
606
|
*/
|
|
656
607
|
export async function updateProject(id, input) {
|
|
657
|
-
|
|
658
|
-
throw new Error('Invalid project ID. Please provide a positive number.');
|
|
659
|
-
}
|
|
608
|
+
validateId(id, 'project');
|
|
660
609
|
return auditedOperation(AuditAction.UPDATE, 'project', id, async () => {
|
|
661
|
-
const project = await patchOne(
|
|
610
|
+
const project = await patchOne(endpointWithId(ENDPOINTS.projects, id), input);
|
|
662
611
|
cache.invalidate(`project:${id}`);
|
|
663
612
|
cache.invalidatePrefix('projects');
|
|
664
613
|
return project;
|
|
@@ -668,11 +617,9 @@ export async function updateProject(id, input) {
|
|
|
668
617
|
* Delete a project
|
|
669
618
|
*/
|
|
670
619
|
export async function deleteProject(id) {
|
|
671
|
-
|
|
672
|
-
throw new Error('Invalid project ID. Please provide a positive number.');
|
|
673
|
-
}
|
|
620
|
+
validateId(id, 'project');
|
|
674
621
|
return auditedOperation(AuditAction.DELETE, 'project', id, async () => {
|
|
675
|
-
await deleteOne(
|
|
622
|
+
await deleteOne(endpointWithId(ENDPOINTS.projects, id));
|
|
676
623
|
cache.invalidate(`project:${id}`);
|
|
677
624
|
cache.invalidatePrefix('projects');
|
|
678
625
|
});
|
|
@@ -682,29 +629,25 @@ export async function deleteProject(id) {
|
|
|
682
629
|
*/
|
|
683
630
|
export async function createProjectTask(input) {
|
|
684
631
|
return auditedOperation(AuditAction.CREATE, 'project_task', undefined, async () => {
|
|
685
|
-
return postOne(
|
|
632
|
+
return postOne(ENDPOINTS.projectTasks, input);
|
|
686
633
|
});
|
|
687
634
|
}
|
|
688
635
|
/**
|
|
689
636
|
* Update a project task
|
|
690
637
|
*/
|
|
691
638
|
export async function updateProjectTask(id, input) {
|
|
692
|
-
|
|
693
|
-
throw new Error('Invalid task ID. Please provide a positive number.');
|
|
694
|
-
}
|
|
639
|
+
validateId(id, 'task');
|
|
695
640
|
return auditedOperation(AuditAction.UPDATE, 'project_task', id, async () => {
|
|
696
|
-
return patchOne(
|
|
641
|
+
return patchOne(endpointWithId(ENDPOINTS.projectTasks, id), input);
|
|
697
642
|
});
|
|
698
643
|
}
|
|
699
644
|
/**
|
|
700
645
|
* Delete a project task
|
|
701
646
|
*/
|
|
702
647
|
export async function deleteProjectTask(id) {
|
|
703
|
-
|
|
704
|
-
throw new Error('Invalid task ID. Please provide a positive number.');
|
|
705
|
-
}
|
|
648
|
+
validateId(id, 'task');
|
|
706
649
|
return auditedOperation(AuditAction.DELETE, 'project_task', id, async () => {
|
|
707
|
-
await deleteOne(
|
|
650
|
+
await deleteOne(endpointWithId(ENDPOINTS.projectTasks, id));
|
|
708
651
|
});
|
|
709
652
|
}
|
|
710
653
|
/**
|
|
@@ -712,18 +655,16 @@ export async function deleteProjectTask(id) {
|
|
|
712
655
|
*/
|
|
713
656
|
export async function assignProjectWorker(input) {
|
|
714
657
|
return auditedOperation(AuditAction.ASSIGN, 'project_worker', undefined, async () => {
|
|
715
|
-
return postOne(
|
|
658
|
+
return postOne(ENDPOINTS.projectWorkers, input);
|
|
716
659
|
});
|
|
717
660
|
}
|
|
718
661
|
/**
|
|
719
662
|
* Remove a worker from a project
|
|
720
663
|
*/
|
|
721
664
|
export async function removeProjectWorker(id) {
|
|
722
|
-
|
|
723
|
-
throw new Error('Invalid project worker ID. Please provide a positive number.');
|
|
724
|
-
}
|
|
665
|
+
validateId(id, 'project worker');
|
|
725
666
|
return auditedOperation(AuditAction.UNASSIGN, 'project_worker', id, async () => {
|
|
726
|
-
await deleteOne(
|
|
667
|
+
await deleteOne(endpointWithId(ENDPOINTS.projectWorkers, id));
|
|
727
668
|
});
|
|
728
669
|
}
|
|
729
670
|
/**
|
|
@@ -731,29 +672,25 @@ export async function removeProjectWorker(id) {
|
|
|
731
672
|
*/
|
|
732
673
|
export async function createTimeRecord(input) {
|
|
733
674
|
return auditedOperation(AuditAction.CREATE, 'time_record', undefined, async () => {
|
|
734
|
-
return postOne(
|
|
675
|
+
return postOne(ENDPOINTS.timeRecords, input);
|
|
735
676
|
});
|
|
736
677
|
}
|
|
737
678
|
/**
|
|
738
679
|
* Update a time record
|
|
739
680
|
*/
|
|
740
681
|
export async function updateTimeRecord(id, input) {
|
|
741
|
-
|
|
742
|
-
throw new Error('Invalid time record ID. Please provide a positive number.');
|
|
743
|
-
}
|
|
682
|
+
validateId(id, 'time record');
|
|
744
683
|
return auditedOperation(AuditAction.UPDATE, 'time_record', id, async () => {
|
|
745
|
-
return patchOne(
|
|
684
|
+
return patchOne(endpointWithId(ENDPOINTS.timeRecords, id), input);
|
|
746
685
|
});
|
|
747
686
|
}
|
|
748
687
|
/**
|
|
749
688
|
* Delete a time record
|
|
750
689
|
*/
|
|
751
690
|
export async function deleteTimeRecord(id) {
|
|
752
|
-
|
|
753
|
-
throw new Error('Invalid time record ID. Please provide a positive number.');
|
|
754
|
-
}
|
|
691
|
+
validateId(id, 'time record');
|
|
755
692
|
return auditedOperation(AuditAction.DELETE, 'time_record', id, async () => {
|
|
756
|
-
await deleteOne(
|
|
693
|
+
await deleteOne(endpointWithId(ENDPOINTS.timeRecords, id));
|
|
757
694
|
});
|
|
758
695
|
}
|
|
759
696
|
// ============================================================================
|
|
@@ -764,17 +701,15 @@ export async function deleteTimeRecord(id) {
|
|
|
764
701
|
*/
|
|
765
702
|
export async function listTrainings(options) {
|
|
766
703
|
const params = buildPaginationParams(options);
|
|
767
|
-
const trainings = await cached(CacheManager.key('trainings', options), () => fetchList(
|
|
704
|
+
const trainings = await cached(CacheManager.key('trainings', options), () => fetchList(ENDPOINTS.trainings), CACHE_TTL.default);
|
|
768
705
|
return sliceForPagination(trainings, params);
|
|
769
706
|
}
|
|
770
707
|
/**
|
|
771
708
|
* Get a specific training by ID
|
|
772
709
|
*/
|
|
773
710
|
export async function getTraining(id) {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
return cached(`training:${id}`, () => fetchOne(`/trainings/trainings/${id}`), CACHE_TTL.default);
|
|
711
|
+
validateId(id, 'training');
|
|
712
|
+
return cached(`training:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.trainings, id)), CACHE_TTL.default);
|
|
778
713
|
}
|
|
779
714
|
/**
|
|
780
715
|
* List training sessions
|
|
@@ -784,17 +719,17 @@ export async function listTrainingSessions(trainingId, options) {
|
|
|
784
719
|
const queryParams = {};
|
|
785
720
|
if (trainingId)
|
|
786
721
|
queryParams.training_id = trainingId;
|
|
787
|
-
const sessions = await fetchList(
|
|
722
|
+
const sessions = await fetchList(ENDPOINTS.trainingSessions, {
|
|
723
|
+
params: queryParams,
|
|
724
|
+
});
|
|
788
725
|
return sliceForPagination(sessions, params);
|
|
789
726
|
}
|
|
790
727
|
/**
|
|
791
728
|
* Get a specific training session by ID
|
|
792
729
|
*/
|
|
793
730
|
export async function getTrainingSession(id) {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
return fetchOne(`/trainings/sessions/${id}`);
|
|
731
|
+
validateId(id, 'session');
|
|
732
|
+
return fetchOne(endpointWithId(ENDPOINTS.trainingSessions, id));
|
|
798
733
|
}
|
|
799
734
|
/**
|
|
800
735
|
* List training enrollments
|
|
@@ -804,7 +739,7 @@ export async function listTrainingEnrollments(trainingId, options) {
|
|
|
804
739
|
const queryParams = {};
|
|
805
740
|
if (trainingId)
|
|
806
741
|
queryParams.training_id = trainingId;
|
|
807
|
-
const enrollments = await fetchList(
|
|
742
|
+
const enrollments = await fetchList(ENDPOINTS.trainingMemberships, {
|
|
808
743
|
params: queryParams,
|
|
809
744
|
});
|
|
810
745
|
return sliceForPagination(enrollments, params);
|
|
@@ -813,10 +748,8 @@ export async function listTrainingEnrollments(trainingId, options) {
|
|
|
813
748
|
* Get a specific training enrollment by ID
|
|
814
749
|
*/
|
|
815
750
|
export async function getTrainingEnrollment(id) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
return fetchOne(`/trainings/memberships/${id}`);
|
|
751
|
+
validateId(id, 'enrollment');
|
|
752
|
+
return fetchOne(endpointWithId(ENDPOINTS.trainingMemberships, id));
|
|
820
753
|
}
|
|
821
754
|
// ============================================================================
|
|
822
755
|
// Training & Development - WRITE endpoints
|
|
@@ -826,7 +759,7 @@ export async function getTrainingEnrollment(id) {
|
|
|
826
759
|
*/
|
|
827
760
|
export async function createTraining(input) {
|
|
828
761
|
return auditedOperation(AuditAction.CREATE, 'training', undefined, async () => {
|
|
829
|
-
const training = await postOne(
|
|
762
|
+
const training = await postOne(ENDPOINTS.trainings, input);
|
|
830
763
|
cache.invalidatePrefix('trainings');
|
|
831
764
|
return training;
|
|
832
765
|
});
|
|
@@ -835,11 +768,9 @@ export async function createTraining(input) {
|
|
|
835
768
|
* Update a training program
|
|
836
769
|
*/
|
|
837
770
|
export async function updateTraining(id, input) {
|
|
838
|
-
|
|
839
|
-
throw new Error('Invalid training ID. Please provide a positive number.');
|
|
840
|
-
}
|
|
771
|
+
validateId(id, 'training');
|
|
841
772
|
return auditedOperation(AuditAction.UPDATE, 'training', id, async () => {
|
|
842
|
-
const training = await patchOne(
|
|
773
|
+
const training = await patchOne(endpointWithId(ENDPOINTS.trainings, id), input);
|
|
843
774
|
cache.invalidate(`training:${id}`);
|
|
844
775
|
cache.invalidatePrefix('trainings');
|
|
845
776
|
return training;
|
|
@@ -849,11 +780,9 @@ export async function updateTraining(id, input) {
|
|
|
849
780
|
* Delete a training program
|
|
850
781
|
*/
|
|
851
782
|
export async function deleteTraining(id) {
|
|
852
|
-
|
|
853
|
-
throw new Error('Invalid training ID. Please provide a positive number.');
|
|
854
|
-
}
|
|
783
|
+
validateId(id, 'training');
|
|
855
784
|
return auditedOperation(AuditAction.DELETE, 'training', id, async () => {
|
|
856
|
-
await deleteOne(
|
|
785
|
+
await deleteOne(endpointWithId(ENDPOINTS.trainings, id));
|
|
857
786
|
cache.invalidate(`training:${id}`);
|
|
858
787
|
cache.invalidatePrefix('trainings');
|
|
859
788
|
});
|
|
@@ -863,29 +792,25 @@ export async function deleteTraining(id) {
|
|
|
863
792
|
*/
|
|
864
793
|
export async function createTrainingSession(input) {
|
|
865
794
|
return auditedOperation(AuditAction.CREATE, 'training_session', undefined, async () => {
|
|
866
|
-
return postOne(
|
|
795
|
+
return postOne(ENDPOINTS.trainingSessions, input);
|
|
867
796
|
});
|
|
868
797
|
}
|
|
869
798
|
/**
|
|
870
799
|
* Update a training session
|
|
871
800
|
*/
|
|
872
801
|
export async function updateTrainingSession(id, input) {
|
|
873
|
-
|
|
874
|
-
throw new Error('Invalid session ID. Please provide a positive number.');
|
|
875
|
-
}
|
|
802
|
+
validateId(id, 'session');
|
|
876
803
|
return auditedOperation(AuditAction.UPDATE, 'training_session', id, async () => {
|
|
877
|
-
return patchOne(
|
|
804
|
+
return patchOne(endpointWithId(ENDPOINTS.trainingSessions, id), input);
|
|
878
805
|
});
|
|
879
806
|
}
|
|
880
807
|
/**
|
|
881
808
|
* Delete a training session
|
|
882
809
|
*/
|
|
883
810
|
export async function deleteTrainingSession(id) {
|
|
884
|
-
|
|
885
|
-
throw new Error('Invalid session ID. Please provide a positive number.');
|
|
886
|
-
}
|
|
811
|
+
validateId(id, 'session');
|
|
887
812
|
return auditedOperation(AuditAction.DELETE, 'training_session', id, async () => {
|
|
888
|
-
await deleteOne(
|
|
813
|
+
await deleteOne(endpointWithId(ENDPOINTS.trainingSessions, id));
|
|
889
814
|
});
|
|
890
815
|
}
|
|
891
816
|
/**
|
|
@@ -893,18 +818,16 @@ export async function deleteTrainingSession(id) {
|
|
|
893
818
|
*/
|
|
894
819
|
export async function enrollInTraining(input) {
|
|
895
820
|
return auditedOperation(AuditAction.ASSIGN, 'training_enrollment', undefined, async () => {
|
|
896
|
-
return postOne(
|
|
821
|
+
return postOne(ENDPOINTS.trainingMemberships, input);
|
|
897
822
|
});
|
|
898
823
|
}
|
|
899
824
|
/**
|
|
900
825
|
* Remove enrollment from a training
|
|
901
826
|
*/
|
|
902
827
|
export async function unenrollFromTraining(id) {
|
|
903
|
-
|
|
904
|
-
throw new Error('Invalid enrollment ID. Please provide a positive number.');
|
|
905
|
-
}
|
|
828
|
+
validateId(id, 'enrollment');
|
|
906
829
|
return auditedOperation(AuditAction.UNASSIGN, 'training_enrollment', id, async () => {
|
|
907
|
-
await deleteOne(
|
|
830
|
+
await deleteOne(endpointWithId(ENDPOINTS.trainingMemberships, id));
|
|
908
831
|
});
|
|
909
832
|
}
|
|
910
833
|
// ============================================================================
|
|
@@ -915,24 +838,22 @@ export async function unenrollFromTraining(id) {
|
|
|
915
838
|
*/
|
|
916
839
|
export async function listWorkAreas(options) {
|
|
917
840
|
const params = buildPaginationParams(options);
|
|
918
|
-
const workAreas = await cached(CacheManager.key('work_areas', options), () => fetchList(
|
|
841
|
+
const workAreas = await cached(CacheManager.key('work_areas', options), () => fetchList(ENDPOINTS.workAreas), CACHE_TTL.locations);
|
|
919
842
|
return sliceForPagination(workAreas, params);
|
|
920
843
|
}
|
|
921
844
|
/**
|
|
922
845
|
* Get a specific work area by ID
|
|
923
846
|
*/
|
|
924
847
|
export async function getWorkArea(id) {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
}
|
|
928
|
-
return cached(`work_area:${id}`, () => fetchOne(`/locations/work_areas/${id}`), CACHE_TTL.locations);
|
|
848
|
+
validateId(id, 'work area');
|
|
849
|
+
return cached(`work_area:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.workAreas, id)), CACHE_TTL.locations);
|
|
929
850
|
}
|
|
930
851
|
/**
|
|
931
852
|
* Create a work area
|
|
932
853
|
*/
|
|
933
854
|
export async function createWorkArea(input) {
|
|
934
855
|
return auditedOperation(AuditAction.CREATE, 'work_area', undefined, async () => {
|
|
935
|
-
const workArea = await postOne(
|
|
856
|
+
const workArea = await postOne(ENDPOINTS.workAreas, input);
|
|
936
857
|
cache.invalidatePrefix('work_areas');
|
|
937
858
|
return workArea;
|
|
938
859
|
});
|
|
@@ -941,11 +862,9 @@ export async function createWorkArea(input) {
|
|
|
941
862
|
* Update a work area
|
|
942
863
|
*/
|
|
943
864
|
export async function updateWorkArea(id, input) {
|
|
944
|
-
|
|
945
|
-
throw new Error('Invalid work area ID. Please provide a positive number.');
|
|
946
|
-
}
|
|
865
|
+
validateId(id, 'work area');
|
|
947
866
|
return auditedOperation(AuditAction.UPDATE, 'work_area', id, async () => {
|
|
948
|
-
const workArea = await patchOne(
|
|
867
|
+
const workArea = await patchOne(endpointWithId(ENDPOINTS.workAreas, id), input);
|
|
949
868
|
cache.invalidate(`work_area:${id}`);
|
|
950
869
|
cache.invalidatePrefix('work_areas');
|
|
951
870
|
return workArea;
|
|
@@ -955,11 +874,9 @@ export async function updateWorkArea(id, input) {
|
|
|
955
874
|
* Archive a work area
|
|
956
875
|
*/
|
|
957
876
|
export async function archiveWorkArea(id) {
|
|
958
|
-
|
|
959
|
-
throw new Error('Invalid work area ID. Please provide a positive number.');
|
|
960
|
-
}
|
|
877
|
+
validateId(id, 'work area');
|
|
961
878
|
return auditedOperation(AuditAction.ARCHIVE, 'work_area', id, async () => {
|
|
962
|
-
const workArea = await postAction(
|
|
879
|
+
const workArea = await postAction(endpointWithAction(ENDPOINTS.workAreas, id, 'archive'));
|
|
963
880
|
cache.invalidate(`work_area:${id}`);
|
|
964
881
|
cache.invalidatePrefix('work_areas');
|
|
965
882
|
return workArea;
|
|
@@ -969,11 +886,9 @@ export async function archiveWorkArea(id) {
|
|
|
969
886
|
* Unarchive a work area
|
|
970
887
|
*/
|
|
971
888
|
export async function unarchiveWorkArea(id) {
|
|
972
|
-
|
|
973
|
-
throw new Error('Invalid work area ID. Please provide a positive number.');
|
|
974
|
-
}
|
|
889
|
+
validateId(id, 'work area');
|
|
975
890
|
return auditedOperation(AuditAction.UNARCHIVE, 'work_area', id, async () => {
|
|
976
|
-
const workArea = await postAction(
|
|
891
|
+
const workArea = await postAction(endpointWithAction(ENDPOINTS.workAreas, id, 'unarchive'));
|
|
977
892
|
cache.invalidate(`work_area:${id}`);
|
|
978
893
|
cache.invalidatePrefix('work_areas');
|
|
979
894
|
return workArea;
|
|
@@ -987,34 +902,30 @@ export async function unarchiveWorkArea(id) {
|
|
|
987
902
|
*/
|
|
988
903
|
export async function listJobPostings(options) {
|
|
989
904
|
const params = buildPaginationParams(options);
|
|
990
|
-
const postings = await cached(CacheManager.key('job_postings', options), () => fetchList(
|
|
905
|
+
const postings = await cached(CacheManager.key('job_postings', options), () => fetchList(ENDPOINTS.jobPostings), CACHE_TTL.default);
|
|
991
906
|
return sliceForPagination(postings, params);
|
|
992
907
|
}
|
|
993
908
|
/**
|
|
994
909
|
* Get a specific job posting by ID
|
|
995
910
|
*/
|
|
996
911
|
export async function getJobPosting(id) {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
}
|
|
1000
|
-
return cached(`job_posting:${id}`, () => fetchOne(`/ats/job_postings/${id}`), CACHE_TTL.default);
|
|
912
|
+
validateId(id, 'job posting');
|
|
913
|
+
return cached(`job_posting:${id}`, () => fetchOne(endpointWithId(ENDPOINTS.jobPostings, id)), CACHE_TTL.default);
|
|
1001
914
|
}
|
|
1002
915
|
/**
|
|
1003
916
|
* List all candidates
|
|
1004
917
|
*/
|
|
1005
918
|
export async function listCandidates(options) {
|
|
1006
919
|
const params = buildPaginationParams(options);
|
|
1007
|
-
const candidates = await fetchList(
|
|
920
|
+
const candidates = await fetchList(ENDPOINTS.candidates);
|
|
1008
921
|
return sliceForPagination(candidates, params);
|
|
1009
922
|
}
|
|
1010
923
|
/**
|
|
1011
924
|
* Get a specific candidate by ID
|
|
1012
925
|
*/
|
|
1013
926
|
export async function getCandidate(id) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
}
|
|
1017
|
-
return fetchOne(`/ats/candidates/${id}`);
|
|
927
|
+
validateId(id, 'candidate');
|
|
928
|
+
return fetchOne(endpointWithId(ENDPOINTS.candidates, id));
|
|
1018
929
|
}
|
|
1019
930
|
/**
|
|
1020
931
|
* List all applications
|
|
@@ -1024,32 +935,30 @@ export async function listApplications(jobPostingId, options) {
|
|
|
1024
935
|
const queryParams = {};
|
|
1025
936
|
if (jobPostingId)
|
|
1026
937
|
queryParams.job_posting_id = jobPostingId;
|
|
1027
|
-
const applications = await fetchList(
|
|
938
|
+
const applications = await fetchList(ENDPOINTS.applications, {
|
|
939
|
+
params: queryParams,
|
|
940
|
+
});
|
|
1028
941
|
return sliceForPagination(applications, params);
|
|
1029
942
|
}
|
|
1030
943
|
/**
|
|
1031
944
|
* Get a specific application by ID
|
|
1032
945
|
*/
|
|
1033
946
|
export async function getApplication(id) {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
}
|
|
1037
|
-
return fetchOne(`/ats/applications/${id}`);
|
|
947
|
+
validateId(id, 'application');
|
|
948
|
+
return fetchOne(endpointWithId(ENDPOINTS.applications, id));
|
|
1038
949
|
}
|
|
1039
950
|
/**
|
|
1040
951
|
* List all hiring stages
|
|
1041
952
|
*/
|
|
1042
953
|
export async function listHiringStages() {
|
|
1043
|
-
return cached('hiring_stages:all', () => fetchList(
|
|
954
|
+
return cached('hiring_stages:all', () => fetchList(ENDPOINTS.hiringStages), CACHE_TTL.default);
|
|
1044
955
|
}
|
|
1045
956
|
/**
|
|
1046
957
|
* Get a specific hiring stage by ID
|
|
1047
958
|
*/
|
|
1048
959
|
export async function getHiringStage(id) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
return fetchOne(`/ats/hiring_stages/${id}`);
|
|
960
|
+
validateId(id, 'hiring stage');
|
|
961
|
+
return fetchOne(endpointWithId(ENDPOINTS.hiringStages, id));
|
|
1053
962
|
}
|
|
1054
963
|
// ============================================================================
|
|
1055
964
|
// ATS (Recruiting) - WRITE endpoints
|
|
@@ -1059,7 +968,7 @@ export async function getHiringStage(id) {
|
|
|
1059
968
|
*/
|
|
1060
969
|
export async function createJobPosting(input) {
|
|
1061
970
|
return auditedOperation(AuditAction.CREATE, 'job_posting', undefined, async () => {
|
|
1062
|
-
const posting = await postOne(
|
|
971
|
+
const posting = await postOne(ENDPOINTS.jobPostings, input);
|
|
1063
972
|
cache.invalidatePrefix('job_postings');
|
|
1064
973
|
return posting;
|
|
1065
974
|
});
|
|
@@ -1068,11 +977,9 @@ export async function createJobPosting(input) {
|
|
|
1068
977
|
* Update a job posting
|
|
1069
978
|
*/
|
|
1070
979
|
export async function updateJobPosting(id, input) {
|
|
1071
|
-
|
|
1072
|
-
throw new Error('Invalid job posting ID. Please provide a positive number.');
|
|
1073
|
-
}
|
|
980
|
+
validateId(id, 'job posting');
|
|
1074
981
|
return auditedOperation(AuditAction.UPDATE, 'job_posting', id, async () => {
|
|
1075
|
-
const posting = await patchOne(
|
|
982
|
+
const posting = await patchOne(endpointWithId(ENDPOINTS.jobPostings, id), input);
|
|
1076
983
|
cache.invalidate(`job_posting:${id}`);
|
|
1077
984
|
cache.invalidatePrefix('job_postings');
|
|
1078
985
|
return posting;
|
|
@@ -1082,11 +989,9 @@ export async function updateJobPosting(id, input) {
|
|
|
1082
989
|
* Delete a job posting
|
|
1083
990
|
*/
|
|
1084
991
|
export async function deleteJobPosting(id) {
|
|
1085
|
-
|
|
1086
|
-
throw new Error('Invalid job posting ID. Please provide a positive number.');
|
|
1087
|
-
}
|
|
992
|
+
validateId(id, 'job posting');
|
|
1088
993
|
return auditedOperation(AuditAction.DELETE, 'job_posting', id, async () => {
|
|
1089
|
-
await deleteOne(
|
|
994
|
+
await deleteOne(endpointWithId(ENDPOINTS.jobPostings, id));
|
|
1090
995
|
cache.invalidate(`job_posting:${id}`);
|
|
1091
996
|
cache.invalidatePrefix('job_postings');
|
|
1092
997
|
});
|
|
@@ -1096,29 +1001,25 @@ export async function deleteJobPosting(id) {
|
|
|
1096
1001
|
*/
|
|
1097
1002
|
export async function createCandidate(input) {
|
|
1098
1003
|
return auditedOperation(AuditAction.CREATE, 'candidate', undefined, async () => {
|
|
1099
|
-
return postOne(
|
|
1004
|
+
return postOne(ENDPOINTS.candidates, input);
|
|
1100
1005
|
});
|
|
1101
1006
|
}
|
|
1102
1007
|
/**
|
|
1103
1008
|
* Update a candidate
|
|
1104
1009
|
*/
|
|
1105
1010
|
export async function updateCandidate(id, input) {
|
|
1106
|
-
|
|
1107
|
-
throw new Error('Invalid candidate ID. Please provide a positive number.');
|
|
1108
|
-
}
|
|
1011
|
+
validateId(id, 'candidate');
|
|
1109
1012
|
return auditedOperation(AuditAction.UPDATE, 'candidate', id, async () => {
|
|
1110
|
-
return patchOne(
|
|
1013
|
+
return patchOne(endpointWithId(ENDPOINTS.candidates, id), input);
|
|
1111
1014
|
});
|
|
1112
1015
|
}
|
|
1113
1016
|
/**
|
|
1114
1017
|
* Delete a candidate
|
|
1115
1018
|
*/
|
|
1116
1019
|
export async function deleteCandidate(id) {
|
|
1117
|
-
|
|
1118
|
-
throw new Error('Invalid candidate ID. Please provide a positive number.');
|
|
1119
|
-
}
|
|
1020
|
+
validateId(id, 'candidate');
|
|
1120
1021
|
return auditedOperation(AuditAction.DELETE, 'candidate', id, async () => {
|
|
1121
|
-
await deleteOne(
|
|
1022
|
+
await deleteOne(endpointWithId(ENDPOINTS.candidates, id));
|
|
1122
1023
|
});
|
|
1123
1024
|
}
|
|
1124
1025
|
/**
|
|
@@ -1126,40 +1027,34 @@ export async function deleteCandidate(id) {
|
|
|
1126
1027
|
*/
|
|
1127
1028
|
export async function createApplication(input) {
|
|
1128
1029
|
return auditedOperation(AuditAction.CREATE, 'application', undefined, async () => {
|
|
1129
|
-
return postOne(
|
|
1030
|
+
return postOne(ENDPOINTS.applications, input);
|
|
1130
1031
|
});
|
|
1131
1032
|
}
|
|
1132
1033
|
/**
|
|
1133
1034
|
* Update an application
|
|
1134
1035
|
*/
|
|
1135
1036
|
export async function updateApplication(id, input) {
|
|
1136
|
-
|
|
1137
|
-
throw new Error('Invalid application ID. Please provide a positive number.');
|
|
1138
|
-
}
|
|
1037
|
+
validateId(id, 'application');
|
|
1139
1038
|
return auditedOperation(AuditAction.UPDATE, 'application', id, async () => {
|
|
1140
|
-
return patchOne(
|
|
1039
|
+
return patchOne(endpointWithId(ENDPOINTS.applications, id), input);
|
|
1141
1040
|
});
|
|
1142
1041
|
}
|
|
1143
1042
|
/**
|
|
1144
1043
|
* Delete an application
|
|
1145
1044
|
*/
|
|
1146
1045
|
export async function deleteApplication(id) {
|
|
1147
|
-
|
|
1148
|
-
throw new Error('Invalid application ID. Please provide a positive number.');
|
|
1149
|
-
}
|
|
1046
|
+
validateId(id, 'application');
|
|
1150
1047
|
return auditedOperation(AuditAction.DELETE, 'application', id, async () => {
|
|
1151
|
-
await deleteOne(
|
|
1048
|
+
await deleteOne(endpointWithId(ENDPOINTS.applications, id));
|
|
1152
1049
|
});
|
|
1153
1050
|
}
|
|
1154
1051
|
/**
|
|
1155
1052
|
* Advance an application to the next stage
|
|
1156
1053
|
*/
|
|
1157
1054
|
export async function advanceApplication(id) {
|
|
1158
|
-
|
|
1159
|
-
throw new Error('Invalid application ID. Please provide a positive number.');
|
|
1160
|
-
}
|
|
1055
|
+
validateId(id, 'application');
|
|
1161
1056
|
return auditedOperation(AuditAction.UPDATE, 'application', id, async () => {
|
|
1162
|
-
return postAction(
|
|
1057
|
+
return postAction(endpointWithAction(ENDPOINTS.applications, id, 'apply'));
|
|
1163
1058
|
});
|
|
1164
1059
|
}
|
|
1165
1060
|
// ============================================================================
|
|
@@ -1173,7 +1068,7 @@ export async function listPayrollSupplements(employeeId, options) {
|
|
|
1173
1068
|
const queryParams = {};
|
|
1174
1069
|
if (employeeId)
|
|
1175
1070
|
queryParams.employee_id = employeeId;
|
|
1176
|
-
const supplements = await fetchList(
|
|
1071
|
+
const supplements = await fetchList(ENDPOINTS.payrollSupplements, {
|
|
1177
1072
|
params: queryParams,
|
|
1178
1073
|
});
|
|
1179
1074
|
return sliceForPagination(supplements, params);
|
|
@@ -1182,10 +1077,8 @@ export async function listPayrollSupplements(employeeId, options) {
|
|
|
1182
1077
|
* Get a specific payroll supplement by ID
|
|
1183
1078
|
*/
|
|
1184
1079
|
export async function getPayrollSupplement(id) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
}
|
|
1188
|
-
return fetchOne(`/payroll/supplements/${id}`);
|
|
1080
|
+
validateId(id, 'supplement');
|
|
1081
|
+
return fetchOne(endpointWithId(ENDPOINTS.payrollSupplements, id));
|
|
1189
1082
|
}
|
|
1190
1083
|
/**
|
|
1191
1084
|
* List tax identifiers
|
|
@@ -1195,7 +1088,7 @@ export async function listTaxIdentifiers(employeeId, options) {
|
|
|
1195
1088
|
const queryParams = {};
|
|
1196
1089
|
if (employeeId)
|
|
1197
1090
|
queryParams.employee_id = employeeId;
|
|
1198
|
-
const identifiers = await fetchList(
|
|
1091
|
+
const identifiers = await fetchList(ENDPOINTS.taxIdentifiers, {
|
|
1199
1092
|
params: queryParams,
|
|
1200
1093
|
});
|
|
1201
1094
|
return sliceForPagination(identifiers, params);
|
|
@@ -1204,10 +1097,8 @@ export async function listTaxIdentifiers(employeeId, options) {
|
|
|
1204
1097
|
* Get a specific tax identifier by ID
|
|
1205
1098
|
*/
|
|
1206
1099
|
export async function getTaxIdentifier(id) {
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
}
|
|
1210
|
-
return fetchOne(`/payroll_employees/identifiers/${id}`);
|
|
1100
|
+
validateId(id, 'tax identifier');
|
|
1101
|
+
return fetchOne(endpointWithId(ENDPOINTS.taxIdentifiers, id));
|
|
1211
1102
|
}
|
|
1212
1103
|
/**
|
|
1213
1104
|
* List family situations
|
|
@@ -1217,7 +1108,7 @@ export async function listFamilySituations(employeeId, options) {
|
|
|
1217
1108
|
const queryParams = {};
|
|
1218
1109
|
if (employeeId)
|
|
1219
1110
|
queryParams.employee_id = employeeId;
|
|
1220
|
-
const situations = await fetchList(
|
|
1111
|
+
const situations = await fetchList(ENDPOINTS.familySituations, {
|
|
1221
1112
|
params: queryParams,
|
|
1222
1113
|
});
|
|
1223
1114
|
return sliceForPagination(situations, params);
|
|
@@ -1226,9 +1117,7 @@ export async function listFamilySituations(employeeId, options) {
|
|
|
1226
1117
|
* Get a specific family situation by ID
|
|
1227
1118
|
*/
|
|
1228
1119
|
export async function getFamilySituation(id) {
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
}
|
|
1232
|
-
return fetchOne(`/payroll/family_situations/${id}`);
|
|
1120
|
+
validateId(id, 'family situation');
|
|
1121
|
+
return fetchOne(endpointWithId(ENDPOINTS.familySituations, id));
|
|
1233
1122
|
}
|
|
1234
1123
|
//# sourceMappingURL=api.js.map
|