@docbrasil/api-systemmanager 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/admin/user.js +84 -0
- package/dist/bundle.cjs +84 -0
- package/dist/bundle.mjs +1 -1
- package/doc/api.md +67 -0
- package/docs/AdminUser.html +278 -13
- package/docs/admin_user.js.html +84 -0
- package/package.json +1 -1
package/api/admin/user.js
CHANGED
|
@@ -298,6 +298,90 @@ class AdminUser {
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
+
/**
|
|
302
|
+
* @author Myndware <augusto.pissarra@myndware.com>
|
|
303
|
+
* @description Batch-create users from an uploaded Excel (.xlsx) or CSV file.
|
|
304
|
+
*
|
|
305
|
+
* Uploads the file as multipart/form-data. The server parses it, validates
|
|
306
|
+
* headers, de-duplicates emails, admits rows FIFO against the organization's
|
|
307
|
+
* user cap, and delegates the actual creation to the existing registration
|
|
308
|
+
* chain. Response is a per-row result array (created / existing / skipped).
|
|
309
|
+
*
|
|
310
|
+
* Status codes:
|
|
311
|
+
* - 200 when at least one row was created or matched an existing user.
|
|
312
|
+
* - 422 (same JSON body shape) when EVERY row was skipped — callers
|
|
313
|
+
* should promote the 422 response body to a completed result, not an
|
|
314
|
+
* error. Axios throws on 422 by default, so catch and inspect
|
|
315
|
+
* `ex.response.data.results`.
|
|
316
|
+
* - 400 for structural failures (invalid_file, missing_columns, empty_file,
|
|
317
|
+
* too_many_rows) — `response.data.code` carries the machine-readable code.
|
|
318
|
+
* - 403 when the caller does not belong to the target organization or lacks
|
|
319
|
+
* user-admin role (code: 'forbidden').
|
|
320
|
+
* - 413 when the uploaded file exceeds 2 MB.
|
|
321
|
+
*
|
|
322
|
+
* @param {FormData} formData A browser FormData instance with a single field
|
|
323
|
+
* named `file` whose value is the .xlsx or .csv File/Blob. Must be
|
|
324
|
+
* FormData so the browser/axios can set the multipart boundary.
|
|
325
|
+
* @param {string} session JWT session token
|
|
326
|
+
* @return {Promise<object>} Batch result:
|
|
327
|
+
* {
|
|
328
|
+
* total: number,
|
|
329
|
+
* created: number,
|
|
330
|
+
* existing: number,
|
|
331
|
+
* skipped: number,
|
|
332
|
+
* results: Array<{
|
|
333
|
+
* row: number, // spreadsheet row (1-based, header = 1)
|
|
334
|
+
* email: string,
|
|
335
|
+
* status: 'created' | 'existing' | 'skipped',
|
|
336
|
+
* userId: string | null,
|
|
337
|
+
* message: string | null // snake_case code, optionally `code:detail`
|
|
338
|
+
* }>
|
|
339
|
+
* }
|
|
340
|
+
* @public
|
|
341
|
+
* @async
|
|
342
|
+
* @example
|
|
343
|
+
*
|
|
344
|
+
* const API = require('@docbrasil/api-systemmanager');
|
|
345
|
+
* const api = new API();
|
|
346
|
+
* const fd = new FormData();
|
|
347
|
+
* fd.append('file', fileInput.files[0]); // .xlsx or .csv
|
|
348
|
+
* const session = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
|
|
349
|
+
* // Ensure the client is scoped to the caller's org:
|
|
350
|
+
* api.admin.user.setOrgId(myOrgId);
|
|
351
|
+
* try {
|
|
352
|
+
* const result = await api.admin.user.batchCreate(fd, session);
|
|
353
|
+
* console.log(`${result.created} created, ${result.skipped} skipped`);
|
|
354
|
+
* } catch (ex) {
|
|
355
|
+
* if (ex?.response?.status === 422 && ex.response.data?.results) {
|
|
356
|
+
* // All-skipped batch — still a valid result to render.
|
|
357
|
+
* console.warn('All rows skipped:', ex.response.data.results);
|
|
358
|
+
* } else {
|
|
359
|
+
* throw ex;
|
|
360
|
+
* }
|
|
361
|
+
* }
|
|
362
|
+
*/
|
|
363
|
+
async batchCreate(formData, session) {
|
|
364
|
+
const self = this;
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
Joi.assert(formData, Joi.any().required(), 'Multipart FormData with a `file` field');
|
|
368
|
+
Joi.assert(session, Joi.string().required(), 'Session token');
|
|
369
|
+
|
|
370
|
+
// Do NOT force Content-Type — let the browser/axios set it with the
|
|
371
|
+
// correct multipart boundary. Raise the axios body-size caps to 5 MB
|
|
372
|
+
// (server enforces its own 2 MB cap via Hapi `maxBytes`).
|
|
373
|
+
const cfg = {
|
|
374
|
+
...self._setHeader(session),
|
|
375
|
+
maxContentLength: 5 * 1024 * 1024,
|
|
376
|
+
maxBodyLength: 5 * 1024 * 1024
|
|
377
|
+
};
|
|
378
|
+
const apiCall = self.client.put(`${self._basePath()}/batch`, formData, cfg);
|
|
379
|
+
return self._returnData(await apiCall);
|
|
380
|
+
} catch (ex) {
|
|
381
|
+
throw ex;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
301
385
|
/**
|
|
302
386
|
* @author Myndware <augusto.pissarra@myndware.com>
|
|
303
387
|
* @description Remove a user
|
package/dist/bundle.cjs
CHANGED
|
@@ -14903,6 +14903,90 @@ class AdminUser {
|
|
|
14903
14903
|
}
|
|
14904
14904
|
}
|
|
14905
14905
|
|
|
14906
|
+
/**
|
|
14907
|
+
* @author Myndware <augusto.pissarra@myndware.com>
|
|
14908
|
+
* @description Batch-create users from an uploaded Excel (.xlsx) or CSV file.
|
|
14909
|
+
*
|
|
14910
|
+
* Uploads the file as multipart/form-data. The server parses it, validates
|
|
14911
|
+
* headers, de-duplicates emails, admits rows FIFO against the organization's
|
|
14912
|
+
* user cap, and delegates the actual creation to the existing registration
|
|
14913
|
+
* chain. Response is a per-row result array (created / existing / skipped).
|
|
14914
|
+
*
|
|
14915
|
+
* Status codes:
|
|
14916
|
+
* - 200 when at least one row was created or matched an existing user.
|
|
14917
|
+
* - 422 (same JSON body shape) when EVERY row was skipped — callers
|
|
14918
|
+
* should promote the 422 response body to a completed result, not an
|
|
14919
|
+
* error. Axios throws on 422 by default, so catch and inspect
|
|
14920
|
+
* `ex.response.data.results`.
|
|
14921
|
+
* - 400 for structural failures (invalid_file, missing_columns, empty_file,
|
|
14922
|
+
* too_many_rows) — `response.data.code` carries the machine-readable code.
|
|
14923
|
+
* - 403 when the caller does not belong to the target organization or lacks
|
|
14924
|
+
* user-admin role (code: 'forbidden').
|
|
14925
|
+
* - 413 when the uploaded file exceeds 2 MB.
|
|
14926
|
+
*
|
|
14927
|
+
* @param {FormData} formData A browser FormData instance with a single field
|
|
14928
|
+
* named `file` whose value is the .xlsx or .csv File/Blob. Must be
|
|
14929
|
+
* FormData so the browser/axios can set the multipart boundary.
|
|
14930
|
+
* @param {string} session JWT session token
|
|
14931
|
+
* @return {Promise<object>} Batch result:
|
|
14932
|
+
* {
|
|
14933
|
+
* total: number,
|
|
14934
|
+
* created: number,
|
|
14935
|
+
* existing: number,
|
|
14936
|
+
* skipped: number,
|
|
14937
|
+
* results: Array<{
|
|
14938
|
+
* row: number, // spreadsheet row (1-based, header = 1)
|
|
14939
|
+
* email: string,
|
|
14940
|
+
* status: 'created' | 'existing' | 'skipped',
|
|
14941
|
+
* userId: string | null,
|
|
14942
|
+
* message: string | null // snake_case code, optionally `code:detail`
|
|
14943
|
+
* }>
|
|
14944
|
+
* }
|
|
14945
|
+
* @public
|
|
14946
|
+
* @async
|
|
14947
|
+
* @example
|
|
14948
|
+
*
|
|
14949
|
+
* const API = require('@docbrasil/api-systemmanager');
|
|
14950
|
+
* const api = new API();
|
|
14951
|
+
* const fd = new FormData();
|
|
14952
|
+
* fd.append('file', fileInput.files[0]); // .xlsx or .csv
|
|
14953
|
+
* const session = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
|
|
14954
|
+
* // Ensure the client is scoped to the caller's org:
|
|
14955
|
+
* api.admin.user.setOrgId(myOrgId);
|
|
14956
|
+
* try {
|
|
14957
|
+
* const result = await api.admin.user.batchCreate(fd, session);
|
|
14958
|
+
* console.log(`${result.created} created, ${result.skipped} skipped`);
|
|
14959
|
+
* } catch (ex) {
|
|
14960
|
+
* if (ex?.response?.status === 422 && ex.response.data?.results) {
|
|
14961
|
+
* // All-skipped batch — still a valid result to render.
|
|
14962
|
+
* console.warn('All rows skipped:', ex.response.data.results);
|
|
14963
|
+
* } else {
|
|
14964
|
+
* throw ex;
|
|
14965
|
+
* }
|
|
14966
|
+
* }
|
|
14967
|
+
*/
|
|
14968
|
+
async batchCreate(formData, session) {
|
|
14969
|
+
const self = this;
|
|
14970
|
+
|
|
14971
|
+
try {
|
|
14972
|
+
Joi__default["default"].assert(formData, Joi__default["default"].any().required(), 'Multipart FormData with a `file` field');
|
|
14973
|
+
Joi__default["default"].assert(session, Joi__default["default"].string().required(), 'Session token');
|
|
14974
|
+
|
|
14975
|
+
// Do NOT force Content-Type — let the browser/axios set it with the
|
|
14976
|
+
// correct multipart boundary. Raise the axios body-size caps to 5 MB
|
|
14977
|
+
// (server enforces its own 2 MB cap via Hapi `maxBytes`).
|
|
14978
|
+
const cfg = {
|
|
14979
|
+
...self._setHeader(session),
|
|
14980
|
+
maxContentLength: 5 * 1024 * 1024,
|
|
14981
|
+
maxBodyLength: 5 * 1024 * 1024
|
|
14982
|
+
};
|
|
14983
|
+
const apiCall = self.client.put(`${self._basePath()}/batch`, formData, cfg);
|
|
14984
|
+
return self._returnData(await apiCall);
|
|
14985
|
+
} catch (ex) {
|
|
14986
|
+
throw ex;
|
|
14987
|
+
}
|
|
14988
|
+
}
|
|
14989
|
+
|
|
14906
14990
|
/**
|
|
14907
14991
|
* @author Myndware <augusto.pissarra@myndware.com>
|
|
14908
14992
|
* @description Remove a user
|