@fluentcommerce/fc-connect-sdk 0.1.48 → 0.1.52

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 (47) hide show
  1. package/CHANGELOG.md +506 -379
  2. package/README.md +343 -0
  3. package/dist/cjs/clients/fluent-client.js +110 -14
  4. package/dist/cjs/data-sources/s3-data-source.js +1 -1
  5. package/dist/cjs/data-sources/sftp-data-source.js +1 -1
  6. package/dist/cjs/index.d.ts +1 -1
  7. package/dist/cjs/services/extraction/extraction-orchestrator.d.ts +4 -1
  8. package/dist/cjs/services/extraction/extraction-orchestrator.js +84 -11
  9. package/dist/cjs/types/index.d.ts +79 -10
  10. package/dist/cjs/versori/fluent-versori-client.d.ts +4 -1
  11. package/dist/cjs/versori/fluent-versori-client.js +131 -13
  12. package/dist/esm/clients/fluent-client.js +110 -14
  13. package/dist/esm/data-sources/s3-data-source.js +1 -1
  14. package/dist/esm/data-sources/sftp-data-source.js +1 -1
  15. package/dist/esm/index.d.ts +1 -1
  16. package/dist/esm/services/extraction/extraction-orchestrator.d.ts +4 -1
  17. package/dist/esm/services/extraction/extraction-orchestrator.js +84 -11
  18. package/dist/esm/types/index.d.ts +79 -10
  19. package/dist/esm/versori/fluent-versori-client.d.ts +4 -1
  20. package/dist/esm/versori/fluent-versori-client.js +131 -13
  21. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/dist/tsconfig.types.tsbuildinfo +1 -1
  24. package/dist/types/index.d.ts +1 -1
  25. package/dist/types/services/extraction/extraction-orchestrator.d.ts +4 -1
  26. package/dist/types/types/index.d.ts +79 -10
  27. package/dist/types/versori/fluent-versori-client.d.ts +4 -1
  28. package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +478 -18
  29. package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +83 -0
  30. package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +52 -0
  31. package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -0
  32. package/docs/02-CORE-GUIDES/api-reference/readme.md +1 -1
  33. package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +68 -4
  34. package/docs/02-CORE-GUIDES/mapping/modules/mapping-01-foundations.md +450 -448
  35. package/docs/02-CORE-GUIDES/mapping/modules/mapping-02-quick-start.md +476 -474
  36. package/docs/02-CORE-GUIDES/mapping/modules/mapping-03-schema-validation.md +464 -462
  37. package/docs/02-CORE-GUIDES/mapping/modules/mapping-05-advanced-patterns.md +1366 -1364
  38. package/docs/readme.md +245 -245
  39. package/package.json +17 -6
  40. package/docs/versori-apis/ACTIVATIONS-AND-VARIABLES-GUIDE.md +0 -60
  41. package/docs/versori-apis/JWT-GENERATION-GUIDE.md +0 -94
  42. package/docs/versori-apis/QUICK-WORKFLOW.md +0 -293
  43. package/docs/versori-apis/README.md +0 -73
  44. package/docs/versori-apis/VERSORI-PLATFORM-ARCHITECTURE.md +0 -880
  45. package/docs/versori-apis/Versori-Platform-API.postman_collection.json +0 -2925
  46. package/docs/versori-apis/Versori-Platform-API.postman_environment.example.json +0 -62
  47. package/docs/versori-apis/Versori-Platform-API.postman_environment.json +0 -178
@@ -5,9 +5,10 @@
5
5
  ## Table of Contents
6
6
 
7
7
  1. [Success Response Structure](#success-response-structure)
8
- 2. [Error Response Structure](#error-response-structure)
9
- 3. [Live Examples](#live-examples)
10
- 4. [HTTP Status Codes](#http-status-codes)
8
+ 2. [Event Log Query (GET)](#event-log-query-get)
9
+ 3. [Error Response Structure](#error-response-structure)
10
+ 4. [Live Examples](#live-examples)
11
+ 5. [HTTP Status Codes](#http-status-codes)
11
12
 
12
13
  ---
13
14
 
@@ -91,6 +92,219 @@ interface EventResponse {
91
92
 
92
93
  ---
93
94
 
95
+ ## Event Log Query (GET)
96
+
97
+ Use `client.getEvents()` for Event API log search (`GET /api/v4.1/event`).
98
+
99
+ ### Input: FluentEventQueryParams
100
+
101
+ ```typescript
102
+ interface FluentEventQueryParams {
103
+ start?: number;
104
+ count?: number;
105
+ from?: string;
106
+ to?: string;
107
+ name?: string;
108
+ category?: string;
109
+ retailerId?: string | number;
110
+ eventType?: string;
111
+ eventStatus?: string;
112
+ 'context.rootEntityType'?: string;
113
+ 'context.rootEntityId'?: string | number;
114
+ 'context.rootEntityRef'?: string;
115
+ 'context.entityType'?: string;
116
+ 'context.entityId'?: string | number;
117
+ 'context.entityRef'?: string;
118
+ }
119
+ ```
120
+
121
+ ### Output: FluentEventLogResponse (SUCCESS)
122
+
123
+ ```typescript
124
+ interface FluentEventLogResponse {
125
+ start: number;
126
+ count: number;
127
+ hasMore: boolean;
128
+ results: FluentEventLogItem[];
129
+ }
130
+ ```
131
+
132
+ ### When to use `getEvents()`
133
+
134
+ - Search historical events across a time window
135
+ - Investigate failed or delayed orchestration flows
136
+ - Filter by entity context to trace a specific order/job/product
137
+ - Collect event IDs for deeper inspection with `getEventById()`
138
+
139
+ ### `getEvents()` limitations and behavior
140
+
141
+ - Read-only endpoint: does not trigger workflows or mutate data
142
+ - `count` is capped by Fluent API (max `5000` per call)
143
+ - Time window constraints apply to `from` and `to`
144
+ - Empty `results` is a valid response for non-matching filters
145
+ - For large datasets, iterate with pagination (`start`, `count`)
146
+
147
+ ### Live Example: Orchestration Audit Query
148
+
149
+ **SDK Code:**
150
+ ```typescript
151
+ const result = await client.getEvents({
152
+ 'context.rootEntityType': 'JOB',
153
+ eventType: 'ORCHESTRATION_AUDIT',
154
+ start: 1,
155
+ count: 1000,
156
+ });
157
+ ```
158
+
159
+ **Output (HTTP 200):**
160
+ ```json
161
+ {
162
+ "start": 1,
163
+ "count": 1000,
164
+ "hasMore": false,
165
+ "results": [
166
+ {
167
+ "id": "e2cc5040-360b-43e9-b3c0-07bbc1934f82",
168
+ "name": "BATCH_COMPLETE",
169
+ "type": "ORCHESTRATION_AUDIT",
170
+ "accountId": "HMDEV",
171
+ "retailerId": "5",
172
+ "category": "BATCH",
173
+ "context": {
174
+ "sourceEvents": ["babc5f37-0a53-4d8e-85f2-dfab813d1e87"],
175
+ "entityType": "BATCH",
176
+ "entityId": "12",
177
+ "entityRef": "12",
178
+ "rootEntityType": "JOB",
179
+ "rootEntityId": "13",
180
+ "rootEntityRef": "13"
181
+ },
182
+ "eventStatus": "COMPLETE",
183
+ "attributes": null,
184
+ "source": null,
185
+ "generatedBy": "Rubix User",
186
+ "generatedOn": "2026-02-05T06:31:56.895+00:00"
187
+ }
188
+ ]
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Get Event By ID (GET)
195
+
196
+ Use `client.getEventById(eventId)` to retrieve a single event by its unique identifier (`GET /api/v4.1/event/{eventId}`).
197
+
198
+ ### Input
199
+
200
+ ```typescript
201
+ // Single string parameter - the event's unique ID
202
+ const eventId = '05838ba2-7025-11eb-b493-0f90922e985a';
203
+ const event = await client.getEventById(eventId);
204
+ ```
205
+
206
+ ### Output: FluentEventLogItem
207
+
208
+ ```typescript
209
+ interface FluentEventLogItem {
210
+ id: string; // Unique event identifier
211
+ name: string; // Event name (e.g., "DeactivateProduct")
212
+ type?: string; // ORCHESTRATION, ORCHESTRATION_AUDIT, API, GENERAL
213
+ accountId?: string; // Account identifier
214
+ retailerId?: string; // Retailer identifier
215
+ category?: string; // ruleSet, snapshot, ACTION, exception, etc.
216
+ context?: FluentEventLogContext; // Entity context information
217
+ eventStatus?: string; // SUCCESS, FAILED, PENDING, NO_MATCH, COMPLETE
218
+ attributes?: FluentEventLogAttribute[] | Record<string, AttributeValue> | null;
219
+ source?: string | null; // Event source
220
+ generatedBy?: string; // Who/what generated the event
221
+ generatedOn?: string; // ISO timestamp when event was generated
222
+ }
223
+
224
+ interface FluentEventLogContext {
225
+ sourceEvents?: string[]; // Parent event IDs (for tracing)
226
+ entityType?: string; // Entity type (ORDER, FULFILMENT, etc.)
227
+ entityId?: string; // Entity ID
228
+ entityRef?: string; // Entity reference
229
+ rootEntityType?: string; // Root entity type
230
+ rootEntityId?: string; // Root entity ID
231
+ rootEntityRef?: string; // Root entity reference
232
+ }
233
+ ```
234
+
235
+ > Note: `attributes` shape varies by event type. Some events return a key/value object, while orchestration events may return arrays or `null`.
236
+
237
+ ### Live Example: Get Event Details
238
+
239
+ **SDK Code:**
240
+ ```typescript
241
+ // Get specific event by ID
242
+ const event = await client.getEventById('e2cc5040-360b-43e9-b3c0-07bbc1934f82');
243
+
244
+ console.log(`Event: ${event.name}`);
245
+ console.log(`Status: ${event.eventStatus}`);
246
+ console.log(`Entity: ${event.context?.entityType}:${event.context?.entityRef}`);
247
+
248
+ // Trace parent events
249
+ if (event.context?.sourceEvents?.length) {
250
+ for (const parentId of event.context.sourceEvents) {
251
+ const parent = await client.getEventById(parentId);
252
+ console.log(` └─ Parent: ${parent.name} (${parent.eventStatus})`);
253
+ }
254
+ }
255
+
256
+ // Extract timing attributes (if available)
257
+ const attrs = event.attributes as Record<string, any> | null;
258
+ if (attrs) {
259
+ const startTimer = attrs['startTimer'];
260
+ const stopTimer = attrs['stopTimer'];
261
+ if (startTimer && stopTimer) {
262
+ const durationMs = parseInt(stopTimer) - parseInt(startTimer);
263
+ console.log(` Duration: ${durationMs}ms`);
264
+ }
265
+ }
266
+ ```
267
+
268
+ **Output (HTTP 200):**
269
+ ```json
270
+ {
271
+ "id": "e2cc5040-360b-43e9-b3c0-07bbc1934f82",
272
+ "name": "BATCH_COMPLETE",
273
+ "type": "ORCHESTRATION_AUDIT",
274
+ "accountId": "HMDEV",
275
+ "retailerId": "5",
276
+ "category": "BATCH",
277
+ "context": {
278
+ "sourceEvents": ["babc5f37-0a53-4d8e-85f2-dfab813d1e87"],
279
+ "entityType": "BATCH",
280
+ "entityId": "12",
281
+ "entityRef": "12",
282
+ "rootEntityType": "JOB",
283
+ "rootEntityId": "13",
284
+ "rootEntityRef": "13"
285
+ },
286
+ "eventStatus": "COMPLETE",
287
+ "attributes": null,
288
+ "source": null,
289
+ "generatedBy": "Rubix User",
290
+ "generatedOn": "2026-02-05T06:31:56.895+00:00"
291
+ }
292
+ ```
293
+
294
+ ### Error: Event Not Found (404)
295
+
296
+ ```typescript
297
+ try {
298
+ const event = await client.getEventById('non-existent-id');
299
+ } catch (error) {
300
+ if (error instanceof FluentAPIError && error.statusCode === 404) {
301
+ console.log('Event not found');
302
+ }
303
+ }
304
+ ```
305
+
306
+ ---
307
+
94
308
  ## Error Response Structure
95
309
 
96
310
  ### Output: FluentAPIError (THROWN)
@@ -101,7 +315,7 @@ When events fail, the SDK throws structured error objects:
101
315
  class FluentAPIError extends Error {
102
316
  name: 'FluentAPIError';
103
317
  message: string; // Error description (e.g., "Request failed: 400")
104
- status: number; // HTTP status code (400, 404, 500, etc.)
318
+ statusCode: number; // HTTP status code (400, 404, 500, etc.)
105
319
  details?: any; // Additional error context
106
320
  errors?: Array<any>; // Validation errors (if applicable)
107
321
  }
@@ -124,7 +338,7 @@ class FluentAPIError extends Error {
124
338
  FluentAPIError {
125
339
  name: "FluentAPIError",
126
340
  message: "Request failed: 404",
127
- status: 404,
341
+ statusCode: 404,
128
342
  details: "No workflow rule matched this event"
129
343
  }
130
344
  ```
@@ -152,7 +366,7 @@ FluentAPIError {
152
366
  FluentAPIError {
153
367
  name: "FluentAPIError",
154
368
  message: "Request failed: 400",
155
- status: 400,
369
+ statusCode: 400,
156
370
  details: "Bad Request - Invalid event configuration"
157
371
  }
158
372
  ```
@@ -285,7 +499,7 @@ POST /api/v4.1/event/sync
285
499
 
286
500
  # Output (HTTP 404) - THROWS FluentAPIError
287
501
  FluentAPIError: Request failed: 404
288
- status: 404
502
+ statusCode: 404
289
503
  message: "No workflow rule matched this event"
290
504
  ```
291
505
 
@@ -300,7 +514,7 @@ try {
300
514
  }, 'sync'); // ← Sync mode waits for workflow
301
515
  } catch (error) {
302
516
  if (error instanceof FluentAPIError) {
303
- console.error(`❌ HTTP ${error.status}: ${error.message}`);
517
+ console.error(`❌ HTTP ${error.statusCode}: ${error.message}`);
304
518
  // Output: ❌ HTTP 404: Request failed: 404
305
519
  }
306
520
  }
@@ -363,7 +577,7 @@ POST /api/v4.1/event/async
363
577
 
364
578
  # Output (HTTP 400) - THROWS FluentAPIError
365
579
  FluentAPIError: Request failed: 400
366
- status: 400
580
+ statusCode: 400
367
581
  message: "Bad Request"
368
582
  ```
369
583
 
@@ -378,7 +592,7 @@ try {
378
592
  }, 'async');
379
593
  } catch (error) {
380
594
  if (error instanceof FluentAPIError) {
381
- console.error(`❌ HTTP ${error.status}: ${error.message}`);
595
+ console.error(`❌ HTTP ${error.statusCode}: ${error.message}`);
382
596
  // Output: ❌ HTTP 400: Request failed: 400
383
597
  // SDK does NOT retry 4xx errors (client error, not transient)
384
598
  }
@@ -483,7 +697,7 @@ try {
483
697
  {
484
698
  name: "FluentAPIError",
485
699
  message: "Request failed: 404",
486
- status: 404,
700
+ statusCode: 404,
487
701
  details: "No workflow rule matched"
488
702
  }
489
703
  ```
@@ -563,7 +777,7 @@ try {
563
777
  await client.sendEvent({ name: 'InvalidEvent', ... });
564
778
  } catch (error) {
565
779
  // Throws immediately, NO retries
566
- console.error(error.status); // 400
780
+ console.error(error.statusCode); // 400
567
781
  }
568
782
  ```
569
783
 
@@ -593,8 +807,8 @@ for (const record of records) {
593
807
 
594
808
  if (error instanceof FluentAPIError) {
595
809
  // SDK already retried 401/5xx - this is non-retryable
596
- console.error(`❌ ${record.sku} - HTTP ${error.status}: ${error.message}`);
597
- results.errors.push({ sku: record.sku, status: error.status, error: error.message });
810
+ console.error(`❌ ${record.sku} - HTTP ${error.statusCode}: ${error.message}`);
811
+ results.errors.push({ sku: record.sku, statusCode: error.statusCode, error: error.message });
598
812
  } else if (error instanceof AuthenticationError) {
599
813
  // Auth failed after 3 retries - credentials issue
600
814
  console.error(`❌ Auth failure: ${error.message}`);
@@ -641,7 +855,7 @@ async function processBatch(products: Product[]): Promise<EventResult[]> {
641
855
  results.push({
642
856
  sku: product.sku,
643
857
  success: false,
644
- error: `HTTP ${error.status}: ${error.message}`
858
+ error: `HTTP ${error.statusCode}: ${error.message}`
645
859
  });
646
860
  } else {
647
861
  results.push({
@@ -689,6 +903,252 @@ async function processBatch(products: Product[]): Promise<EventResult[]> {
689
903
 
690
904
  ---
691
905
 
906
+ ## Event Log Query by ID (GET /api/v4.1/event/{eventId})
907
+
908
+ Use `client.getEventById(eventId)` to retrieve a single event by its unique identifier.
909
+
910
+ ### Input
911
+
912
+ ```typescript
913
+ const event = await client.getEventById('05838ba2-7025-11eb-b493-0f90922e985a');
914
+ ```
915
+
916
+ ### Output: FluentEventLogItem
917
+
918
+ ```typescript
919
+ interface FluentEventLogItem {
920
+ id: string;
921
+ name: string; // Event name (e.g., "BATCH_COMPLETE") — can be null
922
+ type?: string; // ORCHESTRATION_AUDIT, ORCHESTRATION, API, etc.
923
+ accountId?: string;
924
+ retailerId?: string; // String in API response
925
+ category?: string;
926
+ context?: FluentEventLogContext;
927
+ eventStatus?: string; // PENDING, SUCCESS, FAILED, COMPLETE, etc.
928
+ attributes?: FluentEventLogAttribute[] | null; // Can be null
929
+ source?: string | null;
930
+ generatedBy?: string;
931
+ generatedOn?: string; // ISO timestamp
932
+ }
933
+ ```
934
+
935
+ ### Live Example: Get Event by ID
936
+
937
+ **SDK Code:**
938
+ ```typescript
939
+ const event = await client.getEventById('e2cc5040-360b-43e9-b3c0-07bbc1934f82');
940
+ console.log(`Event: ${event.name} - Status: ${event.eventStatus}`);
941
+
942
+ // Trace parent events
943
+ if (event.context?.sourceEvents?.length) {
944
+ for (const parentId of event.context.sourceEvents) {
945
+ const parent = await client.getEventById(parentId);
946
+ console.log(`Parent: ${parent.name} (${parent.eventStatus})`);
947
+ }
948
+ }
949
+
950
+ // Extract timing from attributes
951
+ if (Array.isArray(event.attributes)) {
952
+ const startTimer = event.attributes.find(a => a.name === 'startTimer')?.value;
953
+ const stopTimer = event.attributes.find(a => a.name === 'stopTimer')?.value;
954
+ if (startTimer && stopTimer) {
955
+ console.log(`Duration: ${Number(stopTimer) - Number(startTimer)}ms`);
956
+ }
957
+ }
958
+ ```
959
+
960
+ ### Error Handling
961
+
962
+ ```typescript
963
+ try {
964
+ const event = await client.getEventById('nonexistent-id');
965
+ } catch (error) {
966
+ if (error instanceof FluentAPIError && error.statusCode === 404) {
967
+ console.log('Event not found');
968
+ }
969
+ }
970
+ ```
971
+
972
+ ---
973
+
974
+ ## Event Type / Status / Category Reference
975
+
976
+ ### Event Types (`eventType` parameter)
977
+
978
+ | Value | Description |
979
+ |-------|-------------|
980
+ | `ORCHESTRATION` | Trigger part or whole of a workflow |
981
+ | `ORCHESTRATION_AUDIT` | Audit of what happened during workflow execution |
982
+ | `API` | API interactions and system events |
983
+ | `INTEGRATION` | Integration-related events |
984
+ | `SECURITY` | Security events |
985
+ | `GENERAL` | General system events and notifications |
986
+
987
+ ### Event Statuses (`eventStatus` parameter)
988
+
989
+ | Value | Description |
990
+ |-------|-------------|
991
+ | `PENDING` | Event is pending processing |
992
+ | `SCHEDULED` | Event is scheduled for processing |
993
+ | `NO_MATCH` | No matching ruleset found for this event |
994
+ | `SUCCESS` | Event processed successfully |
995
+ | `FAILED` | Event processing failed |
996
+ | `COMPLETE` | Event completed |
997
+
998
+ ### Event Categories (`category` parameter)
999
+
1000
+ | Value | Description |
1001
+ |-------|-------------|
1002
+ | `snapshot` | State snapshots |
1003
+ | `ruleSet` | Ruleset execution events |
1004
+ | `rule` | Individual rule execution events |
1005
+ | `ACTION` | User/system actions |
1006
+ | `CUSTOM` | Custom log actions |
1007
+ | `exception` | Error/exception events |
1008
+ | `ORDER_WORKFLOW` | Order-specific workflow events |
1009
+ | `BATCH` | Batch processing events |
1010
+
1011
+ ### Root Entity Types (`context.rootEntityType` parameter)
1012
+
1013
+ | Value | Description |
1014
+ |-------|-------------|
1015
+ | `ORDER` | Customer orders |
1016
+ | `LOCATION` | Physical locations and warehouses |
1017
+ | `FULFILMENT_OPTIONS` | Fulfillment configuration |
1018
+ | `PRODUCT_CATALOGUE` | Product definitions and catalogs |
1019
+ | `INVENTORY_CATALOGUE` | Inventory management |
1020
+ | `VIRTUAL_CATALOGUE` | Virtual inventory positions |
1021
+ | `CONTROL_GROUP` | Control and governance |
1022
+ | `RETURN_ORDER` | Return processing |
1023
+ | `BILLING_ACCOUNT` | Billing and payments |
1024
+ | `JOB` | Background jobs and batch processes |
1025
+
1026
+ ### Entity Types (`context.entityType` parameter)
1027
+
1028
+ | Value | Description |
1029
+ |-------|-------------|
1030
+ | `ORDER` | Customer orders |
1031
+ | `FULFILMENT` | Fulfillment operations |
1032
+ | `ARTICLE` | Articles within fulfillments |
1033
+ | `CONSIGNMENT` | Shipping consignments |
1034
+ | `WAVE` | Wave picking operations |
1035
+ | `BATCH` | Batch processing |
1036
+ | `LOCATION` | Location operations |
1037
+ | `PRODUCT` | Product records |
1038
+ | `CATEGORY` | Product categories |
1039
+ | `INVENTORY_POSITION` | Inventory positions |
1040
+ | `INVENTORY_QUANTITY` | Inventory quantities |
1041
+ | `VIRTUAL_POSITION` | Virtual inventory positions |
1042
+ | `CONTROL` | Individual controls |
1043
+ | `RETURN_FULFILMENT` | Return processing |
1044
+ | `CREDIT_MEMO` | Financial adjustments |
1045
+
1046
+ ---
1047
+
1048
+ ## Common Use Cases
1049
+
1050
+ ### 1. Track Batch Ingestion Results
1051
+
1052
+ ```typescript
1053
+ // Find all events for a specific job
1054
+ const events = await client.getEvents({
1055
+ 'context.rootEntityType': 'JOB',
1056
+ 'context.rootEntityId': '13',
1057
+ eventType: 'ORCHESTRATION_AUDIT',
1058
+ count: 1000,
1059
+ });
1060
+
1061
+ console.log(`Found ${events.results.length} events`);
1062
+ for (const event of events.results) {
1063
+ console.log(` ${event.name} (${event.context?.entityType}) - ${event.eventStatus}`);
1064
+ }
1065
+ ```
1066
+
1067
+ ### 2. Find Failed Workflow Events
1068
+
1069
+ ```typescript
1070
+ const failed = await client.getEvents({
1071
+ eventStatus: 'FAILED',
1072
+ eventType: 'ORCHESTRATION_AUDIT',
1073
+ from: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
1074
+ to: new Date().toISOString(),
1075
+ count: 1000,
1076
+ });
1077
+
1078
+ for (const event of failed.results) {
1079
+ console.log(`FAILED: ${event.name} on ${event.context?.entityType}:${event.context?.entityRef}`);
1080
+ }
1081
+ ```
1082
+
1083
+ ### 3. Paginate Through Large Result Sets
1084
+
1085
+ ```typescript
1086
+ let start = 0;
1087
+ const pageSize = 1000;
1088
+ let allEvents: FluentEventLogItem[] = [];
1089
+
1090
+ let hasMore = true;
1091
+ while (hasMore) {
1092
+ const page = await client.getEvents({
1093
+ 'context.rootEntityType': 'ORDER',
1094
+ eventType: 'ORCHESTRATION_AUDIT',
1095
+ start,
1096
+ count: pageSize,
1097
+ });
1098
+
1099
+ allEvents.push(...page.results);
1100
+ hasMore = page.hasMore;
1101
+ start += page.count;
1102
+ }
1103
+
1104
+ console.log(`Total events: ${allEvents.length}`);
1105
+ ```
1106
+
1107
+ ### 4. Extract Performance Timing
1108
+
1109
+ ```typescript
1110
+ const events = await client.getEvents({
1111
+ category: 'ruleSet',
1112
+ eventType: 'ORCHESTRATION_AUDIT',
1113
+ from: '2026-02-01T00:00:00.000Z',
1114
+ to: '2026-02-15T00:00:00.000Z',
1115
+ count: 5000,
1116
+ });
1117
+
1118
+ for (const event of events.results) {
1119
+ if (Array.isArray(event.attributes)) {
1120
+ const startTimer = event.attributes.find(a => a.name === 'startTimer')?.value;
1121
+ const stopTimer = event.attributes.find(a => a.name === 'stopTimer')?.value;
1122
+ if (startTimer && stopTimer) {
1123
+ const duration = Number(stopTimer) - Number(startTimer);
1124
+ console.log(`${event.name}: ${duration}ms (${event.eventStatus})`);
1125
+ }
1126
+ }
1127
+ }
1128
+ ```
1129
+
1130
+ ### 5. API Time Range Limits
1131
+
1132
+ The Event API enforces time range constraints:
1133
+ - **`from`**: Must be within **4 months back** from current date
1134
+ - **`to`**: Must be within **1 month forward** from current date
1135
+ - **Default**: If `from` is not specified, searches the **past 30 days**
1136
+ - **Max `count`**: 5000 events per request (recommended to avoid timeouts)
1137
+ - **Date format**: `YYYY-MM-DDTHH:mm:ss.SSSZ` (UTC ISO string)
1138
+
1139
+ ```typescript
1140
+ // This will fail - too far in the past
1141
+ try {
1142
+ const tooOld = await client.getEvents({
1143
+ from: '2020-01-01T00:00:00.000Z', // More than 4 months ago
1144
+ });
1145
+ } catch (error) {
1146
+ // API Error: "'from' and 'to' must be within 4 months back and 1 months forward"
1147
+ }
1148
+ ```
1149
+
1150
+ ---
1151
+
692
1152
  ## Related Documentation
693
1153
 
694
1154
  - **Event API Guide**: [fc-connect-sdk/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md](../docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md)
@@ -697,6 +1157,6 @@ async function processBatch(products: Product[]): Promise<EventResult[]> {
697
1157
 
698
1158
  ---
699
1159
 
700
- **Generated from live test environment**: sagirish.test.api.fluentretail.com
701
- **SDK Version**: 0.1.46
702
- **Test Date**: 2025-01-19
1160
+ **Generated from live test environments**: sagirish.test.api.fluentretail.com, hmdev.sandbox.api.fluentretail.com
1161
+ **SDK Version**: 0.1.51
1162
+ **Last Updated**: 2026-02-15
@@ -310,6 +310,89 @@ const event = await client.sendEvent(
310
310
  );
311
311
  ```
312
312
 
313
+ #### getEvents Method
314
+
315
+ Search event logs and orchestration audit events using Event API filters.
316
+
317
+ ```typescript
318
+ async getEvents(params?: FluentEventQueryParams): Promise<FluentEventLogResponse>
319
+ ```
320
+
321
+ **Key Filters:**
322
+
323
+ - `eventType` - `ORCHESTRATION`, `ORCHESTRATION_AUDIT`, `API`, `GENERAL`
324
+ - `eventStatus` - `PENDING`, `SCHEDULED`, `SUCCESS`, `FAILED`, `COMPLETE`, `NO_MATCH`
325
+ - `context.rootEntityType`, `context.rootEntityId`, `context.rootEntityRef`
326
+ - `context.entityType`, `context.entityId`, `context.entityRef`
327
+ - `from`, `to`, `start`, `count`
328
+
329
+ **Example:**
330
+
331
+ ```typescript
332
+ const auditEvents = await client.getEvents({
333
+ 'context.rootEntityType': 'JOB',
334
+ eventType: 'ORCHESTRATION_AUDIT',
335
+ start: 1,
336
+ count: 1000,
337
+ });
338
+
339
+ console.log(auditEvents.hasMore);
340
+ console.log(auditEvents.results[0]?.name);
341
+ ```
342
+
343
+ **Response Shape:**
344
+
345
+ ```typescript
346
+ interface FluentEventLogResponse {
347
+ start: number;
348
+ count: number;
349
+ hasMore: boolean;
350
+ results: FluentEventLogItem[];
351
+ }
352
+ ```
353
+
354
+ **When to use `getEvents()`:**
355
+
356
+ - Investigate failed orchestration runs (`eventStatus: 'FAILED'`)
357
+ - Trace execution for jobs/orders/products using context filters
358
+ - Build operational dashboards and lightweight audit reports
359
+ - Find candidate event IDs before calling `getEventById()`
360
+
361
+ **Limitations / behavior notes:**
362
+
363
+ - Read-only API: does not trigger workflows or mutate entities
364
+ - `count` is capped by Fluent API (max `5000` per request)
365
+ - Time window constraints apply to `from`/`to` on the backend API
366
+ - Empty `results` for a valid query is normal and not treated as an error
367
+ - Use bounded time ranges and pagination (`start` + `count`) for large searches
368
+
369
+ #### getEventById Method
370
+
371
+ Fetch a single event by ID from Event API.
372
+
373
+ ```typescript
374
+ async getEventById(eventId: string): Promise<FluentEventLogItem>
375
+ ```
376
+
377
+ **Example:**
378
+
379
+ ```typescript
380
+ const event = await client.getEventById('e2cc5040-360b-43e9-b3c0-07bbc1934f82');
381
+ console.log(event.name, event.eventStatus);
382
+ ```
383
+
384
+ **When to use `getEventById()`:**
385
+
386
+ - Drill into a known event from logs, alerts, or trace tooling
387
+ - Inspect full context (`sourceEvents`, `entityRef`, `rootEntityRef`)
388
+ - Correlate parent/child orchestration events for root-cause analysis
389
+
390
+ **Limitations / behavior notes:**
391
+
392
+ - Requires a concrete event ID (it does not support filtering)
393
+ - Throws `FluentValidationError` for empty IDs
394
+ - Returns HTTP `404` (as `FluentAPIError`) when the event does not exist
395
+
313
396
  ### Job & Batch Operations
314
397
 
315
398
  #### createJob Method