@webex/contact-center 3.8.1 → 3.9.0-multipleLLM.1

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 (102) hide show
  1. package/dist/cc.js +106 -63
  2. package/dist/cc.js.map +1 -1
  3. package/dist/index.js +13 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/logger-proxy.js +24 -1
  6. package/dist/logger-proxy.js.map +1 -1
  7. package/dist/metrics/MetricsManager.js +1 -1
  8. package/dist/metrics/MetricsManager.js.map +1 -1
  9. package/dist/metrics/behavioral-events.js +88 -0
  10. package/dist/metrics/behavioral-events.js.map +1 -1
  11. package/dist/metrics/constants.js +26 -1
  12. package/dist/metrics/constants.js.map +1 -1
  13. package/dist/services/AddressBook.js +271 -0
  14. package/dist/services/AddressBook.js.map +1 -0
  15. package/dist/services/EntryPoint.js +227 -0
  16. package/dist/services/EntryPoint.js.map +1 -0
  17. package/dist/services/Queue.js +261 -0
  18. package/dist/services/Queue.js.map +1 -0
  19. package/dist/services/config/constants.js +24 -2
  20. package/dist/services/config/constants.js.map +1 -1
  21. package/dist/services/config/index.js +1 -43
  22. package/dist/services/config/index.js.map +1 -1
  23. package/dist/services/config/types.js +22 -5
  24. package/dist/services/config/types.js.map +1 -1
  25. package/dist/services/core/GlobalTypes.js.map +1 -1
  26. package/dist/services/core/Utils.js +162 -2
  27. package/dist/services/core/Utils.js.map +1 -1
  28. package/dist/services/core/aqm-reqs.js +0 -4
  29. package/dist/services/core/aqm-reqs.js.map +1 -1
  30. package/dist/services/core/websocket/WebSocketManager.js +0 -4
  31. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  32. package/dist/services/task/TaskManager.js +74 -2
  33. package/dist/services/task/TaskManager.js.map +1 -1
  34. package/dist/services/task/constants.js +7 -1
  35. package/dist/services/task/constants.js.map +1 -1
  36. package/dist/services/task/contact.js +86 -0
  37. package/dist/services/task/contact.js.map +1 -1
  38. package/dist/services/task/index.js +384 -72
  39. package/dist/services/task/index.js.map +1 -1
  40. package/dist/services/task/types.js +14 -0
  41. package/dist/services/task/types.js.map +1 -1
  42. package/dist/types/cc.d.ts +77 -43
  43. package/dist/types/index.d.ts +8 -3
  44. package/dist/types/metrics/constants.d.ts +20 -0
  45. package/dist/types/services/AddressBook.d.ts +74 -0
  46. package/dist/types/services/EntryPoint.d.ts +67 -0
  47. package/dist/types/services/Queue.d.ts +76 -0
  48. package/dist/types/services/config/constants.d.ts +23 -1
  49. package/dist/types/services/config/index.d.ts +1 -14
  50. package/dist/types/services/config/types.d.ts +44 -64
  51. package/dist/types/services/core/GlobalTypes.d.ts +25 -0
  52. package/dist/types/services/core/Utils.d.ts +40 -1
  53. package/dist/types/services/task/constants.d.ts +6 -0
  54. package/dist/types/services/task/contact.d.ts +10 -0
  55. package/dist/types/services/task/index.d.ts +44 -2
  56. package/dist/types/services/task/types.d.ts +123 -1
  57. package/dist/types/types.d.ts +162 -0
  58. package/dist/types/utils/PageCache.d.ts +173 -0
  59. package/dist/types.js +17 -0
  60. package/dist/types.js.map +1 -1
  61. package/dist/utils/PageCache.js +192 -0
  62. package/dist/utils/PageCache.js.map +1 -0
  63. package/dist/webex.js +1 -1
  64. package/package.json +10 -10
  65. package/src/cc.ts +122 -81
  66. package/src/index.ts +19 -3
  67. package/src/logger-proxy.ts +24 -1
  68. package/src/metrics/MetricsManager.ts +1 -1
  69. package/src/metrics/behavioral-events.ts +92 -0
  70. package/src/metrics/constants.ts +30 -0
  71. package/src/services/AddressBook.ts +291 -0
  72. package/src/services/EntryPoint.ts +241 -0
  73. package/src/services/Queue.ts +277 -0
  74. package/src/services/config/constants.ts +26 -2
  75. package/src/services/config/index.ts +1 -55
  76. package/src/services/config/types.ts +22 -65
  77. package/src/services/core/GlobalTypes.ts +27 -0
  78. package/src/services/core/Utils.ts +199 -1
  79. package/src/services/core/aqm-reqs.ts +0 -5
  80. package/src/services/core/websocket/WebSocketManager.ts +0 -4
  81. package/src/services/task/TaskManager.ts +79 -3
  82. package/src/services/task/constants.ts +6 -0
  83. package/src/services/task/contact.ts +80 -0
  84. package/src/services/task/index.ts +457 -57
  85. package/src/services/task/types.ts +133 -0
  86. package/src/types.ts +180 -0
  87. package/src/utils/PageCache.ts +252 -0
  88. package/test/unit/spec/cc.ts +31 -82
  89. package/test/unit/spec/metrics/MetricsManager.ts +0 -1
  90. package/test/unit/spec/metrics/behavioral-events.ts +56 -0
  91. package/test/unit/spec/services/AddressBook.ts +332 -0
  92. package/test/unit/spec/services/EntryPoint.ts +259 -0
  93. package/test/unit/spec/services/Queue.ts +323 -0
  94. package/test/unit/spec/services/config/index.ts +0 -71
  95. package/test/unit/spec/services/core/Utils.ts +50 -0
  96. package/test/unit/spec/services/core/aqm-reqs.ts +1 -3
  97. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +0 -4
  98. package/test/unit/spec/services/task/TaskManager.ts +145 -1
  99. package/test/unit/spec/services/task/contact.ts +31 -1
  100. package/test/unit/spec/services/task/index.ts +410 -123
  101. package/umd/contact-center.min.js +2 -2
  102. package/umd/contact-center.min.js.map +1 -1
@@ -0,0 +1,291 @@
1
+ import {HTTP_METHODS, WebexSDK} from '../types';
2
+ import type {
3
+ AddressBookEntry,
4
+ AddressBookEntriesResponse,
5
+ AddressBookEntrySearchParams,
6
+ } from '../types';
7
+ import LoggerProxy from '../logger-proxy';
8
+ import WebexRequest from './core/WebexRequest';
9
+ import PageCache, {PAGINATION_DEFAULTS} from '../utils/PageCache';
10
+ import MetricsManager from '../metrics/MetricsManager';
11
+ import {WCC_API_GATEWAY} from './constants';
12
+ import {endPointMap} from './config/constants';
13
+ import {METRIC_EVENT_NAMES} from '../metrics/constants';
14
+
15
+ /**
16
+ * AddressBook API class for managing Webex Contact Center address book entries.
17
+ * Provides functionality to fetch address book entries using the entry API.
18
+ *
19
+ * @class AddressBook
20
+ * @public
21
+ * @example
22
+ * ```typescript
23
+ * import Webex from 'webex';
24
+ *
25
+ * const webex = new Webex({ credentials: 'YOUR_ACCESS_TOKEN' });
26
+ * const cc = webex.cc;
27
+ *
28
+ * // Register and login first
29
+ * await cc.register();
30
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
31
+ *
32
+ * // Get AddressBook API instance from ContactCenter
33
+ * const addressBookAPI = cc.addressBook;
34
+ *
35
+ * // Get entries from agent's default address book
36
+ * const entries = await addressBookAPI.getEntries();
37
+ *
38
+ * // Get entries from a specific address book with pagination
39
+ * const entries = await addressBookAPI.getEntries({
40
+ * addressBookId: 'addressBookId123',
41
+ * page: 0,
42
+ * pageSize: 50
43
+ * });
44
+ *
45
+ * // Search for specific entries
46
+ * const searchResults = await addressBook.getEntries({
47
+ * search: 'john',
48
+ * filter: 'name=="John Doe"'
49
+ * });
50
+ * ```
51
+ */
52
+ export class AddressBook {
53
+ private webexRequest: WebexRequest;
54
+ private webex: WebexSDK;
55
+ private getAddressBookId: () => string;
56
+ private metricsManager: MetricsManager;
57
+
58
+ // Page cache using the common utility
59
+ private pageCache: PageCache<AddressBookEntry>;
60
+
61
+ /**
62
+ * Creates an instance of AddressBook
63
+ * @param {WebexSDK} webex - The Webex SDK instance
64
+ * @param {() => string} getAddressBookId - Function to get the addressBookId from agent profile
65
+ * @public
66
+ */
67
+ constructor(webex: WebexSDK, getAddressBookId: () => string) {
68
+ this.webex = webex;
69
+ this.webexRequest = WebexRequest.getInstance({webex});
70
+ this.getAddressBookId = getAddressBookId;
71
+ this.pageCache = new PageCache<AddressBookEntry>('AddressBook');
72
+ this.metricsManager = MetricsManager.getInstance({webex});
73
+ }
74
+
75
+ /**
76
+ * Fetches address book entries for a specific address book using the entry API
77
+ * @param {AddressBookEntrySearchParams} [params] - Search and pagination parameters including addressBookId
78
+ * @returns {Promise<AddressBookEntriesResponse>} Promise resolving to address book entries
79
+ * @throws {Error} If the API call fails
80
+ * @public
81
+ * @example
82
+ * ```typescript
83
+ * // Get entries from agent's default address book
84
+ * const response = await addressBookAPI.getEntries();
85
+ *
86
+ * // Get entries from a specific address book with pagination
87
+ * const response = await addressBookAPI.getEntries({
88
+ * addressBookId: 'addressBookId123',
89
+ * page: 0,
90
+ * pageSize: 25
91
+ * });
92
+ * ```
93
+ */
94
+ public async getEntries(
95
+ params: AddressBookEntrySearchParams = {}
96
+ ): Promise<AddressBookEntriesResponse> {
97
+ const startTime = Date.now();
98
+ const {
99
+ addressBookId,
100
+ page = PAGINATION_DEFAULTS.PAGE,
101
+ pageSize = PAGINATION_DEFAULTS.PAGE_SIZE,
102
+ search,
103
+ filter,
104
+ attributes,
105
+ } = params;
106
+
107
+ // Use provided addressBookId or fall back to agent's address book
108
+ const bookId = addressBookId || this.getAddressBookId();
109
+ const orgId = this.webex.credentials.getOrgId();
110
+ const isSearchRequest = !!(search || filter || attributes);
111
+
112
+ LoggerProxy.info('Fetching address book entries', {
113
+ module: 'AddressBook',
114
+ method: 'getEntries',
115
+ data: {
116
+ orgId,
117
+ bookId,
118
+ page,
119
+ pageSize,
120
+ isSearchRequest,
121
+ },
122
+ });
123
+
124
+ // Check if we can use cache for simple pagination (no search/filter/attributes)
125
+ if (this.pageCache.canUseCache({search, filter, attributes})) {
126
+ const cacheKey = this.pageCache.buildCacheKey(bookId, page, pageSize);
127
+ const cachedPage = this.pageCache.getCachedPage(cacheKey);
128
+
129
+ if (cachedPage) {
130
+ const duration = Date.now() - startTime;
131
+
132
+ LoggerProxy.info(`Returning page ${page} from cache`, {
133
+ module: 'AddressBook',
134
+ method: 'getEntries',
135
+ data: {
136
+ cacheHit: true,
137
+ duration,
138
+ recordCount: cachedPage.data.length,
139
+ page,
140
+ pageSize,
141
+ },
142
+ });
143
+
144
+ return {
145
+ data: cachedPage.data,
146
+ meta: {
147
+ page,
148
+ pageSize,
149
+ totalPages: cachedPage.totalMeta?.totalPages,
150
+ totalRecords: cachedPage.totalMeta?.totalRecords,
151
+ },
152
+ };
153
+ }
154
+ }
155
+
156
+ // Start timing for the operation
157
+ this.metricsManager.timeEvent(METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_SUCCESS);
158
+
159
+ // Validate address book id early to avoid bad requests
160
+ if (!bookId) {
161
+ const errorData = {
162
+ orgId,
163
+ bookId,
164
+ isSearchRequest,
165
+ page,
166
+ pageSize,
167
+ error: 'Missing addressBookId for agent. Ensure agent profile contains addressBookId.',
168
+ };
169
+ LoggerProxy.error('AddressBook called without a valid addressBookId', {
170
+ module: 'AddressBook',
171
+ method: 'getEntries',
172
+ data: errorData,
173
+ });
174
+
175
+ this.metricsManager.trackEvent(METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_FAILED, errorData, [
176
+ 'behavioral',
177
+ 'operational',
178
+ ]);
179
+
180
+ throw new Error('AddressBook: addressBookId is not available for the current agent.');
181
+ }
182
+
183
+ try {
184
+ // Build query parameters according to spec
185
+ const queryParams = new URLSearchParams({
186
+ page: page.toString(),
187
+ pageSize: pageSize.toString(),
188
+ });
189
+
190
+ if (filter) queryParams.append('filter', filter);
191
+ if (attributes) queryParams.append('attributes', attributes);
192
+ if (search) queryParams.append('search', search);
193
+
194
+ const resource = endPointMap.addressBookEntries(orgId, bookId, queryParams.toString());
195
+
196
+ LoggerProxy.info('Making API request to fetch address book entries', {
197
+ module: 'AddressBook',
198
+ method: 'getEntries',
199
+ data: {
200
+ resource,
201
+ service: WCC_API_GATEWAY,
202
+ },
203
+ });
204
+
205
+ const response = await this.webexRequest.request({
206
+ service: WCC_API_GATEWAY,
207
+ resource,
208
+ method: HTTP_METHODS.GET,
209
+ });
210
+
211
+ const duration = Date.now() - startTime;
212
+
213
+ const recordCount = response.body?.data?.length || 0;
214
+ const totalRecords = response.body?.meta?.totalRecords;
215
+
216
+ LoggerProxy.info(`Successfully retrieved ${recordCount} address book entries`, {
217
+ module: 'AddressBook',
218
+ method: 'getEntries',
219
+ data: {
220
+ statusCode: response.statusCode,
221
+ duration,
222
+ recordCount,
223
+ totalRecords,
224
+ isSearchRequest,
225
+ page,
226
+ pageSize,
227
+ },
228
+ });
229
+
230
+ // Only track metrics for search requests or first page loads to reduce metric volume
231
+ if (isSearchRequest || page === 0) {
232
+ this.metricsManager.trackEvent(
233
+ METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_SUCCESS,
234
+ {
235
+ orgId,
236
+ bookId,
237
+ statusCode: response.statusCode,
238
+ recordCount,
239
+ totalRecords,
240
+ isSearchRequest,
241
+ isFirstPage: page === 0,
242
+ },
243
+ ['behavioral', 'operational']
244
+ );
245
+ }
246
+
247
+ // Cache the page data for simple pagination (no search/filter/attributes)
248
+ if (this.pageCache.canUseCache({search, filter, attributes}) && response.body?.data) {
249
+ const cacheKey = this.pageCache.buildCacheKey(bookId, page, pageSize);
250
+ this.pageCache.cachePage(cacheKey, response.body.data, response.body.meta);
251
+
252
+ LoggerProxy.info('Cached address book entries for future requests', {
253
+ module: 'AddressBook',
254
+ method: 'getEntries',
255
+ data: {
256
+ cacheKey,
257
+ recordCount,
258
+ },
259
+ });
260
+ }
261
+
262
+ return response.body;
263
+ } catch (error) {
264
+ const errorData = {
265
+ orgId,
266
+ bookId,
267
+ error: error instanceof Error ? error.message : String(error),
268
+ isSearchRequest,
269
+ page,
270
+ pageSize,
271
+ };
272
+
273
+ LoggerProxy.error('Failed to fetch address book entries', {
274
+ module: 'AddressBook',
275
+ method: 'getEntries',
276
+ data: errorData,
277
+ error,
278
+ });
279
+
280
+ // Track all failures for troubleshooting
281
+ this.metricsManager.trackEvent(METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_FAILED, errorData, [
282
+ 'behavioral',
283
+ 'operational',
284
+ ]);
285
+
286
+ throw error;
287
+ }
288
+ }
289
+ }
290
+
291
+ export default AddressBook;
@@ -0,0 +1,241 @@
1
+ import {HTTP_METHODS, WebexSDK} from '../types';
2
+ import type {EntryPointRecord, EntryPointListResponse, EntryPointSearchParams} from '../types';
3
+ import LoggerProxy from '../logger-proxy';
4
+ import WebexRequest from './core/WebexRequest';
5
+ import PageCache, {PAGINATION_DEFAULTS} from '../utils/PageCache';
6
+ import MetricsManager from '../metrics/MetricsManager';
7
+ import {WCC_API_GATEWAY} from './constants';
8
+ import {endPointMap} from './config/constants';
9
+ import {METRIC_EVENT_NAMES} from '../metrics/constants';
10
+
11
+ /**
12
+ * EntryPoint class for managing Webex Contact Center entry points.
13
+ * Provides functionality to fetch, search, and paginate through entry points.
14
+ *
15
+ * @class EntryPoint
16
+ * @public
17
+ * @example
18
+ * ```typescript
19
+ * import Webex from 'webex';
20
+ *
21
+ * const webex = new Webex({ credentials: 'YOUR_ACCESS_TOKEN' });
22
+ * const cc = webex.cc;
23
+ *
24
+ * // Register and login first
25
+ * await cc.register();
26
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
27
+ *
28
+ * // Get EntryPoint API instance from ContactCenter
29
+ * const entryPointAPI = cc.entryPoint;
30
+ *
31
+ * // Get all entry points with pagination
32
+ * const response = await entryPointAPI.getEntryPoints({
33
+ * page: 0,
34
+ * pageSize: 50
35
+ * });
36
+ *
37
+ * // Search for specific entry points
38
+ * const searchResults = await entryPointAPI.searchEntryPoints({
39
+ * search: 'support',
40
+ * filter: 'type=="voice"'
41
+ * });
42
+ * ```
43
+ */
44
+ export class EntryPoint {
45
+ private webexRequest: WebexRequest;
46
+ private webex: WebexSDK;
47
+ private metricsManager: MetricsManager;
48
+
49
+ // Page cache using the common utility
50
+ private pageCache: PageCache<EntryPointRecord>;
51
+
52
+ /**
53
+ * Creates an instance of EntryPoint
54
+ * @param {WebexSDK} webex - The Webex SDK instance
55
+ * @public
56
+ */
57
+ constructor(webex: WebexSDK) {
58
+ this.webex = webex;
59
+ this.webexRequest = WebexRequest.getInstance({webex});
60
+ this.pageCache = new PageCache<EntryPointRecord>('EntryPoint');
61
+ this.metricsManager = MetricsManager.getInstance({webex});
62
+ }
63
+
64
+ /**
65
+ * Fetches entry points for the organization with pagination support
66
+ * @param {EntryPointSearchParams} [params] - Search and pagination parameters
67
+ * @returns {Promise<EntryPointListResponse>} Promise resolving to paginated entry points
68
+ * @throws {Error} If the API call fails
69
+ * @public
70
+ * @example
71
+ * ```typescript
72
+ * // Get first page of entry points
73
+ * const response = await entryPointAPI.getEntryPoints();
74
+ *
75
+ * // Get specific page with custom page size
76
+ * const response = await entryPointAPI.getEntryPoints({
77
+ * page: 2,
78
+ * pageSize: 25
79
+ * });
80
+ * ```
81
+ */
82
+ public async getEntryPoints(
83
+ params: EntryPointSearchParams = {}
84
+ ): Promise<EntryPointListResponse> {
85
+ const startTime = Date.now();
86
+ const {
87
+ page = PAGINATION_DEFAULTS.PAGE,
88
+ pageSize = PAGINATION_DEFAULTS.PAGE_SIZE,
89
+ search,
90
+ filter,
91
+ attributes,
92
+ sortBy,
93
+ sortOrder = 'asc',
94
+ } = params;
95
+
96
+ const orgId = this.webex.credentials.getOrgId();
97
+ const isSearchRequest = !!(search || filter || attributes || sortBy);
98
+
99
+ LoggerProxy.info(
100
+ `Fetching entry points - orgId: ${orgId}, page: ${page}, pageSize: ${pageSize}, isSearchRequest: ${isSearchRequest}`,
101
+ {
102
+ module: 'EntryPoint',
103
+ method: 'getEntryPoints',
104
+ }
105
+ );
106
+
107
+ // Check if we can use cache for simple pagination (no search/filter/attributes/sort)
108
+ if (this.pageCache.canUseCache({search, filter, attributes, sortBy})) {
109
+ const cacheKey = this.pageCache.buildCacheKey(orgId, page, pageSize);
110
+ const cachedPage = this.pageCache.getCachedPage(cacheKey);
111
+
112
+ if (cachedPage) {
113
+ const duration = Date.now() - startTime;
114
+
115
+ LoggerProxy.log(
116
+ `Returning page ${page} from cache - cacheHit: true, duration: ${duration}ms, recordCount: ${cachedPage.data.length}, pageSize: ${pageSize}`,
117
+ {
118
+ module: 'EntryPoint',
119
+ method: 'getEntryPoints',
120
+ }
121
+ );
122
+
123
+ return {
124
+ data: cachedPage.data,
125
+ meta: {
126
+ page,
127
+ pageSize,
128
+ totalPages: cachedPage.totalMeta?.totalPages,
129
+ totalRecords: cachedPage.totalMeta?.totalRecords,
130
+ },
131
+ };
132
+ }
133
+ }
134
+
135
+ // Start timing only for actual API calls (not cache hits)
136
+ this.metricsManager.timeEvent(METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS);
137
+
138
+ try {
139
+ // Build query parameters
140
+ const queryParams = new URLSearchParams({
141
+ page: page.toString(),
142
+ pageSize: pageSize.toString(),
143
+ sortOrder,
144
+ });
145
+
146
+ if (search) queryParams.append('search', search);
147
+ if (filter) queryParams.append('filter', filter);
148
+ if (attributes) queryParams.append('attributes', attributes);
149
+ if (sortBy) queryParams.append('sortBy', sortBy);
150
+
151
+ const resource = endPointMap.entryPointList(orgId, queryParams.toString());
152
+
153
+ LoggerProxy.log(
154
+ `Making API request to fetch entry points - resource: ${resource}, service: ${WCC_API_GATEWAY}`,
155
+ {
156
+ module: 'EntryPoint',
157
+ method: 'getEntryPoints',
158
+ }
159
+ );
160
+
161
+ const response = await this.webexRequest.request({
162
+ service: WCC_API_GATEWAY,
163
+ resource,
164
+ method: HTTP_METHODS.GET,
165
+ });
166
+
167
+ const duration = Date.now() - startTime;
168
+
169
+ const recordCount = response.body?.data?.length || 0;
170
+ const totalRecords = response.body?.meta?.totalRecords;
171
+
172
+ LoggerProxy.log(`Successfully retrieved ${recordCount} entry points`, {
173
+ module: 'EntryPoint',
174
+ method: 'getEntryPoints',
175
+ data: {
176
+ statusCode: response.statusCode,
177
+ duration,
178
+ recordCount,
179
+ totalRecords,
180
+ isSearchRequest,
181
+ page,
182
+ pageSize,
183
+ },
184
+ });
185
+
186
+ // Only track metrics for search requests or first page loads to reduce metric volume
187
+ if (isSearchRequest || page === 0) {
188
+ this.metricsManager.trackEvent(
189
+ METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS,
190
+ {
191
+ orgId,
192
+ statusCode: response.statusCode,
193
+ recordCount,
194
+ totalRecords,
195
+ isSearchRequest,
196
+ isFirstPage: page === 0,
197
+ },
198
+ ['behavioral']
199
+ );
200
+ }
201
+
202
+ // Cache the page data for simple pagination (no search/filter/attributes/sort)
203
+ if (this.pageCache.canUseCache({search, filter, attributes, sortBy}) && response.body?.data) {
204
+ const cacheKey = this.pageCache.buildCacheKey(orgId, page, pageSize);
205
+ this.pageCache.cachePage(cacheKey, response.body.data, response.body.meta);
206
+
207
+ LoggerProxy.log('Cached entry points data for future requests', {
208
+ module: 'EntryPoint',
209
+ method: 'getEntryPoints',
210
+ data: {cacheKey, recordCount},
211
+ });
212
+ }
213
+
214
+ return response.body;
215
+ } catch (error) {
216
+ const errorData = {
217
+ orgId,
218
+ error: error instanceof Error ? error.message : String(error),
219
+ isSearchRequest,
220
+ page,
221
+ pageSize,
222
+ };
223
+
224
+ LoggerProxy.error(`Failed to fetch entry points`, {
225
+ module: 'EntryPoint',
226
+ method: 'getEntryPoints',
227
+ data: errorData,
228
+ error,
229
+ });
230
+
231
+ // Track all failures for troubleshooting
232
+ this.metricsManager.trackEvent(METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_FAILED, errorData, [
233
+ 'behavioral',
234
+ ]);
235
+
236
+ throw error;
237
+ }
238
+ }
239
+ }
240
+
241
+ export default EntryPoint;