@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.
- package/CHANGELOG.md +506 -379
- package/README.md +343 -0
- package/dist/cjs/clients/fluent-client.js +110 -14
- package/dist/cjs/data-sources/s3-data-source.js +1 -1
- package/dist/cjs/data-sources/sftp-data-source.js +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/services/extraction/extraction-orchestrator.d.ts +4 -1
- package/dist/cjs/services/extraction/extraction-orchestrator.js +84 -11
- package/dist/cjs/types/index.d.ts +79 -10
- package/dist/cjs/versori/fluent-versori-client.d.ts +4 -1
- package/dist/cjs/versori/fluent-versori-client.js +131 -13
- package/dist/esm/clients/fluent-client.js +110 -14
- package/dist/esm/data-sources/s3-data-source.js +1 -1
- package/dist/esm/data-sources/sftp-data-source.js +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/services/extraction/extraction-orchestrator.d.ts +4 -1
- package/dist/esm/services/extraction/extraction-orchestrator.js +84 -11
- package/dist/esm/types/index.d.ts +79 -10
- package/dist/esm/versori/fluent-versori-client.d.ts +4 -1
- package/dist/esm/versori/fluent-versori-client.js +131 -13
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/services/extraction/extraction-orchestrator.d.ts +4 -1
- package/dist/types/types/index.d.ts +79 -10
- package/dist/types/versori/fluent-versori-client.d.ts +4 -1
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +478 -18
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +83 -0
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +52 -0
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -0
- package/docs/02-CORE-GUIDES/api-reference/readme.md +1 -1
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +68 -4
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-01-foundations.md +450 -448
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-02-quick-start.md +476 -474
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-03-schema-validation.md +464 -462
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-05-advanced-patterns.md +1366 -1364
- package/docs/readme.md +245 -245
- package/package.json +17 -6
- package/docs/versori-apis/ACTIVATIONS-AND-VARIABLES-GUIDE.md +0 -60
- package/docs/versori-apis/JWT-GENERATION-GUIDE.md +0 -94
- package/docs/versori-apis/QUICK-WORKFLOW.md +0 -293
- package/docs/versori-apis/README.md +0 -73
- package/docs/versori-apis/VERSORI-PLATFORM-ARCHITECTURE.md +0 -880
- package/docs/versori-apis/Versori-Platform-API.postman_collection.json +0 -2925
- package/docs/versori-apis/Versori-Platform-API.postman_environment.example.json +0 -62
- 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. [
|
|
9
|
-
3. [
|
|
10
|
-
4. [
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
597
|
-
results.errors.push({ sku: record.sku,
|
|
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.
|
|
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
|
|
701
|
-
**SDK Version**: 0.1.
|
|
702
|
-
**
|
|
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
|