@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.56
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 +12 -0
- package/README.md +11 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,626 +1,626 @@
|
|
|
1
|
-
# Module 1: Introduction to Data Ingestion
|
|
2
|
-
|
|
3
|
-
[← Back to Ingestion Guide](../ingestion-readme.md)
|
|
4
|
-
|
|
5
|
-
**Module 1 of 9** | **Level**: Beginner | **Time**: 10 minutes
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
This module introduces data ingestion concepts, explains when to ingest data into Fluent Commerce, and covers the key features of the FC Connect SDK's ingestion system.
|
|
12
|
-
|
|
13
|
-
## Learning Objectives
|
|
14
|
-
|
|
15
|
-
By the end of this module, you will:
|
|
16
|
-
- ✅ Understand what data ingestion is and why it's important
|
|
17
|
-
- ✅ Know when to use the Batch API vs GraphQL mutations
|
|
18
|
-
- ✅ Understand the complete ingestion workflow
|
|
19
|
-
- ✅ Recognize the business use cases for inventory ingestion
|
|
20
|
-
- ✅ Understand the critical Batch API limitations
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## What is Data Ingestion?
|
|
25
|
-
|
|
26
|
-
**Data ingestion** is the process of importing data from external systems into Fluent Commerce. This typically involves:
|
|
27
|
-
|
|
28
|
-
1. **Reading** data from a source (S3, SFTP, API, database)
|
|
29
|
-
2. **Parsing** the data format (CSV, Parquet, XML, JSON)
|
|
30
|
-
3. **Transforming** the data to match Fluent's schema
|
|
31
|
-
4. **Validating** the transformed data
|
|
32
|
-
5. **Sending** the data to Fluent Commerce via Batch API or GraphQL mutations
|
|
33
|
-
6. **Tracking** the ingestion state to prevent duplicates
|
|
34
|
-
|
|
35
|
-
### Why is Ingestion Important?
|
|
36
|
-
|
|
37
|
-
Fluent Commerce acts as the central orchestration layer for order management and inventory. To maintain accurate data, it needs regular updates from:
|
|
38
|
-
|
|
39
|
-
- **Warehouse Management Systems (WMS)** - Real-time inventory levels
|
|
40
|
-
- **E-commerce Platforms** - Product catalogs, pricing, availability
|
|
41
|
-
- **ERP Systems** - Master data, locations, suppliers
|
|
42
|
-
- **3PL Partners** - External inventory positions
|
|
43
|
-
- **Data Lakes** - Historical data, analytics exports
|
|
44
|
-
|
|
45
|
-
Without reliable ingestion, Fluent Commerce cannot:
|
|
46
|
-
- Route orders to correct locations
|
|
47
|
-
- Provide accurate inventory availability
|
|
48
|
-
- Optimize fulfillment decisions
|
|
49
|
-
- Track inventory across the network
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## When to Use the Batch API
|
|
54
|
-
|
|
55
|
-
The Fluent Commerce **Batch API** is optimized for **bulk inventory updates** only.
|
|
56
|
-
|
|
57
|
-
### ✅ Use Batch API For:
|
|
58
|
-
|
|
59
|
-
| Use Case | Why Batch API? | Example |
|
|
60
|
-
|----------|----------------|---------|
|
|
61
|
-
| **Daily Inventory Sync** | Bulk updates, high volume | WMS → Fluent daily full sync |
|
|
62
|
-
| **Stock Adjustments** | Multiple positions at once | Cycle count results from warehouse |
|
|
63
|
-
| **Location Transfers** | Update source and destination | Move inventory between warehouses |
|
|
64
|
-
| **3PL Inventory Updates** | External partner data feeds | SFTP CSV from fulfillment partner |
|
|
65
|
-
|
|
66
|
-
### ❌ Do NOT Use Batch API For:
|
|
67
|
-
|
|
68
|
-
| Entity Type | Use Instead | Notes |
|
|
69
|
-
|-------------|-------------|-------|
|
|
70
|
-
| **Orders** | `createOrder` mutation | Batch API does NOT support orders |
|
|
71
|
-
| **Products** | `createProduct`, `updateProduct` | Batch API does NOT support products |
|
|
72
|
-
| **Locations** | Location-specific mutations | Batch API does NOT support locations |
|
|
73
|
-
| **Customers** | `createCustomer` mutation | Batch API does NOT support customers |
|
|
74
|
-
|
|
75
|
-
### Critical Batch API Limitations
|
|
76
|
-
|
|
77
|
-
The Batch API has **strict limitations**:
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// ✅ CORRECT - Batch API supports ONLY this combination
|
|
81
|
-
{
|
|
82
|
-
"entityType": "INVENTORY", // ✅ Only INVENTORY
|
|
83
|
-
"action": "UPSERT", // ✅ Only UPSERT action
|
|
84
|
-
"entities": [...] // ✅ Array of InventoryPositionInput
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ❌ WRONG - These are NOT supported
|
|
88
|
-
{
|
|
89
|
-
"entityType": "ORDER", // ❌ Orders not supported
|
|
90
|
-
"action": "CREATE" // ❌ CREATE action not supported
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Schema Reference:**
|
|
95
|
-
```json
|
|
96
|
-
// From docs/schema/fluent-commerce-schema.json
|
|
97
|
-
{
|
|
98
|
-
"enums": {
|
|
99
|
-
"EntityType": {
|
|
100
|
-
"values": ["INVENTORY"],
|
|
101
|
-
"note": "Batch API ONLY supports INVENTORY"
|
|
102
|
-
},
|
|
103
|
-
"BatchAction": {
|
|
104
|
-
"values": ["UPSERT"],
|
|
105
|
-
"note": "Batch API ONLY supports UPSERT action"
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Complete Ingestion Workflow
|
|
114
|
-
|
|
115
|
-
The SDK provides a **complete ingestion framework** that handles all stages:
|
|
116
|
-
|
|
117
|
-
```mermaid
|
|
118
|
-
graph TD
|
|
119
|
-
A[Data Source] --> B{File Already Processed?}
|
|
120
|
-
B -->|Yes| Z[Skip File]
|
|
121
|
-
B -->|No| C[Acquire Lock]
|
|
122
|
-
C --> D[Parse Data]
|
|
123
|
-
D --> E[Transform with UniversalMapper]
|
|
124
|
-
E --> F[Validate Schema]
|
|
125
|
-
F --> G[Create/Reuse Job]
|
|
126
|
-
G --> H[Send Batches]
|
|
127
|
-
H --> I[Monitor Status]
|
|
128
|
-
I --> J[Mark as Processed]
|
|
129
|
-
J --> K[Release Lock]
|
|
130
|
-
K --> L[Archive/Delete Source]
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Workflow Components
|
|
134
|
-
|
|
135
|
-
1. **Data Sources** - Where data comes from
|
|
136
|
-
- S3 buckets (most common)
|
|
137
|
-
- SFTP servers
|
|
138
|
-
- Local files (development)
|
|
139
|
-
- HTTP APIs
|
|
140
|
-
|
|
141
|
-
2. **Parsers** - Convert file formats to structured data
|
|
142
|
-
- CSV → Array of objects
|
|
143
|
-
- Parquet → Column-oriented records
|
|
144
|
-
- XML → Parsed object tree
|
|
145
|
-
- JSON → Native objects
|
|
146
|
-
|
|
147
|
-
3. **Field Mapper** - Transform source → Fluent schema
|
|
148
|
-
- `UniversalMapper` - Declarative field mapping
|
|
149
|
-
- SDK Resolvers - Built-in transformations (`sdk.parseInt`, `sdk.uppercase`, etc.)
|
|
150
|
-
- Custom Resolvers - Business logic transformations
|
|
151
|
-
|
|
152
|
-
4. **Validator** - Ensure data meets requirements
|
|
153
|
-
- Required fields present
|
|
154
|
-
- Correct data types
|
|
155
|
-
- Business rules (quantity >= 0, etc.)
|
|
156
|
-
|
|
157
|
-
5. **Job Manager** - Coordinate batch operations
|
|
158
|
-
- Job strategies (DAILY, PER_FILE, BATCHES_PER_JOB)
|
|
159
|
-
- Batch size optimization
|
|
160
|
-
- Retry logic for failed batches
|
|
161
|
-
|
|
162
|
-
6. **State Manager** - Prevent duplicate processing
|
|
163
|
-
- Track processed files
|
|
164
|
-
- Distributed locking
|
|
165
|
-
- Idempotent operations
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Business Use Cases
|
|
170
|
-
|
|
171
|
-
### Use Case 1: Daily Inventory Sync
|
|
172
|
-
|
|
173
|
-
**Scenario**: WMS exports full inventory snapshot to S3 daily at 2 AM.
|
|
174
|
-
|
|
175
|
-
**Requirements:**
|
|
176
|
-
- ✅ Process only new files (state management)
|
|
177
|
-
- ✅ Handle 50,000+ inventory positions
|
|
178
|
-
- ✅ Complete within 30 minutes
|
|
179
|
-
- ✅ Prevent duplicate processing
|
|
180
|
-
|
|
181
|
-
**Solution**: Building blocks composition with DAILY job reuse
|
|
182
|
-
```typescript
|
|
183
|
-
import {
|
|
184
|
-
createClient,
|
|
185
|
-
S3DataSource,
|
|
186
|
-
CSVParserService,
|
|
187
|
-
UniversalMapper,
|
|
188
|
-
StateService,
|
|
189
|
-
VersoriKVAdapter
|
|
190
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
191
|
-
|
|
192
|
-
// Initialize services
|
|
193
|
-
// In Versori: use ctx.log directly
|
|
194
|
-
// In standalone: use createConsoleLogger() or custom logger
|
|
195
|
-
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
196
|
-
service: 'inventory-ingestion',
|
|
197
|
-
correlationId: generateCorrelationId()
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
const stateService = new StateService(logger);
|
|
201
|
-
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
202
|
-
|
|
203
|
-
const client = await createClient({
|
|
204
|
-
config: {
|
|
205
|
-
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
206
|
-
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
207
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
208
|
-
username: process.env.FLUENT_USERNAME!, // Required for password grant
|
|
209
|
-
password: process.env.FLUENT_PASSWORD!, // Required for password grant
|
|
210
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const s3 = new S3DataSource(
|
|
215
|
-
{
|
|
216
|
-
type: 'S3_CSV',
|
|
217
|
-
connectionId: 's3-inventory',
|
|
218
|
-
name: 'S3 Inventory Source',
|
|
219
|
-
s3Config: {
|
|
220
|
-
bucket: 'inventory-bucket',
|
|
221
|
-
region: 'us-east-1',
|
|
222
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
223
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
logger
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
const parser = new CSVParserService(logger);
|
|
230
|
-
const mapper = new UniversalMapper({ fields: inventoryMapping.fields });
|
|
231
|
-
|
|
232
|
-
// Create daily job (reuse for all batches)
|
|
233
|
-
const job = await client.createJob({
|
|
234
|
-
name: 'Daily Inventory Sync',
|
|
235
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
// Process files with state management
|
|
239
|
-
const files = await s3.listFiles({ prefix: 'data/' });
|
|
240
|
-
|
|
241
|
-
for (const file of files) {
|
|
242
|
-
// Check if already processed
|
|
243
|
-
const fileKey = ['file', 'default', file.path];
|
|
244
|
-
const alreadyProcessed = await kvAdapter.get(fileKey);
|
|
245
|
-
|
|
246
|
-
if (alreadyProcessed) continue;
|
|
247
|
-
|
|
248
|
-
const content = await s3.downloadFile(file.path);
|
|
249
|
-
const records = await parser.parse(content as string);
|
|
250
|
-
const result = await mapper.map(records);
|
|
251
|
-
|
|
252
|
-
// Send in batches
|
|
253
|
-
for (let i = 0; i < result.data.length; i += 1000) {
|
|
254
|
-
const batch = result.data.slice(i, i + 1000);
|
|
255
|
-
await client.sendBatch(job.id, {
|
|
256
|
-
action: 'UPSERT',
|
|
257
|
-
entityType: 'INVENTORY',
|
|
258
|
-
source: 'S3_CSV_IMPORT',
|
|
259
|
-
event: 'INVENTORY_UPDATE',
|
|
260
|
-
entities: batch
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
await stateService.updateSyncState(kvAdapter, [{
|
|
265
|
-
fileName: file.path,
|
|
266
|
-
lastModified: new Date().toISOString(),
|
|
267
|
-
recordCount: result.data.length
|
|
268
|
-
}]);
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Use Case 2: Real-Time Stock Adjustments
|
|
273
|
-
|
|
274
|
-
**Scenario**: Warehouse performs cycle counts and sends SFTP files every hour.
|
|
275
|
-
|
|
276
|
-
**Requirements:**
|
|
277
|
-
- ✅ Process multiple files per day
|
|
278
|
-
- ✅ Each file is independent
|
|
279
|
-
- ✅ Track which files processed
|
|
280
|
-
- ✅ Handle network interruptions
|
|
281
|
-
|
|
282
|
-
**Solution**: Building blocks with PER_FILE job creation and state tracking
|
|
283
|
-
```typescript
|
|
284
|
-
import {
|
|
285
|
-
createClient,
|
|
286
|
-
SftpDataSource,
|
|
287
|
-
CSVParserService,
|
|
288
|
-
UniversalMapper,
|
|
289
|
-
StateService,
|
|
290
|
-
VersoriKVAdapter
|
|
291
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
292
|
-
|
|
293
|
-
// Initialize services
|
|
294
|
-
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
295
|
-
service: 'inventory-ingestion',
|
|
296
|
-
correlationId: generateCorrelationId()
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
const stateService = new StateService(logger);
|
|
300
|
-
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
301
|
-
|
|
302
|
-
const client = await createClient({
|
|
303
|
-
config: {
|
|
304
|
-
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
305
|
-
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
306
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
307
|
-
username: process.env.FLUENT_USERNAME!, // Required for password grant
|
|
308
|
-
password: process.env.FLUENT_PASSWORD!, // Required for password grant
|
|
309
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
const sftp = new SftpDataSource({
|
|
314
|
-
type: 'SFTP_CSV',
|
|
315
|
-
connectionId: 'sftp-warehouse',
|
|
316
|
-
name: 'Warehouse SFTP',
|
|
317
|
-
settings: {
|
|
318
|
-
host: 'sftp.warehouse.com',
|
|
319
|
-
port: 22,
|
|
320
|
-
username: process.env.SFTP_USERNAME!,
|
|
321
|
-
privateKey: process.env.SFTP_PRIVATE_KEY!,
|
|
322
|
-
remotePath: '/inventory/hourly',
|
|
323
|
-
filePattern: 'cycle_count_*.csv'
|
|
324
|
-
}
|
|
325
|
-
}, logger);
|
|
326
|
-
|
|
327
|
-
const parser = new CSVParserService(logger);
|
|
328
|
-
const mapper = new UniversalMapper({ fields: adjustmentMapping.fields });
|
|
329
|
-
|
|
330
|
-
// Process files - create new job for each file
|
|
331
|
-
const files = await sftp.listFiles({ filePattern: 'cycle_count_*.csv' });
|
|
332
|
-
|
|
333
|
-
for (const file of files) {
|
|
334
|
-
// Check if already processed
|
|
335
|
-
const fileKey = ['file', 'default', file.path];
|
|
336
|
-
const alreadyProcessed = await kvAdapter.get(fileKey);
|
|
337
|
-
|
|
338
|
-
if (alreadyProcessed) continue;
|
|
339
|
-
|
|
340
|
-
try {
|
|
341
|
-
const content = await sftp.downloadFile(file.path);
|
|
342
|
-
const records = await parser.parse(content as string);
|
|
343
|
-
const result = await mapper.map(records);
|
|
344
|
-
|
|
345
|
-
// Create new job for this file (PER_FILE strategy)
|
|
346
|
-
const job = await client.createJob({
|
|
347
|
-
name: `Cycle Count - ${file.path}`,
|
|
348
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
// Send in batches of 500
|
|
352
|
-
for (let i = 0; i < result.data.length; i += 500) {
|
|
353
|
-
const batch = result.data.slice(i, i + 500);
|
|
354
|
-
await client.sendBatch(job.id, {
|
|
355
|
-
action: 'UPSERT',
|
|
356
|
-
entityType: 'INVENTORY',
|
|
357
|
-
source: 'SFTP_CSV_IMPORT',
|
|
358
|
-
event: 'CYCLE_COUNT_UPDATE',
|
|
359
|
-
entities: batch
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
await stateService.updateSyncState(kvAdapter, [{
|
|
364
|
-
fileName: file.path,
|
|
365
|
-
lastModified: new Date().toISOString(),
|
|
366
|
-
recordCount: result.data.length
|
|
367
|
-
}]);
|
|
368
|
-
} catch (error) {
|
|
369
|
-
console.error(`Failed to process ${file.path}`, error);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### Use Case 3: 3PL Partner Inventory
|
|
375
|
-
|
|
376
|
-
**Scenario**: Third-party logistics partner sends inventory feeds via SFTP twice daily.
|
|
377
|
-
|
|
378
|
-
**Requirements:**
|
|
379
|
-
- ✅ Validate partner data format
|
|
380
|
-
- ✅ Enrich with location mapping
|
|
381
|
-
- ✅ Handle missing/invalid records
|
|
382
|
-
- ✅ Audit trail for compliance
|
|
383
|
-
|
|
384
|
-
**Solution**: Custom resolvers with validation
|
|
385
|
-
```typescript
|
|
386
|
-
const mapper = new UniversalMapper({
|
|
387
|
-
fields: {
|
|
388
|
-
ref: { source: 'partner_sku', required: true },
|
|
389
|
-
productRef: { source: 'partner_sku', required: true },
|
|
390
|
-
locationRef: {
|
|
391
|
-
source: 'partner_location_code',
|
|
392
|
-
resolver: 'custom.mapPartnerLocation', // ✅ Custom business logic
|
|
393
|
-
required: true
|
|
394
|
-
},
|
|
395
|
-
qty: {
|
|
396
|
-
source: 'available_quantity',
|
|
397
|
-
resolver: 'sdk.parseInt',
|
|
398
|
-
required: true,
|
|
399
|
-
validation: (value) => value >= 0 // ✅ Business rule
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}, {
|
|
403
|
-
customResolvers: {
|
|
404
|
-
'custom.mapPartnerLocation': (value, sourceData, config, helpers) => {
|
|
405
|
-
const mapping = {
|
|
406
|
-
'P1': 'WH-PARTNER-EAST',
|
|
407
|
-
'P2': 'WH-PARTNER-WEST'
|
|
408
|
-
};
|
|
409
|
-
const mapped = mapping[value];
|
|
410
|
-
if (!mapped) {
|
|
411
|
-
throw new Error(`Unknown partner location: ${value}`);
|
|
412
|
-
}
|
|
413
|
-
return mapped;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
});
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## Key Ingestion Features
|
|
422
|
-
|
|
423
|
-
### 1. Format Flexibility
|
|
424
|
-
|
|
425
|
-
The SDK supports **multiple input formats** with the same workflow:
|
|
426
|
-
|
|
427
|
-
| Format | Parser | Use Case |
|
|
428
|
-
|--------|--------|----------|
|
|
429
|
-
| CSV | `CSVParserService` | Most common - simple, human-readable |
|
|
430
|
-
| Parquet | `ParquetParserService` | Large datasets - columnar, compressed |
|
|
431
|
-
| XML | `XMLParserService` | Enterprise systems - SFCC, SAP, Magento |
|
|
432
|
-
| JSON | `JSONParserService` | APIs, webhooks, modern systems |
|
|
433
|
-
|
|
434
|
-
### 2. State Management
|
|
435
|
-
|
|
436
|
-
**Problem**: Without state management, reprocessing files creates duplicates.
|
|
437
|
-
|
|
438
|
-
**Solution**: `StateService` tracks processed files with distributed locking:
|
|
439
|
-
|
|
440
|
-
```typescript
|
|
441
|
-
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
442
|
-
service: 'inventory-ingestion',
|
|
443
|
-
correlationId: generateCorrelationId()
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
const stateService = new StateService(logger);
|
|
447
|
-
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
448
|
-
|
|
449
|
-
// Check if file already processed
|
|
450
|
-
if (await stateService.isFileProcessed(kvAdapter, 'file.csv')) {
|
|
451
|
-
logger.info('File already processed, skipping');
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// Acquire lock for concurrent safety
|
|
456
|
-
const lockAcquired = await stateService.acquireLock('ingestion-lock', kvAdapter, 15);
|
|
457
|
-
if (!lockAcquired) {
|
|
458
|
-
logger.info('File locked by another process');
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
try {
|
|
463
|
-
// Process file
|
|
464
|
-
await processFile('file.csv');
|
|
465
|
-
|
|
466
|
-
// Mark as processed
|
|
467
|
-
await stateService.updateSyncState(kvAdapter, [{
|
|
468
|
-
fileName: 'file.csv',
|
|
469
|
-
lastModified: new Date().toISOString(),
|
|
470
|
-
recordCount: recordCount
|
|
471
|
-
}]);
|
|
472
|
-
} finally {
|
|
473
|
-
await stateService.releaseLock('ingestion-lock', kvAdapter);
|
|
474
|
-
}
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
### 3. Performance Optimization
|
|
478
|
-
|
|
479
|
-
**Batch Size Optimization**: Automatically calculate optimal batch size based on data:
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
function calculateOptimalBatchSize(
|
|
483
|
-
totalRecords: number,
|
|
484
|
-
avgRecordSize: number
|
|
485
|
-
): number {
|
|
486
|
-
const MAX_BATCH_SIZE = 10000;
|
|
487
|
-
const MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB
|
|
488
|
-
|
|
489
|
-
const recordsPerPayload = Math.floor(MAX_PAYLOAD_SIZE / avgRecordSize);
|
|
490
|
-
return Math.min(recordsPerPayload, MAX_BATCH_SIZE);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const batchSize = calculateOptimalBatchSize(50000, 200);
|
|
494
|
-
// Result: Optimal size based on record size and payload limits
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
**Parallel Processing**: Process multiple files/batches with configurable strategies:
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
import { createClient, S3DataSource, CSVParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
501
|
-
|
|
502
|
-
// Initialize services
|
|
503
|
-
const client = await createClient({ config });
|
|
504
|
-
const s3 = new S3DataSource(
|
|
505
|
-
{
|
|
506
|
-
type: 'S3_CSV',
|
|
507
|
-
connectionId: 's3-inventory',
|
|
508
|
-
name: 'S3 Inventory',
|
|
509
|
-
s3Config: s3Config,
|
|
510
|
-
},
|
|
511
|
-
logger
|
|
512
|
-
);
|
|
513
|
-
const parser = new CSVParserService();
|
|
514
|
-
const mapper = new UniversalMapper(mappingConfig);
|
|
515
|
-
|
|
516
|
-
// Create daily job (reuse for all batches)
|
|
517
|
-
const job = await client.createJob({
|
|
518
|
-
name: 'Daily Inventory Sync',
|
|
519
|
-
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
// Process multiple files
|
|
523
|
-
const files = await s3.listFiles({ prefix: 'data/', maxKeys: 10 });
|
|
524
|
-
|
|
525
|
-
for (const file of files) {
|
|
526
|
-
const content = await s3.downloadFile(file.path);
|
|
527
|
-
const records = await parser.parse(content as string);
|
|
528
|
-
const result = await mapper.map(records);
|
|
529
|
-
|
|
530
|
-
// Send in batches of 1000
|
|
531
|
-
for (let i = 0; i < result.data.length; i += 1000) {
|
|
532
|
-
const batch = result.data.slice(i, i + 1000);
|
|
533
|
-
await client.sendBatch(job.id, {
|
|
534
|
-
action: 'UPSERT',
|
|
535
|
-
entityType: 'INVENTORY',
|
|
536
|
-
entities: batch
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### 4. Error Handling
|
|
543
|
-
|
|
544
|
-
**Fail-Fast with Recovery**: Stop on critical errors, retry transient failures:
|
|
545
|
-
|
|
546
|
-
```typescript
|
|
547
|
-
class RetryableIngestion {
|
|
548
|
-
async executeWithRetry<T>(
|
|
549
|
-
operation: () => Promise<T>,
|
|
550
|
-
context: string
|
|
551
|
-
): Promise<T> {
|
|
552
|
-
let lastError: Error;
|
|
553
|
-
let delay = 1000;
|
|
554
|
-
|
|
555
|
-
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
556
|
-
try {
|
|
557
|
-
return await operation();
|
|
558
|
-
} catch (error) {
|
|
559
|
-
lastError = error;
|
|
560
|
-
|
|
561
|
-
// Retry network errors, fail on validation errors
|
|
562
|
-
if (!this.isRetryable(error)) {
|
|
563
|
-
throw error; // ✅ Fail fast on validation errors
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
console.log(`Retry ${attempt}/3 for ${context}`);
|
|
567
|
-
await this.sleep(delay);
|
|
568
|
-
delay *= 2; // Exponential backoff
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
throw new Error(`Failed after 3 retries: ${lastError.message}`);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
private isRetryable(error: any): boolean {
|
|
576
|
-
return error.code === 'NETWORK_ERROR' ||
|
|
577
|
-
error.code === 'TIMEOUT_ERROR' ||
|
|
578
|
-
error.code === 'RATE_LIMIT_ERROR';
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
---
|
|
584
|
-
|
|
585
|
-
## Ingestion vs Extraction
|
|
586
|
-
|
|
587
|
-
The SDK provides **two complementary workflows**:
|
|
588
|
-
|
|
589
|
-
| Aspect | Ingestion (this guide) | Extraction |
|
|
590
|
-
|--------|------------------------|-----------|
|
|
591
|
-
| **Direction** | External → Fluent Commerce | Fluent Commerce → External |
|
|
592
|
-
| **Primary API** | Batch API (UPSERT) | GraphQL Queries |
|
|
593
|
-
| **Use Case** | Update inventory positions | Export data for analytics/BI |
|
|
594
|
-
| **Data Source** | S3, SFTP, files | Fluent Commerce GraphQL API |
|
|
595
|
-
| **Data Destination** | Fluent Commerce | S3, SFTP, files, databases |
|
|
596
|
-
| **Typical Frequency** | Hourly, daily | Daily, weekly, on-demand |
|
|
597
|
-
| **State Management** | Prevent duplicate ingestion | Track extraction checkpoints |
|
|
598
|
-
|
|
599
|
-
**See Also**: [Data Extraction Guide](../../extraction/) for the reverse workflow.
|
|
600
|
-
|
|
601
|
-
---
|
|
602
|
-
|
|
603
|
-
## Key Takeaways
|
|
604
|
-
|
|
605
|
-
- 🎯 **Batch API is for inventory only** - Use GraphQL mutations for orders, products, locations
|
|
606
|
-
- 🎯 **State management prevents duplicates** - Essential for production workflows
|
|
607
|
-
- 🎯 **UniversalMapper transforms data** - Declarative field mapping with validation
|
|
608
|
-
- 🎯 **Job strategies optimize performance** - DAILY for frequent updates, PER_FILE for large datasets
|
|
609
|
-
- 🎯 **Error handling is critical** - Implement retry logic and fail-fast validation
|
|
610
|
-
|
|
611
|
-
---
|
|
612
|
-
|
|
613
|
-
## Next Steps
|
|
614
|
-
|
|
615
|
-
Continue to [Module 2: Quick Start](../../auto-pagination/modules/auto-pagination-02-quick-start.md) to build your first ingestion workflow with a complete working example.
|
|
616
|
-
|
|
617
|
-
---
|
|
618
|
-
|
|
619
|
-
[← Previous: Main Guide](../ingestion-readme.md) | [Back to Guide](../ingestion-readme.md) | [Next: Quick Start →](../../auto-pagination/modules/auto-pagination-02-quick-start.md)
|
|
620
|
-
|
|
621
|
-
## Related Documentation
|
|
622
|
-
|
|
623
|
-
- [Batch API Reference](../../api-reference/modules/api-reference-01-client-api.md#job-batch-operations) - Complete API documentation
|
|
624
|
-
- [Universal Mapping Guide](../../mapping/mapping-readme.md) - Field transformation patterns
|
|
625
|
-
- [State Management](./02-core-guides-ingestion-07-state-management.md) - Duplicate prevention in detail
|
|
626
|
-
- [Orchestrators Guide](../../extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md) - High-level workflow coordination
|
|
1
|
+
# Module 1: Introduction to Data Ingestion
|
|
2
|
+
|
|
3
|
+
[← Back to Ingestion Guide](../ingestion-readme.md)
|
|
4
|
+
|
|
5
|
+
**Module 1 of 9** | **Level**: Beginner | **Time**: 10 minutes
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This module introduces data ingestion concepts, explains when to ingest data into Fluent Commerce, and covers the key features of the FC Connect SDK's ingestion system.
|
|
12
|
+
|
|
13
|
+
## Learning Objectives
|
|
14
|
+
|
|
15
|
+
By the end of this module, you will:
|
|
16
|
+
- ✅ Understand what data ingestion is and why it's important
|
|
17
|
+
- ✅ Know when to use the Batch API vs GraphQL mutations
|
|
18
|
+
- ✅ Understand the complete ingestion workflow
|
|
19
|
+
- ✅ Recognize the business use cases for inventory ingestion
|
|
20
|
+
- ✅ Understand the critical Batch API limitations
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What is Data Ingestion?
|
|
25
|
+
|
|
26
|
+
**Data ingestion** is the process of importing data from external systems into Fluent Commerce. This typically involves:
|
|
27
|
+
|
|
28
|
+
1. **Reading** data from a source (S3, SFTP, API, database)
|
|
29
|
+
2. **Parsing** the data format (CSV, Parquet, XML, JSON)
|
|
30
|
+
3. **Transforming** the data to match Fluent's schema
|
|
31
|
+
4. **Validating** the transformed data
|
|
32
|
+
5. **Sending** the data to Fluent Commerce via Batch API or GraphQL mutations
|
|
33
|
+
6. **Tracking** the ingestion state to prevent duplicates
|
|
34
|
+
|
|
35
|
+
### Why is Ingestion Important?
|
|
36
|
+
|
|
37
|
+
Fluent Commerce acts as the central orchestration layer for order management and inventory. To maintain accurate data, it needs regular updates from:
|
|
38
|
+
|
|
39
|
+
- **Warehouse Management Systems (WMS)** - Real-time inventory levels
|
|
40
|
+
- **E-commerce Platforms** - Product catalogs, pricing, availability
|
|
41
|
+
- **ERP Systems** - Master data, locations, suppliers
|
|
42
|
+
- **3PL Partners** - External inventory positions
|
|
43
|
+
- **Data Lakes** - Historical data, analytics exports
|
|
44
|
+
|
|
45
|
+
Without reliable ingestion, Fluent Commerce cannot:
|
|
46
|
+
- Route orders to correct locations
|
|
47
|
+
- Provide accurate inventory availability
|
|
48
|
+
- Optimize fulfillment decisions
|
|
49
|
+
- Track inventory across the network
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## When to Use the Batch API
|
|
54
|
+
|
|
55
|
+
The Fluent Commerce **Batch API** is optimized for **bulk inventory updates** only.
|
|
56
|
+
|
|
57
|
+
### ✅ Use Batch API For:
|
|
58
|
+
|
|
59
|
+
| Use Case | Why Batch API? | Example |
|
|
60
|
+
|----------|----------------|---------|
|
|
61
|
+
| **Daily Inventory Sync** | Bulk updates, high volume | WMS → Fluent daily full sync |
|
|
62
|
+
| **Stock Adjustments** | Multiple positions at once | Cycle count results from warehouse |
|
|
63
|
+
| **Location Transfers** | Update source and destination | Move inventory between warehouses |
|
|
64
|
+
| **3PL Inventory Updates** | External partner data feeds | SFTP CSV from fulfillment partner |
|
|
65
|
+
|
|
66
|
+
### ❌ Do NOT Use Batch API For:
|
|
67
|
+
|
|
68
|
+
| Entity Type | Use Instead | Notes |
|
|
69
|
+
|-------------|-------------|-------|
|
|
70
|
+
| **Orders** | `createOrder` mutation | Batch API does NOT support orders |
|
|
71
|
+
| **Products** | `createProduct`, `updateProduct` | Batch API does NOT support products |
|
|
72
|
+
| **Locations** | Location-specific mutations | Batch API does NOT support locations |
|
|
73
|
+
| **Customers** | `createCustomer` mutation | Batch API does NOT support customers |
|
|
74
|
+
|
|
75
|
+
### Critical Batch API Limitations
|
|
76
|
+
|
|
77
|
+
The Batch API has **strict limitations**:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// ✅ CORRECT - Batch API supports ONLY this combination
|
|
81
|
+
{
|
|
82
|
+
"entityType": "INVENTORY", // ✅ Only INVENTORY
|
|
83
|
+
"action": "UPSERT", // ✅ Only UPSERT action
|
|
84
|
+
"entities": [...] // ✅ Array of InventoryPositionInput
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ❌ WRONG - These are NOT supported
|
|
88
|
+
{
|
|
89
|
+
"entityType": "ORDER", // ❌ Orders not supported
|
|
90
|
+
"action": "CREATE" // ❌ CREATE action not supported
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Schema Reference:**
|
|
95
|
+
```json
|
|
96
|
+
// From docs/schema/fluent-commerce-schema.json
|
|
97
|
+
{
|
|
98
|
+
"enums": {
|
|
99
|
+
"EntityType": {
|
|
100
|
+
"values": ["INVENTORY"],
|
|
101
|
+
"note": "Batch API ONLY supports INVENTORY"
|
|
102
|
+
},
|
|
103
|
+
"BatchAction": {
|
|
104
|
+
"values": ["UPSERT"],
|
|
105
|
+
"note": "Batch API ONLY supports UPSERT action"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Complete Ingestion Workflow
|
|
114
|
+
|
|
115
|
+
The SDK provides a **complete ingestion framework** that handles all stages:
|
|
116
|
+
|
|
117
|
+
```mermaid
|
|
118
|
+
graph TD
|
|
119
|
+
A[Data Source] --> B{File Already Processed?}
|
|
120
|
+
B -->|Yes| Z[Skip File]
|
|
121
|
+
B -->|No| C[Acquire Lock]
|
|
122
|
+
C --> D[Parse Data]
|
|
123
|
+
D --> E[Transform with UniversalMapper]
|
|
124
|
+
E --> F[Validate Schema]
|
|
125
|
+
F --> G[Create/Reuse Job]
|
|
126
|
+
G --> H[Send Batches]
|
|
127
|
+
H --> I[Monitor Status]
|
|
128
|
+
I --> J[Mark as Processed]
|
|
129
|
+
J --> K[Release Lock]
|
|
130
|
+
K --> L[Archive/Delete Source]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Workflow Components
|
|
134
|
+
|
|
135
|
+
1. **Data Sources** - Where data comes from
|
|
136
|
+
- S3 buckets (most common)
|
|
137
|
+
- SFTP servers
|
|
138
|
+
- Local files (development)
|
|
139
|
+
- HTTP APIs
|
|
140
|
+
|
|
141
|
+
2. **Parsers** - Convert file formats to structured data
|
|
142
|
+
- CSV → Array of objects
|
|
143
|
+
- Parquet → Column-oriented records
|
|
144
|
+
- XML → Parsed object tree
|
|
145
|
+
- JSON → Native objects
|
|
146
|
+
|
|
147
|
+
3. **Field Mapper** - Transform source → Fluent schema
|
|
148
|
+
- `UniversalMapper` - Declarative field mapping
|
|
149
|
+
- SDK Resolvers - Built-in transformations (`sdk.parseInt`, `sdk.uppercase`, etc.)
|
|
150
|
+
- Custom Resolvers - Business logic transformations
|
|
151
|
+
|
|
152
|
+
4. **Validator** - Ensure data meets requirements
|
|
153
|
+
- Required fields present
|
|
154
|
+
- Correct data types
|
|
155
|
+
- Business rules (quantity >= 0, etc.)
|
|
156
|
+
|
|
157
|
+
5. **Job Manager** - Coordinate batch operations
|
|
158
|
+
- Job strategies (DAILY, PER_FILE, BATCHES_PER_JOB)
|
|
159
|
+
- Batch size optimization
|
|
160
|
+
- Retry logic for failed batches
|
|
161
|
+
|
|
162
|
+
6. **State Manager** - Prevent duplicate processing
|
|
163
|
+
- Track processed files
|
|
164
|
+
- Distributed locking
|
|
165
|
+
- Idempotent operations
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Business Use Cases
|
|
170
|
+
|
|
171
|
+
### Use Case 1: Daily Inventory Sync
|
|
172
|
+
|
|
173
|
+
**Scenario**: WMS exports full inventory snapshot to S3 daily at 2 AM.
|
|
174
|
+
|
|
175
|
+
**Requirements:**
|
|
176
|
+
- ✅ Process only new files (state management)
|
|
177
|
+
- ✅ Handle 50,000+ inventory positions
|
|
178
|
+
- ✅ Complete within 30 minutes
|
|
179
|
+
- ✅ Prevent duplicate processing
|
|
180
|
+
|
|
181
|
+
**Solution**: Building blocks composition with DAILY job reuse
|
|
182
|
+
```typescript
|
|
183
|
+
import {
|
|
184
|
+
createClient,
|
|
185
|
+
S3DataSource,
|
|
186
|
+
CSVParserService,
|
|
187
|
+
UniversalMapper,
|
|
188
|
+
StateService,
|
|
189
|
+
VersoriKVAdapter
|
|
190
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
191
|
+
|
|
192
|
+
// Initialize services
|
|
193
|
+
// In Versori: use ctx.log directly
|
|
194
|
+
// In standalone: use createConsoleLogger() or custom logger
|
|
195
|
+
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
196
|
+
service: 'inventory-ingestion',
|
|
197
|
+
correlationId: generateCorrelationId()
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const stateService = new StateService(logger);
|
|
201
|
+
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
202
|
+
|
|
203
|
+
const client = await createClient({
|
|
204
|
+
config: {
|
|
205
|
+
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
206
|
+
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
207
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
208
|
+
username: process.env.FLUENT_USERNAME!, // Required for password grant
|
|
209
|
+
password: process.env.FLUENT_PASSWORD!, // Required for password grant
|
|
210
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const s3 = new S3DataSource(
|
|
215
|
+
{
|
|
216
|
+
type: 'S3_CSV',
|
|
217
|
+
connectionId: 's3-inventory',
|
|
218
|
+
name: 'S3 Inventory Source',
|
|
219
|
+
s3Config: {
|
|
220
|
+
bucket: 'inventory-bucket',
|
|
221
|
+
region: 'us-east-1',
|
|
222
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
223
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
logger
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const parser = new CSVParserService(logger);
|
|
230
|
+
const mapper = new UniversalMapper({ fields: inventoryMapping.fields });
|
|
231
|
+
|
|
232
|
+
// Create daily job (reuse for all batches)
|
|
233
|
+
const job = await client.createJob({
|
|
234
|
+
name: 'Daily Inventory Sync',
|
|
235
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Process files with state management
|
|
239
|
+
const files = await s3.listFiles({ prefix: 'data/' });
|
|
240
|
+
|
|
241
|
+
for (const file of files) {
|
|
242
|
+
// Check if already processed
|
|
243
|
+
const fileKey = ['file', 'default', file.path];
|
|
244
|
+
const alreadyProcessed = await kvAdapter.get(fileKey);
|
|
245
|
+
|
|
246
|
+
if (alreadyProcessed) continue;
|
|
247
|
+
|
|
248
|
+
const content = await s3.downloadFile(file.path);
|
|
249
|
+
const records = await parser.parse(content as string);
|
|
250
|
+
const result = await mapper.map(records);
|
|
251
|
+
|
|
252
|
+
// Send in batches
|
|
253
|
+
for (let i = 0; i < result.data.length; i += 1000) {
|
|
254
|
+
const batch = result.data.slice(i, i + 1000);
|
|
255
|
+
await client.sendBatch(job.id, {
|
|
256
|
+
action: 'UPSERT',
|
|
257
|
+
entityType: 'INVENTORY',
|
|
258
|
+
source: 'S3_CSV_IMPORT',
|
|
259
|
+
event: 'INVENTORY_UPDATE',
|
|
260
|
+
entities: batch
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
await stateService.updateSyncState(kvAdapter, [{
|
|
265
|
+
fileName: file.path,
|
|
266
|
+
lastModified: new Date().toISOString(),
|
|
267
|
+
recordCount: result.data.length
|
|
268
|
+
}]);
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Use Case 2: Real-Time Stock Adjustments
|
|
273
|
+
|
|
274
|
+
**Scenario**: Warehouse performs cycle counts and sends SFTP files every hour.
|
|
275
|
+
|
|
276
|
+
**Requirements:**
|
|
277
|
+
- ✅ Process multiple files per day
|
|
278
|
+
- ✅ Each file is independent
|
|
279
|
+
- ✅ Track which files processed
|
|
280
|
+
- ✅ Handle network interruptions
|
|
281
|
+
|
|
282
|
+
**Solution**: Building blocks with PER_FILE job creation and state tracking
|
|
283
|
+
```typescript
|
|
284
|
+
import {
|
|
285
|
+
createClient,
|
|
286
|
+
SftpDataSource,
|
|
287
|
+
CSVParserService,
|
|
288
|
+
UniversalMapper,
|
|
289
|
+
StateService,
|
|
290
|
+
VersoriKVAdapter
|
|
291
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
292
|
+
|
|
293
|
+
// Initialize services
|
|
294
|
+
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
295
|
+
service: 'inventory-ingestion',
|
|
296
|
+
correlationId: generateCorrelationId()
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
const stateService = new StateService(logger);
|
|
300
|
+
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
301
|
+
|
|
302
|
+
const client = await createClient({
|
|
303
|
+
config: {
|
|
304
|
+
baseUrl: process.env.FLUENT_BASE_URL!,
|
|
305
|
+
clientId: process.env.FLUENT_CLIENT_ID!,
|
|
306
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET!,
|
|
307
|
+
username: process.env.FLUENT_USERNAME!, // Required for password grant
|
|
308
|
+
password: process.env.FLUENT_PASSWORD!, // Required for password grant
|
|
309
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const sftp = new SftpDataSource({
|
|
314
|
+
type: 'SFTP_CSV',
|
|
315
|
+
connectionId: 'sftp-warehouse',
|
|
316
|
+
name: 'Warehouse SFTP',
|
|
317
|
+
settings: {
|
|
318
|
+
host: 'sftp.warehouse.com',
|
|
319
|
+
port: 22,
|
|
320
|
+
username: process.env.SFTP_USERNAME!,
|
|
321
|
+
privateKey: process.env.SFTP_PRIVATE_KEY!,
|
|
322
|
+
remotePath: '/inventory/hourly',
|
|
323
|
+
filePattern: 'cycle_count_*.csv'
|
|
324
|
+
}
|
|
325
|
+
}, logger);
|
|
326
|
+
|
|
327
|
+
const parser = new CSVParserService(logger);
|
|
328
|
+
const mapper = new UniversalMapper({ fields: adjustmentMapping.fields });
|
|
329
|
+
|
|
330
|
+
// Process files - create new job for each file
|
|
331
|
+
const files = await sftp.listFiles({ filePattern: 'cycle_count_*.csv' });
|
|
332
|
+
|
|
333
|
+
for (const file of files) {
|
|
334
|
+
// Check if already processed
|
|
335
|
+
const fileKey = ['file', 'default', file.path];
|
|
336
|
+
const alreadyProcessed = await kvAdapter.get(fileKey);
|
|
337
|
+
|
|
338
|
+
if (alreadyProcessed) continue;
|
|
339
|
+
|
|
340
|
+
try {
|
|
341
|
+
const content = await sftp.downloadFile(file.path);
|
|
342
|
+
const records = await parser.parse(content as string);
|
|
343
|
+
const result = await mapper.map(records);
|
|
344
|
+
|
|
345
|
+
// Create new job for this file (PER_FILE strategy)
|
|
346
|
+
const job = await client.createJob({
|
|
347
|
+
name: `Cycle Count - ${file.path}`,
|
|
348
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Send in batches of 500
|
|
352
|
+
for (let i = 0; i < result.data.length; i += 500) {
|
|
353
|
+
const batch = result.data.slice(i, i + 500);
|
|
354
|
+
await client.sendBatch(job.id, {
|
|
355
|
+
action: 'UPSERT',
|
|
356
|
+
entityType: 'INVENTORY',
|
|
357
|
+
source: 'SFTP_CSV_IMPORT',
|
|
358
|
+
event: 'CYCLE_COUNT_UPDATE',
|
|
359
|
+
entities: batch
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
await stateService.updateSyncState(kvAdapter, [{
|
|
364
|
+
fileName: file.path,
|
|
365
|
+
lastModified: new Date().toISOString(),
|
|
366
|
+
recordCount: result.data.length
|
|
367
|
+
}]);
|
|
368
|
+
} catch (error) {
|
|
369
|
+
console.error(`Failed to process ${file.path}`, error);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Use Case 3: 3PL Partner Inventory
|
|
375
|
+
|
|
376
|
+
**Scenario**: Third-party logistics partner sends inventory feeds via SFTP twice daily.
|
|
377
|
+
|
|
378
|
+
**Requirements:**
|
|
379
|
+
- ✅ Validate partner data format
|
|
380
|
+
- ✅ Enrich with location mapping
|
|
381
|
+
- ✅ Handle missing/invalid records
|
|
382
|
+
- ✅ Audit trail for compliance
|
|
383
|
+
|
|
384
|
+
**Solution**: Custom resolvers with validation
|
|
385
|
+
```typescript
|
|
386
|
+
const mapper = new UniversalMapper({
|
|
387
|
+
fields: {
|
|
388
|
+
ref: { source: 'partner_sku', required: true },
|
|
389
|
+
productRef: { source: 'partner_sku', required: true },
|
|
390
|
+
locationRef: {
|
|
391
|
+
source: 'partner_location_code',
|
|
392
|
+
resolver: 'custom.mapPartnerLocation', // ✅ Custom business logic
|
|
393
|
+
required: true
|
|
394
|
+
},
|
|
395
|
+
qty: {
|
|
396
|
+
source: 'available_quantity',
|
|
397
|
+
resolver: 'sdk.parseInt',
|
|
398
|
+
required: true,
|
|
399
|
+
validation: (value) => value >= 0 // ✅ Business rule
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}, {
|
|
403
|
+
customResolvers: {
|
|
404
|
+
'custom.mapPartnerLocation': (value, sourceData, config, helpers) => {
|
|
405
|
+
const mapping = {
|
|
406
|
+
'P1': 'WH-PARTNER-EAST',
|
|
407
|
+
'P2': 'WH-PARTNER-WEST'
|
|
408
|
+
};
|
|
409
|
+
const mapped = mapping[value];
|
|
410
|
+
if (!mapped) {
|
|
411
|
+
throw new Error(`Unknown partner location: ${value}`);
|
|
412
|
+
}
|
|
413
|
+
return mapped;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Key Ingestion Features
|
|
422
|
+
|
|
423
|
+
### 1. Format Flexibility
|
|
424
|
+
|
|
425
|
+
The SDK supports **multiple input formats** with the same workflow:
|
|
426
|
+
|
|
427
|
+
| Format | Parser | Use Case |
|
|
428
|
+
|--------|--------|----------|
|
|
429
|
+
| CSV | `CSVParserService` | Most common - simple, human-readable |
|
|
430
|
+
| Parquet | `ParquetParserService` | Large datasets - columnar, compressed |
|
|
431
|
+
| XML | `XMLParserService` | Enterprise systems - SFCC, SAP, Magento |
|
|
432
|
+
| JSON | `JSONParserService` | APIs, webhooks, modern systems |
|
|
433
|
+
|
|
434
|
+
### 2. State Management
|
|
435
|
+
|
|
436
|
+
**Problem**: Without state management, reprocessing files creates duplicates.
|
|
437
|
+
|
|
438
|
+
**Solution**: `StateService` tracks processed files with distributed locking:
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
442
|
+
service: 'inventory-ingestion',
|
|
443
|
+
correlationId: generateCorrelationId()
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const stateService = new StateService(logger);
|
|
447
|
+
const kvAdapter = new VersoriKVAdapter(openKv());
|
|
448
|
+
|
|
449
|
+
// Check if file already processed
|
|
450
|
+
if (await stateService.isFileProcessed(kvAdapter, 'file.csv')) {
|
|
451
|
+
logger.info('File already processed, skipping');
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Acquire lock for concurrent safety
|
|
456
|
+
const lockAcquired = await stateService.acquireLock('ingestion-lock', kvAdapter, 15);
|
|
457
|
+
if (!lockAcquired) {
|
|
458
|
+
logger.info('File locked by another process');
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
try {
|
|
463
|
+
// Process file
|
|
464
|
+
await processFile('file.csv');
|
|
465
|
+
|
|
466
|
+
// Mark as processed
|
|
467
|
+
await stateService.updateSyncState(kvAdapter, [{
|
|
468
|
+
fileName: 'file.csv',
|
|
469
|
+
lastModified: new Date().toISOString(),
|
|
470
|
+
recordCount: recordCount
|
|
471
|
+
}]);
|
|
472
|
+
} finally {
|
|
473
|
+
await stateService.releaseLock('ingestion-lock', kvAdapter);
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### 3. Performance Optimization
|
|
478
|
+
|
|
479
|
+
**Batch Size Optimization**: Automatically calculate optimal batch size based on data:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
function calculateOptimalBatchSize(
|
|
483
|
+
totalRecords: number,
|
|
484
|
+
avgRecordSize: number
|
|
485
|
+
): number {
|
|
486
|
+
const MAX_BATCH_SIZE = 10000;
|
|
487
|
+
const MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB
|
|
488
|
+
|
|
489
|
+
const recordsPerPayload = Math.floor(MAX_PAYLOAD_SIZE / avgRecordSize);
|
|
490
|
+
return Math.min(recordsPerPayload, MAX_BATCH_SIZE);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const batchSize = calculateOptimalBatchSize(50000, 200);
|
|
494
|
+
// Result: Optimal size based on record size and payload limits
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Parallel Processing**: Process multiple files/batches with configurable strategies:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
import { createClient, S3DataSource, CSVParserService, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
501
|
+
|
|
502
|
+
// Initialize services
|
|
503
|
+
const client = await createClient({ config });
|
|
504
|
+
const s3 = new S3DataSource(
|
|
505
|
+
{
|
|
506
|
+
type: 'S3_CSV',
|
|
507
|
+
connectionId: 's3-inventory',
|
|
508
|
+
name: 'S3 Inventory',
|
|
509
|
+
s3Config: s3Config,
|
|
510
|
+
},
|
|
511
|
+
logger
|
|
512
|
+
);
|
|
513
|
+
const parser = new CSVParserService();
|
|
514
|
+
const mapper = new UniversalMapper(mappingConfig);
|
|
515
|
+
|
|
516
|
+
// Create daily job (reuse for all batches)
|
|
517
|
+
const job = await client.createJob({
|
|
518
|
+
name: 'Daily Inventory Sync',
|
|
519
|
+
retailerId: process.env.FLUENT_RETAILER_ID!
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
// Process multiple files
|
|
523
|
+
const files = await s3.listFiles({ prefix: 'data/', maxKeys: 10 });
|
|
524
|
+
|
|
525
|
+
for (const file of files) {
|
|
526
|
+
const content = await s3.downloadFile(file.path);
|
|
527
|
+
const records = await parser.parse(content as string);
|
|
528
|
+
const result = await mapper.map(records);
|
|
529
|
+
|
|
530
|
+
// Send in batches of 1000
|
|
531
|
+
for (let i = 0; i < result.data.length; i += 1000) {
|
|
532
|
+
const batch = result.data.slice(i, i + 1000);
|
|
533
|
+
await client.sendBatch(job.id, {
|
|
534
|
+
action: 'UPSERT',
|
|
535
|
+
entityType: 'INVENTORY',
|
|
536
|
+
entities: batch
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 4. Error Handling
|
|
543
|
+
|
|
544
|
+
**Fail-Fast with Recovery**: Stop on critical errors, retry transient failures:
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
class RetryableIngestion {
|
|
548
|
+
async executeWithRetry<T>(
|
|
549
|
+
operation: () => Promise<T>,
|
|
550
|
+
context: string
|
|
551
|
+
): Promise<T> {
|
|
552
|
+
let lastError: Error;
|
|
553
|
+
let delay = 1000;
|
|
554
|
+
|
|
555
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
556
|
+
try {
|
|
557
|
+
return await operation();
|
|
558
|
+
} catch (error) {
|
|
559
|
+
lastError = error;
|
|
560
|
+
|
|
561
|
+
// Retry network errors, fail on validation errors
|
|
562
|
+
if (!this.isRetryable(error)) {
|
|
563
|
+
throw error; // ✅ Fail fast on validation errors
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
console.log(`Retry ${attempt}/3 for ${context}`);
|
|
567
|
+
await this.sleep(delay);
|
|
568
|
+
delay *= 2; // Exponential backoff
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
throw new Error(`Failed after 3 retries: ${lastError.message}`);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
private isRetryable(error: any): boolean {
|
|
576
|
+
return error.code === 'NETWORK_ERROR' ||
|
|
577
|
+
error.code === 'TIMEOUT_ERROR' ||
|
|
578
|
+
error.code === 'RATE_LIMIT_ERROR';
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## Ingestion vs Extraction
|
|
586
|
+
|
|
587
|
+
The SDK provides **two complementary workflows**:
|
|
588
|
+
|
|
589
|
+
| Aspect | Ingestion (this guide) | Extraction |
|
|
590
|
+
|--------|------------------------|-----------|
|
|
591
|
+
| **Direction** | External → Fluent Commerce | Fluent Commerce → External |
|
|
592
|
+
| **Primary API** | Batch API (UPSERT) | GraphQL Queries |
|
|
593
|
+
| **Use Case** | Update inventory positions | Export data for analytics/BI |
|
|
594
|
+
| **Data Source** | S3, SFTP, files | Fluent Commerce GraphQL API |
|
|
595
|
+
| **Data Destination** | Fluent Commerce | S3, SFTP, files, databases |
|
|
596
|
+
| **Typical Frequency** | Hourly, daily | Daily, weekly, on-demand |
|
|
597
|
+
| **State Management** | Prevent duplicate ingestion | Track extraction checkpoints |
|
|
598
|
+
|
|
599
|
+
**See Also**: [Data Extraction Guide](../../extraction/) for the reverse workflow.
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## Key Takeaways
|
|
604
|
+
|
|
605
|
+
- 🎯 **Batch API is for inventory only** - Use GraphQL mutations for orders, products, locations
|
|
606
|
+
- 🎯 **State management prevents duplicates** - Essential for production workflows
|
|
607
|
+
- 🎯 **UniversalMapper transforms data** - Declarative field mapping with validation
|
|
608
|
+
- 🎯 **Job strategies optimize performance** - DAILY for frequent updates, PER_FILE for large datasets
|
|
609
|
+
- 🎯 **Error handling is critical** - Implement retry logic and fail-fast validation
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
## Next Steps
|
|
614
|
+
|
|
615
|
+
Continue to [Module 2: Quick Start](../../auto-pagination/modules/auto-pagination-02-quick-start.md) to build your first ingestion workflow with a complete working example.
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
[← Previous: Main Guide](../ingestion-readme.md) | [Back to Guide](../ingestion-readme.md) | [Next: Quick Start →](../../auto-pagination/modules/auto-pagination-02-quick-start.md)
|
|
620
|
+
|
|
621
|
+
## Related Documentation
|
|
622
|
+
|
|
623
|
+
- [Batch API Reference](../../api-reference/modules/api-reference-01-client-api.md#job-batch-operations) - Complete API documentation
|
|
624
|
+
- [Universal Mapping Guide](../../mapping/mapping-readme.md) - Field transformation patterns
|
|
625
|
+
- [State Management](./02-core-guides-ingestion-07-state-management.md) - Duplicate prevention in detail
|
|
626
|
+
- [Orchestrators Guide](../../extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md) - High-level workflow coordination
|