@newpeak/barista-cli 0.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 (82) hide show
  1. package/.eslintrc.json +23 -0
  2. package/.prettierrc +9 -0
  3. package/.sisyphus/notepads/liberica-employees/learnings.md +73 -0
  4. package/AGENTS.md +270 -0
  5. package/CONTRIBUTING.md +291 -0
  6. package/README.md +707 -0
  7. package/bin/barista +6 -0
  8. package/bin/barista.js +3 -0
  9. package/docs/ARCHITECTURE.md +184 -0
  10. package/docs/COMMANDS.md +352 -0
  11. package/docs/COMMAND_DESIGN_SPEC.md +811 -0
  12. package/docs/INTEGRATION_NOTES.md +270 -0
  13. package/docs/commands/REFERENCE.md +297 -0
  14. package/docs/commands/arabica/auth/index.md +296 -0
  15. package/docs/commands/liberica/auth/index.md +133 -0
  16. package/docs/commands/liberica/context/index.md +60 -0
  17. package/docs/commands/liberica/employees/create.md +185 -0
  18. package/docs/commands/liberica/employees/disable.md +138 -0
  19. package/docs/commands/liberica/employees/enable.md +137 -0
  20. package/docs/commands/liberica/employees/get.md +153 -0
  21. package/docs/commands/liberica/employees/list.md +168 -0
  22. package/docs/commands/liberica/employees/update.md +180 -0
  23. package/docs/commands/liberica/orgs/list.md +62 -0
  24. package/docs/commands/liberica/positions/list.md +61 -0
  25. package/docs/commands/liberica/roles/list.md +67 -0
  26. package/docs/commands/liberica/users/create.md +170 -0
  27. package/docs/commands/liberica/users/get.md +151 -0
  28. package/docs/commands/liberica/users/list.md +175 -0
  29. package/package.json +37 -0
  30. package/src/commands/arabica/auth/index.ts +277 -0
  31. package/src/commands/arabica/auth/login.ts +5 -0
  32. package/src/commands/arabica/auth/logout.ts +5 -0
  33. package/src/commands/arabica/auth/register.ts +5 -0
  34. package/src/commands/arabica/auth/status.ts +5 -0
  35. package/src/commands/arabica/index.ts +23 -0
  36. package/src/commands/auth.ts +107 -0
  37. package/src/commands/context.ts +60 -0
  38. package/src/commands/liberica/auth/index.ts +170 -0
  39. package/src/commands/liberica/context/index.ts +43 -0
  40. package/src/commands/liberica/employees/create.ts +275 -0
  41. package/src/commands/liberica/employees/delete.ts +122 -0
  42. package/src/commands/liberica/employees/disable.ts +97 -0
  43. package/src/commands/liberica/employees/enable.ts +97 -0
  44. package/src/commands/liberica/employees/get.ts +115 -0
  45. package/src/commands/liberica/employees/index.ts +23 -0
  46. package/src/commands/liberica/employees/list.ts +131 -0
  47. package/src/commands/liberica/employees/update.ts +157 -0
  48. package/src/commands/liberica/index.ts +36 -0
  49. package/src/commands/liberica/orgs/index.ts +35 -0
  50. package/src/commands/liberica/positions/index.ts +30 -0
  51. package/src/commands/liberica/roles/index.ts +59 -0
  52. package/src/commands/liberica/users/create.ts +132 -0
  53. package/src/commands/liberica/users/delete.ts +49 -0
  54. package/src/commands/liberica/users/disable.ts +41 -0
  55. package/src/commands/liberica/users/enable.ts +30 -0
  56. package/src/commands/liberica/users/get.ts +46 -0
  57. package/src/commands/liberica/users/index.ts +27 -0
  58. package/src/commands/liberica/users/list.ts +68 -0
  59. package/src/commands/liberica/users/me.ts +42 -0
  60. package/src/commands/liberica/users/reset-password.ts +42 -0
  61. package/src/commands/liberica/users/update.ts +48 -0
  62. package/src/core/api/client.ts +825 -0
  63. package/src/core/auth/token-manager.ts +183 -0
  64. package/src/core/config/manager.ts +164 -0
  65. package/src/index.ts +37 -0
  66. package/src/types/employee.ts +102 -0
  67. package/src/types/index.ts +75 -0
  68. package/src/types/org.ts +25 -0
  69. package/src/types/position.ts +24 -0
  70. package/src/types/user.ts +64 -0
  71. package/tests/unit/commands/arabica/auth.test.ts +230 -0
  72. package/tests/unit/commands/liberica/auth.test.ts +175 -0
  73. package/tests/unit/commands/liberica/context.test.ts +98 -0
  74. package/tests/unit/commands/liberica/employees/create.test.ts +463 -0
  75. package/tests/unit/commands/liberica/employees/disable.test.ts +82 -0
  76. package/tests/unit/commands/liberica/employees/enable.test.ts +82 -0
  77. package/tests/unit/commands/liberica/employees/get.test.ts +111 -0
  78. package/tests/unit/commands/liberica/employees/list.test.ts +294 -0
  79. package/tests/unit/commands/liberica/employees/update.test.ts +210 -0
  80. package/tests/unit/config.test.ts +141 -0
  81. package/tests/unit/types.test.ts +195 -0
  82. package/tsconfig.json +20 -0
@@ -0,0 +1,825 @@
1
+ import axios, { AxiosInstance, AxiosError } from 'axios';
2
+ import { configManager } from '../config/manager.js';
3
+ import { tokenManager } from '../auth/token-manager.js';
4
+ import { Service, Environment, APIResponse } from '../../types/index.js';
5
+ import {
6
+ CreateEmployeeRequest,
7
+ UpdateEmployeeRequest,
8
+ EmployeeQueryParams,
9
+ EmployeeApiResponse,
10
+ } from '../../types/employee.js';
11
+ import {
12
+ CreateUserRequest,
13
+ UpdateUserRequest,
14
+ UserQueryParams,
15
+ UserApiResponse,
16
+ } from '../../types/user.js';
17
+ import { OrgListItem } from '../../types/org.js';
18
+ import { PositionListItem } from '../../types/position.js';
19
+
20
+ export interface LoginResponse {
21
+ token: string;
22
+ expiresAt?: string;
23
+ }
24
+
25
+ export class APIClient {
26
+ private client: AxiosInstance;
27
+
28
+ constructor(baseURL: string, timeout: number = 30000) {
29
+ this.client = axios.create({
30
+ baseURL,
31
+ timeout,
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'tranLanguageCode': 'zh',
35
+ },
36
+ });
37
+ }
38
+
39
+ async login(
40
+ service: Service,
41
+ environment: Environment,
42
+ tenant: string,
43
+ username: string,
44
+ password: string
45
+ ): Promise<APIResponse<LoginResponse>> {
46
+ try {
47
+ const response = await this.client.post<APIResponse<LoginResponse>>('/api/enterprise/loginApi', {
48
+ account: username,
49
+ password,
50
+ });
51
+ return response.data;
52
+ } catch (error) {
53
+ if (axios.isAxiosError(error)) {
54
+ const axiosError = error as AxiosError<APIResponse<LoginResponse>>;
55
+ const responseData = axiosError.response?.data;
56
+ if (responseData) {
57
+ // Backend returns error in different format: {success, code, message} instead of {success, error: {code, message}}
58
+ if (!responseData.success && responseData.message) {
59
+ return {
60
+ success: false,
61
+ error: {
62
+ code: responseData.code || 'UNKNOWN_ERROR',
63
+ message: responseData.message,
64
+ },
65
+ };
66
+ }
67
+ return responseData;
68
+ }
69
+ return {
70
+ success: false,
71
+ error: {
72
+ code: 'NETWORK_ERROR',
73
+ message: axiosError.message || 'Network error occurred',
74
+ },
75
+ };
76
+ }
77
+ return {
78
+ success: false,
79
+ error: {
80
+ code: 'UNKNOWN_ERROR',
81
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
82
+ },
83
+ };
84
+ }
85
+ }
86
+
87
+ async loginArabica(
88
+ environment: Environment,
89
+ account: string,
90
+ password: string,
91
+ rememberMe: boolean = false
92
+ ): Promise<APIResponse<LoginResponse>> {
93
+ try {
94
+ const response = await this.client.post<APIResponse<LoginResponse>>('/api/login', {
95
+ account,
96
+ password,
97
+ rememberMe,
98
+ });
99
+ return response.data;
100
+ } catch (error) {
101
+ if (axios.isAxiosError(error)) {
102
+ const axiosError = error as AxiosError<APIResponse<LoginResponse>>;
103
+ const responseData = axiosError.response?.data;
104
+ if (responseData) {
105
+ if (!responseData.success && responseData.message) {
106
+ return {
107
+ success: false,
108
+ error: {
109
+ code: responseData.code || 'UNKNOWN_ERROR',
110
+ message: responseData.message,
111
+ },
112
+ };
113
+ }
114
+ return responseData;
115
+ }
116
+ return {
117
+ success: false,
118
+ error: {
119
+ code: 'NETWORK_ERROR',
120
+ message: axiosError.message || 'Network error occurred',
121
+ },
122
+ };
123
+ }
124
+ return {
125
+ success: false,
126
+ error: {
127
+ code: 'UNKNOWN_ERROR',
128
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
129
+ },
130
+ };
131
+ }
132
+ }
133
+
134
+ async registerArabica(
135
+ environment: Environment,
136
+ email: string,
137
+ account: string,
138
+ password: string,
139
+ phone?: string,
140
+ username?: string,
141
+ policyContent?: string,
142
+ privacyContent?: string
143
+ ): Promise<APIResponse<{ userId?: string }>> {
144
+ try {
145
+ const response = await this.client.post<APIResponse<{ userId?: string }>>('/member/user/register', {
146
+ email,
147
+ account,
148
+ password,
149
+ phone,
150
+ userName: username,
151
+ policyContent,
152
+ privacyContent,
153
+ });
154
+ return response.data;
155
+ } catch (error) {
156
+ if (axios.isAxiosError(error)) {
157
+ const axiosError = error as AxiosError<APIResponse<{ userId?: string }>>;
158
+ const responseData = axiosError.response?.data;
159
+ if (responseData) {
160
+ if (!responseData.success && responseData.message) {
161
+ return {
162
+ success: false,
163
+ error: {
164
+ code: responseData.code || 'UNKNOWN_ERROR',
165
+ message: responseData.message,
166
+ },
167
+ };
168
+ }
169
+ return responseData;
170
+ }
171
+ return {
172
+ success: false,
173
+ error: {
174
+ code: 'NETWORK_ERROR',
175
+ message: axiosError.message || 'Network error occurred',
176
+ },
177
+ };
178
+ }
179
+ return {
180
+ success: false,
181
+ error: {
182
+ code: 'UNKNOWN_ERROR',
183
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
184
+ },
185
+ };
186
+ }
187
+ }
188
+
189
+ setAuthToken(token: string): void {
190
+ this.client.defaults.headers.common['Authorization'] = token;
191
+ }
192
+
193
+ clearAuthToken(): void {
194
+ delete this.client.defaults.headers.common['Authorization'];
195
+ }
196
+
197
+ getClient(): AxiosInstance {
198
+ return this.client;
199
+ }
200
+ }
201
+
202
+ export function createAPIClient(service: Service, environment: Environment, tenant?: string): APIClient {
203
+ const baseURL = configManager.getEnvironmentUrl(service, environment, tenant);
204
+ const timeout = configManager.getConfig().environments[environment][service].timeout;
205
+ return new APIClient(baseURL, timeout);
206
+ }
207
+
208
+ const orgCache = new Map<string, { items: OrgListItem[]; timestamp: number }>();
209
+ const positionCache = new Map<string, { items: PositionListItem[]; timestamp: number }>();
210
+ const CACHE_TTL_MS = 5 * 60 * 1000;
211
+
212
+ export const apiClient = {
213
+ async login(
214
+ service: Service,
215
+ environment: Environment,
216
+ tenant: string,
217
+ username: string,
218
+ password: string
219
+ ): Promise<APIResponse<LoginResponse>> {
220
+ const client = createAPIClient(service, environment, tenant);
221
+ return client.login(service, environment, tenant, username, password);
222
+ },
223
+
224
+ async loginArabica(
225
+ environment: Environment,
226
+ account: string,
227
+ password: string,
228
+ rememberMe: boolean = false
229
+ ): Promise<APIResponse<LoginResponse>> {
230
+ const client = createAPIClient('arabica' as Service, environment);
231
+ return client.loginArabica(environment, account, password, rememberMe);
232
+ },
233
+
234
+ async registerArabica(
235
+ environment: Environment,
236
+ email: string,
237
+ account: string,
238
+ password: string,
239
+ phone?: string,
240
+ username?: string,
241
+ policyContent?: string,
242
+ privacyContent?: string
243
+ ): Promise<APIResponse<{ userId?: string }>> {
244
+ const client = createAPIClient('arabica' as Service, environment);
245
+ return client.registerArabica(environment, email, account, password, phone, username, policyContent, privacyContent);
246
+ },
247
+
248
+ async getCodeByType(
249
+ environment: Environment,
250
+ tenant: string,
251
+ type: string
252
+ ): Promise<{ success: boolean; data?: string; error?: { code: string; message: string } }> {
253
+ try {
254
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
255
+ if (!token) {
256
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
257
+ }
258
+ const client = createAPIClient('liberica' as Service, environment, tenant);
259
+ client.setAuthToken(token);
260
+ const response = await client.getClient().get<{ success: boolean; data?: string; message?: string }>(
261
+ `/api/enterprise/master/id/getCodeByType?type=${type}`
262
+ );
263
+ return response.data;
264
+ } catch (error) {
265
+ const errorResult = handleApiError(error) as { success: boolean; data?: string; error?: { code: string; message: string } };
266
+ return errorResult;
267
+ }
268
+ },
269
+
270
+ async createEmployee(
271
+ environment: Environment,
272
+ tenant: string,
273
+ data: CreateEmployeeRequest
274
+ ): Promise<EmployeeApiResponse> {
275
+ try {
276
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
277
+ if (!token) {
278
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
279
+ }
280
+ const client = createAPIClient('liberica' as Service, environment, tenant);
281
+ client.setAuthToken(token);
282
+ const response = await client.getClient().post<EmployeeApiResponse>('/api/enterprise/employee/add', data);
283
+ return response.data;
284
+ } catch (error) {
285
+ return handleApiError(error);
286
+ }
287
+ },
288
+
289
+ async searchEmployees(
290
+ environment: Environment,
291
+ tenant: string,
292
+ searchText: string
293
+ ): Promise<{ success: boolean; data?: any[]; error?: { code: string; message: string } }> {
294
+ try {
295
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
296
+ if (!token) {
297
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
298
+ }
299
+ const client = createAPIClient('liberica' as Service, environment, tenant);
300
+ client.setAuthToken(token);
301
+ const url = `/api/enterprise/master/employee/list?searchText=${encodeURIComponent(searchText)}`;
302
+ const response = await client.getClient().get(url);
303
+ return response.data;
304
+ } catch (error) {
305
+ return handleApiError(error) as { success: boolean; data?: any[]; error?: { code: string; message: string } };
306
+ }
307
+ },
308
+
309
+ async listEmployees(
310
+ environment: Environment,
311
+ tenant: string,
312
+ params: EmployeeQueryParams
313
+ ): Promise<EmployeeApiResponse> {
314
+ try {
315
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
316
+ if (!token) {
317
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
318
+ }
319
+ const client = createAPIClient('liberica' as Service, environment, tenant);
320
+ client.setAuthToken(token);
321
+ const queryString = new URLSearchParams();
322
+ if (params.pageNo !== undefined) queryString.append('pageNo', params.pageNo.toString());
323
+ if (params.pageSize) queryString.append('pageSize', params.pageSize.toString());
324
+ if (params.status) queryString.append('status', params.status.toString());
325
+ if (params.organizationId) queryString.append('organizationId', params.organizationId.toString());
326
+ if (params.employeeCode) queryString.append('employeeCode', params.employeeCode);
327
+ if (params.employeeName) queryString.append('employeeName', params.employeeName);
328
+ const url = `/api/enterprise/employee/page${queryString.toString() ? '?' + queryString.toString() : ''}`;
329
+ const response = await client.getClient().get<EmployeeApiResponse>(url);
330
+ return response.data;
331
+ } catch (error) {
332
+ return handleApiError(error);
333
+ }
334
+ },
335
+
336
+ async getEmployee(
337
+ environment: Environment,
338
+ tenant: string,
339
+ employeeId: string
340
+ ): Promise<EmployeeApiResponse> {
341
+ try {
342
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
343
+ if (!token) {
344
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
345
+ }
346
+ const client = createAPIClient('liberica' as Service, environment, tenant);
347
+ client.setAuthToken(token);
348
+ const response = await client.getClient().get<EmployeeApiResponse>(
349
+ `/api/enterprise/employee/detail?employeeId=${employeeId}`
350
+ );
351
+ return response.data;
352
+ } catch (error) {
353
+ return handleApiError(error);
354
+ }
355
+ },
356
+
357
+ async updateEmployee(
358
+ environment: Environment,
359
+ tenant: string,
360
+ data: UpdateEmployeeRequest
361
+ ): Promise<EmployeeApiResponse> {
362
+ try {
363
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
364
+ if (!token) {
365
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
366
+ }
367
+ const client = createAPIClient('liberica' as Service, environment, tenant);
368
+ client.setAuthToken(token);
369
+ const response = await client.getClient().post<EmployeeApiResponse>('/api/enterprise/employee/edit', data);
370
+ return response.data;
371
+ } catch (error) {
372
+ return handleApiError(error);
373
+ }
374
+ },
375
+
376
+ async disableEmployee(
377
+ environment: Environment,
378
+ tenant: string,
379
+ employeeId: string
380
+ ): Promise<EmployeeApiResponse> {
381
+ try {
382
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
383
+ if (!token) {
384
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
385
+ }
386
+ const client = createAPIClient('liberica' as Service, environment, tenant);
387
+ client.setAuthToken(token);
388
+ const response = await client.getClient().post<EmployeeApiResponse>(
389
+ '/api/enterprise/employee/deActive',
390
+ { employeeId }
391
+ );
392
+ return response.data;
393
+ } catch (error) {
394
+ return handleApiError(error);
395
+ }
396
+ },
397
+
398
+ async enableEmployee(
399
+ environment: Environment,
400
+ tenant: string,
401
+ employeeId: string
402
+ ): Promise<EmployeeApiResponse> {
403
+ try {
404
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
405
+ if (!token) {
406
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
407
+ }
408
+ const client = createAPIClient('liberica' as Service, environment, tenant);
409
+ client.setAuthToken(token);
410
+ const response = await client.getClient().post<EmployeeApiResponse>(
411
+ '/api/enterprise/employee/active',
412
+ { employeeId }
413
+ );
414
+ return response.data;
415
+ } catch (error) {
416
+ return handleApiError(error);
417
+ }
418
+ },
419
+
420
+ async deleteEmployee(
421
+ environment: Environment,
422
+ tenant: string,
423
+ employeeId: string
424
+ ): Promise<EmployeeApiResponse> {
425
+ try {
426
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
427
+ if (!token) {
428
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
429
+ }
430
+ const client = createAPIClient('liberica' as Service, environment, tenant);
431
+ client.setAuthToken(token);
432
+ const response = await client.getClient().post<EmployeeApiResponse>(
433
+ '/api/enterprise/employee/delete',
434
+ { employeeId }
435
+ );
436
+ return response.data;
437
+ } catch (error) {
438
+ return handleApiError(error);
439
+ }
440
+ },
441
+
442
+ async getOrgListName(
443
+ environment: Environment,
444
+ tenant: string
445
+ ): Promise<{ success: boolean; data?: OrgListItem[]; error?: { code: string; message: string } }> {
446
+ const cacheKey = `${environment}:${tenant}`;
447
+ const cached = orgCache.get(cacheKey);
448
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
449
+ return { success: true, data: cached.items };
450
+ }
451
+ try {
452
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
453
+ if (!token) {
454
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
455
+ }
456
+ const client = createAPIClient('liberica' as Service, environment, tenant);
457
+ client.setAuthToken(token);
458
+ // Use /tree endpoint which returns all orgs with their IDs and names
459
+ const response = await client.getClient().post<{ success?: boolean; data?: { orgTreeList?: { orgId: number; orgName?: string }[] }; message?: string }>(
460
+ '/api/enterprise/master/org/tree',
461
+ { orgParentId: -1 } // -1 means get all root orgs
462
+ );
463
+ if (response.data?.success === false) {
464
+ return {
465
+ success: false,
466
+ error: { code: response.data?.message || 'FETCH_ORG_ERROR', message: response.data?.message || 'Failed to fetch organization list' },
467
+ };
468
+ }
469
+ const orgList = (response.data as any)?.data?.orgTreeList || [];
470
+ const items: OrgListItem[] = orgList.map((o: { orgId: number; orgName?: string }) => ({
471
+ id: o.orgId,
472
+ name: o.orgName || '',
473
+ }));
474
+ orgCache.set(cacheKey, { items, timestamp: Date.now() });
475
+ return { success: true, data: items };
476
+ } catch (error) {
477
+ return handleApiError(error) as { success: boolean; data?: OrgListItem[]; error?: { code: string; message: string } };
478
+ }
479
+ },
480
+
481
+ async listPositions(
482
+ environment: Environment,
483
+ tenant: string
484
+ ): Promise<{ success: boolean; data?: PositionListItem[]; error?: { code: string; message: string } }> {
485
+ const cacheKey = `${environment}:${tenant}`;
486
+ const cached = positionCache.get(cacheKey);
487
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
488
+ return { success: true, data: cached.items };
489
+ }
490
+ try {
491
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
492
+ if (!token) {
493
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
494
+ }
495
+ const client = createAPIClient('liberica' as Service, environment, tenant);
496
+ client.setAuthToken(token);
497
+ const response = await client.getClient().get<{ success?: boolean; data?: { id?: string; name?: string }[]; message?: string }>(
498
+ '/api/enterprise/master/position/list'
499
+ );
500
+ if (response.data?.success === false) {
501
+ return {
502
+ success: false,
503
+ error: { code: response.data?.message || 'FETCH_POSITION_ERROR', message: response.data?.message || 'Failed to fetch position list' },
504
+ };
505
+ }
506
+ const items: PositionListItem[] = ((response.data as any)?.data || []).map((p: { id?: string; name?: string }) => ({
507
+ id: p.id || '',
508
+ name: p.name || '',
509
+ }));
510
+ positionCache.set(cacheKey, { items, timestamp: Date.now() });
511
+ return { success: true, data: items };
512
+ } catch (error) {
513
+ return handleApiError(error) as { success: boolean; data?: PositionListItem[]; error?: { code: string; message: string } };
514
+ }
515
+ },
516
+
517
+ async createUser(
518
+ environment: Environment,
519
+ tenant: string,
520
+ data: CreateUserRequest
521
+ ): Promise<UserApiResponse> {
522
+ try {
523
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
524
+ if (!token) {
525
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
526
+ }
527
+ const client = createAPIClient('liberica' as Service, environment, tenant);
528
+ client.setAuthToken(token);
529
+ const response = await client.getClient().post<UserApiResponse>('/api/enterprise/user/add', data);
530
+ return response.data;
531
+ } catch (error) {
532
+ return handleApiError(error) as UserApiResponse;
533
+ }
534
+ },
535
+
536
+ async listUsers(
537
+ environment: Environment,
538
+ tenant: string,
539
+ params: UserQueryParams
540
+ ): Promise<UserApiResponse> {
541
+ try {
542
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
543
+ if (!token) {
544
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
545
+ }
546
+ const client = createAPIClient('liberica' as Service, environment, tenant);
547
+ client.setAuthToken(token);
548
+ const queryString = new URLSearchParams();
549
+ if (params.pageNo !== undefined) queryString.append('pageNo', params.pageNo.toString());
550
+ if (params.pageSize) queryString.append('pageSize', params.pageSize.toString());
551
+ if (params.status) queryString.append('status', params.status.toString());
552
+ if (params.account) queryString.append('account', params.account);
553
+ if (params.realName) queryString.append('realName', params.realName);
554
+ if (params.employeeId) queryString.append('employeeId', params.employeeId.toString());
555
+ const url = '/api/enterprise/user/page' + (queryString.toString() ? '?' + queryString.toString() : '');
556
+ const response = await client.getClient().get<UserApiResponse>(url);
557
+ return response.data;
558
+ } catch (error) {
559
+ return handleApiError(error) as UserApiResponse;
560
+ }
561
+ },
562
+
563
+ async getUser(
564
+ environment: Environment,
565
+ tenant: string,
566
+ userId: string
567
+ ): Promise<UserApiResponse> {
568
+ try {
569
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
570
+ if (!token) {
571
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
572
+ }
573
+ const client = createAPIClient('liberica' as Service, environment, tenant);
574
+ client.setAuthToken(token);
575
+ const response = await client.getClient().get<UserApiResponse>(
576
+ '/api/enterprise/user/detail?userId=' + userId
577
+ );
578
+ return response.data;
579
+ } catch (error) {
580
+ return handleApiError(error) as UserApiResponse;
581
+ }
582
+ },
583
+
584
+ async updateUser(
585
+ environment: Environment,
586
+ tenant: string,
587
+ data: UpdateUserRequest
588
+ ): Promise<UserApiResponse> {
589
+ try {
590
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
591
+ if (!token) {
592
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
593
+ }
594
+ const client = createAPIClient('liberica' as Service, environment, tenant);
595
+ client.setAuthToken(token);
596
+ const response = await client.getClient().post<UserApiResponse>('/api/enterprise/user/edit', data);
597
+ return response.data;
598
+ } catch (error) {
599
+ return handleApiError(error) as UserApiResponse;
600
+ }
601
+ },
602
+
603
+ async deleteUser(
604
+ environment: Environment,
605
+ tenant: string,
606
+ userId: string
607
+ ): Promise<UserApiResponse> {
608
+ try {
609
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
610
+ if (!token) {
611
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
612
+ }
613
+ const client = createAPIClient('liberica' as Service, environment, tenant);
614
+ client.setAuthToken(token);
615
+ const response = await client.getClient().post<UserApiResponse>(
616
+ '/api/enterprise/user/batchDelete',
617
+ { userIdList: [userId] }
618
+ );
619
+ return response.data;
620
+ } catch (error) {
621
+ return handleApiError(error) as UserApiResponse;
622
+ }
623
+ },
624
+
625
+ async enableUser(
626
+ environment: Environment,
627
+ tenant: string,
628
+ userId: string
629
+ ): Promise<UserApiResponse> {
630
+ try {
631
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
632
+ if (!token) {
633
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
634
+ }
635
+ const client = createAPIClient('liberica' as Service, environment, tenant);
636
+ client.setAuthToken(token);
637
+ const response = await client.getClient().post<UserApiResponse>(
638
+ '/api/enterprise/user/batchActive',
639
+ { userIdList: [userId] }
640
+ );
641
+ return response.data;
642
+ } catch (error) {
643
+ return handleApiError(error) as UserApiResponse;
644
+ }
645
+ },
646
+
647
+ async disableUser(
648
+ environment: Environment,
649
+ tenant: string,
650
+ userId: string
651
+ ): Promise<UserApiResponse> {
652
+ try {
653
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
654
+ if (!token) {
655
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
656
+ }
657
+ const client = createAPIClient('liberica' as Service, environment, tenant);
658
+ client.setAuthToken(token);
659
+ const response = await client.getClient().post<UserApiResponse>(
660
+ '/api/enterprise/user/batchDeActive',
661
+ { userIdList: [userId] }
662
+ );
663
+ return response.data;
664
+ } catch (error) {
665
+ return handleApiError(error) as UserApiResponse;
666
+ }
667
+ },
668
+
669
+ async getCurrentUser(
670
+ environment: Environment,
671
+ tenant: string
672
+ ): Promise<UserApiResponse> {
673
+ try {
674
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
675
+ if (!token) {
676
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
677
+ }
678
+ const client = createAPIClient('liberica' as Service, environment, tenant);
679
+ client.setAuthToken(token);
680
+ const response = await client.getClient().get<UserApiResponse>('/api/enterprise/user/getUserInfo');
681
+ return response.data;
682
+ } catch (error) {
683
+ return handleApiError(error) as UserApiResponse;
684
+ }
685
+ },
686
+
687
+ async getUserIndexInfo(
688
+ environment: Environment,
689
+ tenant: string
690
+ ): Promise<{ success: boolean; data?: any; error?: { code: string; message: string } }> {
691
+ try {
692
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
693
+ if (!token) {
694
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
695
+ }
696
+ const client = createAPIClient('liberica' as Service, environment, tenant);
697
+ client.setAuthToken(token);
698
+ const response = await client.getClient().get('/api/userIndexInfo');
699
+ return response.data;
700
+ } catch (error) {
701
+ return handleApiError(error) as { success: boolean; data?: any; error?: { code: string; message: string } };
702
+ }
703
+ },
704
+
705
+ async updateUserOrgOrApp(
706
+ environment: Environment,
707
+ tenant: string,
708
+ params: { newOrgId?: string; newAppId?: string }
709
+ ): Promise<{ success: boolean; data?: any; error?: { code: string; message: string } }> {
710
+ try {
711
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
712
+ if (!token) {
713
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
714
+ }
715
+ const client = createAPIClient('liberica' as Service, environment, tenant);
716
+ client.setAuthToken(token);
717
+ const response = await client.getClient().post('/api/updateUserOrgOrApp', params);
718
+ return response.data;
719
+ } catch (error) {
720
+ return handleApiError(error) as { success: boolean; data?: any; error?: { code: string; message: string } };
721
+ }
722
+ },
723
+
724
+ async resetPassword(
725
+ environment: Environment,
726
+ tenant: string,
727
+ userId: string
728
+ ): Promise<UserApiResponse> {
729
+ try {
730
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
731
+ if (!token) {
732
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
733
+ }
734
+ const client = createAPIClient('liberica' as Service, environment, tenant);
735
+ client.setAuthToken(token);
736
+ const response = await client.getClient().post<UserApiResponse>(
737
+ '/api/enterprise/user/resetPassword',
738
+ { userId }
739
+ );
740
+ return response.data;
741
+ } catch (error) {
742
+ return handleApiError(error) as UserApiResponse;
743
+ }
744
+ },
745
+
746
+ async listRoles(
747
+ environment: Environment,
748
+ tenant: string
749
+ ): Promise<{ success: boolean; data?: any[]; error?: { code: string; message: string } }> {
750
+ try {
751
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
752
+ if (!token) {
753
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
754
+ }
755
+ const client = createAPIClient('liberica' as Service, environment, tenant);
756
+ client.setAuthToken(token);
757
+ const response = await client.getClient().get('/api/enterprise/sysRole/list');
758
+ return response.data;
759
+ } catch (error) {
760
+ return handleApiError(error) as { success: boolean; data?: any[]; error?: { code: string; message: string } };
761
+ }
762
+ },
763
+
764
+ async existCheck(
765
+ environment: Environment,
766
+ tenant: string,
767
+ account: string
768
+ ): Promise<{ success: boolean; data?: boolean; error?: { code: string; message: string } }> {
769
+ try {
770
+ const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
771
+ if (!token) {
772
+ return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in. Run: barista auth login --service liberica --env ' + environment } };
773
+ }
774
+ const client = createAPIClient('liberica' as Service, environment, tenant);
775
+ client.setAuthToken(token);
776
+ const response = await client.getClient().get('/api/enterprise/user/existCheck', {
777
+ params: { account },
778
+ timeout: 60000 // 增加超时时间到60秒
779
+ });
780
+ return response.data;
781
+ } catch (error) {
782
+ return handleApiError(error) as { success: boolean; data?: boolean; error?: { code: string; message: string } };
783
+ }
784
+ },
785
+
786
+ };
787
+
788
+ function handleApiError(error: unknown): EmployeeApiResponse {
789
+ if (axios.isAxiosError(error)) {
790
+ const axiosError = error as AxiosError<Record<string, unknown>>;
791
+ const responseData = axiosError.response?.data;
792
+ if (responseData) {
793
+ const success = responseData.success as boolean | undefined;
794
+ if (success === false) {
795
+ const code = responseData.code as string | undefined;
796
+ const message = responseData.message as string | undefined;
797
+ const errorObj = responseData.error as { code?: string; message?: string } | undefined;
798
+ if (!errorObj && (code || message)) {
799
+ return {
800
+ success: false,
801
+ error: {
802
+ code: code || 'API_ERROR',
803
+ message: message || 'API error occurred',
804
+ },
805
+ };
806
+ }
807
+ }
808
+ return responseData as unknown as EmployeeApiResponse;
809
+ }
810
+ return {
811
+ success: false,
812
+ error: {
813
+ code: 'NETWORK_ERROR',
814
+ message: axiosError.message || 'Network error occurred',
815
+ },
816
+ };
817
+ }
818
+ return {
819
+ success: false,
820
+ error: {
821
+ code: 'UNKNOWN_ERROR',
822
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
823
+ },
824
+ };
825
+ }