@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,888 +1,888 @@
|
|
|
1
|
-
---
|
|
2
|
-
template_id: tpl-webhook-generic-xml-order
|
|
3
|
-
canonical_filename: template-webhook-generic-xml-order.md
|
|
4
|
-
sdk_version: ^0.1.39
|
|
5
|
-
runtime: versori
|
|
6
|
-
direction: ingestion
|
|
7
|
-
source: webhook-xml
|
|
8
|
-
destination: fluent-graphql
|
|
9
|
-
entity: order
|
|
10
|
-
format: xml
|
|
11
|
-
logging: versori
|
|
12
|
-
status: stable
|
|
13
|
-
features:
|
|
14
|
-
- external-json-config
|
|
15
|
-
- memory-management
|
|
16
|
-
- enhanced-logging
|
|
17
|
-
- audit-trail
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
# Template: Webhook - Generic XML Order to Fluent GraphQL
|
|
21
|
-
|
|
22
|
-
**SDK Version:** @fluentcommerce/fc-connect-sdk@^0.1.39
|
|
23
|
-
**Last Updated:** 2025-01-24
|
|
24
|
-
**Deployment Target:** Versori Platform
|
|
25
|
-
|
|
26
|
-
**FC Connect SDK Use Case Guide**
|
|
27
|
-
|
|
28
|
-
> **SDK**: [@fluentcommerce/fc-connect-sdk](https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk)
|
|
29
|
-
> **Version**: Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
30
|
-
|
|
31
|
-
**Context**: Receive generic XML orders via Versori HTTP webhook and create orders in Fluent Commerce using GraphQL mutations.
|
|
32
|
-
|
|
33
|
-
**Complexity**: Medium
|
|
34
|
-
|
|
35
|
-
**Runtime**: Versori Platform
|
|
36
|
-
|
|
37
|
-
**Estimated Lines**: ~600 lines (modular structure)
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## STEP 1: Understand This Template
|
|
42
|
-
|
|
43
|
-
**What This Template Does:**
|
|
44
|
-
|
|
45
|
-
- Versori HTTP webhook endpoint receiving XML order data
|
|
46
|
-
- XML parsing with optional nodes config for nested/escaped XML segments
|
|
47
|
-
- GraphQL mutation mapping from XML structure to Fluent schema
|
|
48
|
-
- Custom resolvers for data transformation and API calls
|
|
49
|
-
- Memory management (clears large XML payloads after mapping)
|
|
50
|
-
- Error handling and structured response formatting
|
|
51
|
-
- Audit trail (save input/output to filesystem for debugging)
|
|
52
|
-
- **Sync + Fire-and-Forget Pattern**: Fast webhook response, background processing
|
|
53
|
-
|
|
54
|
-
**Key SDK Components:**
|
|
55
|
-
|
|
56
|
-
- `createClient()` - Universal client factory (auto-detects Versori context)
|
|
57
|
-
- `GraphQLMutationMapper` - XML/JSON → GraphQL mutation mapping
|
|
58
|
-
- `XMLParserService` - XML parsing with nodes extraction
|
|
59
|
-
- Native Versori `log` - Use `log` from context
|
|
60
|
-
|
|
61
|
-
**Entity Type:**
|
|
62
|
-
|
|
63
|
-
- **Order** - Fluent entity for order creation
|
|
64
|
-
- **GraphQL Mutation** - Uses `createOrder` mutation (not Event API)
|
|
65
|
-
|
|
66
|
-
**Critical Patterns:**
|
|
67
|
-
|
|
68
|
-
- **Sync + Fire-and-Forget**: Webhook validates quickly, returns immediately, processes in background
|
|
69
|
-
- **External JSON Config**: Mapping configuration in separate JSON file (`config/order-mapping.json`)
|
|
70
|
-
- **Modular Architecture**: Separate services, workflows, config, types folders
|
|
71
|
-
- **Memory Management**: Clears large XML payloads from memory after mapping
|
|
72
|
-
- **Background Processing**: Long-running operations (GraphQL mutations) happen asynchronously
|
|
73
|
-
- **Error Handling**: Comprehensive error handling with structured logging and recommendations
|
|
74
|
-
- **Activation Variables**: Configuration via Versori activation variables (OUTPUT_DIR, validateConnectionOnStart)
|
|
75
|
-
|
|
76
|
-
**When to Use This Template:**
|
|
77
|
-
|
|
78
|
-
- ✅ Real-time order ingestion from external systems (SFCC, Shopify, custom)
|
|
79
|
-
- ✅ XML order format (can be adapted for JSON)
|
|
80
|
-
- ✅ Need fast webhook response (don't wait for order creation)
|
|
81
|
-
- ✅ Single order per webhook call
|
|
82
|
-
- ✅ Need audit trail for debugging
|
|
83
|
-
|
|
84
|
-
**When NOT to Use:**
|
|
85
|
-
|
|
86
|
-
- ❌ Bulk order processing (use Batch API or scheduled workflows)
|
|
87
|
-
- ❌ Order updates (use GraphQL `updateOrder` mutation)
|
|
88
|
-
- ❌ CSV/JSON formats (use appropriate format template)
|
|
89
|
-
- ❌ Need synchronous order creation (wait for result before responding)
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## STEP 2: Implementation Prompt for Claude Code
|
|
94
|
-
|
|
95
|
-
**Copy this prompt and send to Claude Code to generate the complete implementation:**
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
Create a Versori webhook workflow for generic XML order ingestion to Fluent Commerce GraphQL.
|
|
99
|
-
|
|
100
|
-
REQUIREMENTS:
|
|
101
|
-
1. Runtime: Versori Platform (HTTP webhook)
|
|
102
|
-
2. Source: XML order data via HTTP POST webhook
|
|
103
|
-
3. Destination: Fluent Commerce GraphQL API (createOrder mutation)
|
|
104
|
-
4. Format: XML with optional nodes extraction
|
|
105
|
-
5. Entity: Order (GraphQL mutation)
|
|
106
|
-
|
|
107
|
-
KEY FEATURES:
|
|
108
|
-
- Sync + fire-and-forget pattern (fast webhook response, background processing)
|
|
109
|
-
- External JSON mapping configuration (not inline TypeScript)
|
|
110
|
-
- Modular architecture (workflows/, services/, config/, types/)
|
|
111
|
-
- XML parsing with optional nodes config for nested XML segments
|
|
112
|
-
- GraphQLMutationMapper for XML → GraphQL transformation
|
|
113
|
-
- Custom resolvers for data transformation
|
|
114
|
-
- Audit trail (save input/output files)
|
|
115
|
-
- Comprehensive error handling with structured logging
|
|
116
|
-
|
|
117
|
-
CRITICAL REQUIREMENTS:
|
|
118
|
-
1. Webhook Mode: response: { mode: 'sync' } (fast response)
|
|
119
|
-
2. Background Processing: Fire-and-forget pattern (no await on long operations)
|
|
120
|
-
3. Mapping Config: External JSON file (config/order-mapping.json)
|
|
121
|
-
4. Modular Structure: Separate services/, config/, types/ folders
|
|
122
|
-
5. Native Logging: Use log from context (no LoggingService)
|
|
123
|
-
6. Error Handling: Structured error responses with recommendations
|
|
124
|
-
|
|
125
|
-
SDK METHODS TO USE:
|
|
126
|
-
- createClient({ ...ctx, log }) - Pass full Versori context
|
|
127
|
-
- new GraphQLMutationMapper(mappingConfig, log, { fluentClient: client }) - Initialize mapper
|
|
128
|
-
- mapper.mapWithNodes(xmlData, customResolvers, context) - Map XML with custom resolvers (REQUIRED for custom resolvers)
|
|
129
|
-
- mapper.map(xmlData) - Map XML without custom resolvers (built-in SDK resolvers only)
|
|
130
|
-
- mapWithNodes() now returns query automatically (no need for buildMutation())
|
|
131
|
-
- client.graphql({ query, variables }) - Execute GraphQL mutation
|
|
132
|
-
|
|
133
|
-
FORBIDDEN PATTERNS:
|
|
134
|
-
- ❌ Inline mapping config (use external JSON)
|
|
135
|
-
- ❌ await on background processing (use fire-and-forget)
|
|
136
|
-
- ❌ LoggingService (use native log from context)
|
|
137
|
-
- ❌ All code in one file (use modular structure)
|
|
138
|
-
- ❌ async mode webhook (use sync + fire-and-forget)
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## STEP 3: Detailed Flow Documentation
|
|
144
|
-
|
|
145
|
-
### Complete Processing Flow
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
149
|
-
│ 1. WEBHOOK RECEIVED │
|
|
150
|
-
│ POST https://{workspace}.versori.run/generic-xml-order │
|
|
151
|
-
│ Content-Type: application/xml │
|
|
152
|
-
│ Body: <Order>...</Order> │
|
|
153
|
-
└────────────────────┬────────────────────────────────────────┘
|
|
154
|
-
│
|
|
155
|
-
▼
|
|
156
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
157
|
-
│ 2. QUICK VALIDATION (Synchronous, ~10-50ms) │
|
|
158
|
-
│ - Check fluent_commerce connection exists │
|
|
159
|
-
│ - Validate XML payload present │
|
|
160
|
-
│ - Return HTTP 200 OK immediately │
|
|
161
|
-
└────────────────────┬────────────────────────────────────────┘
|
|
162
|
-
│
|
|
163
|
-
▼
|
|
164
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
165
|
-
│ 3. BACKGROUND PROCESSING (Fire-and-Forget) │
|
|
166
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
167
|
-
│ │ 3a. Initialize Fluent Client │ │
|
|
168
|
-
│ │ - createClient({ ...ctx, log }) │ │
|
|
169
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
170
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
171
|
-
│ │ 3b. Parse XML (if needed) │ │
|
|
172
|
-
│ │ - Versori auto-parses XML to object │ │
|
|
173
|
-
│ │ - Optional: Extract nested XML segments │ │
|
|
174
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
175
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
176
|
-
│ │ 3c. Map XML to GraphQL Variables │ │
|
|
177
|
-
│ │ - Load mapping config from JSON │ │
|
|
178
|
-
│ │ - GraphQLMutationMapper.mapWithNodes() (REQUIRED for custom resolvers)│ │
|
|
179
|
-
│ │ - Apply custom resolvers │ │
|
|
180
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
181
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
182
|
-
│ │ 3d. Generate GraphQL Mutation │ │
|
|
183
|
-
│ │ - Query returned in result.query │ │
|
|
184
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
185
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
186
|
-
│ │ 3e. Execute GraphQL Mutation │ │
|
|
187
|
-
│ │ - client.graphql({ query, variables }) │ │
|
|
188
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
189
|
-
│ ┌─────────────────────────────────────────────────────┐ │
|
|
190
|
-
│ │ 3f. Save Audit Trail (Optional) │ │
|
|
191
|
-
│ │ - 1-incoming-xml.json │ │
|
|
192
|
-
│ │ - 2-mapped-variables.json │ │
|
|
193
|
-
│ │ - 3-graphql-response.json │ │
|
|
194
|
-
│ └─────────────────────────────────────────────────────┘ │
|
|
195
|
-
└─────────────────────────────────────────────────────────────┘
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Response Timing
|
|
199
|
-
|
|
200
|
-
| Stage | Timing | Blocking |
|
|
201
|
-
|-------|--------|----------|
|
|
202
|
-
| **Webhook Validation** | ~10-50ms | ✅ Yes (blocks response) |
|
|
203
|
-
| **Background Processing** | ~500-2000ms | ❌ No (fire-and-forget) |
|
|
204
|
-
| **Total Response Time** | ~10-50ms | ✅ Fast response |
|
|
205
|
-
|
|
206
|
-
**Key Benefit**: Webhook caller receives immediate acknowledgment (~50ms) while order creation happens in background (~2s).
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## STEP 4: Production Modular Structure
|
|
211
|
-
|
|
212
|
-
> **✅ This section shows the COMPLETE production-ready modular structure.**
|
|
213
|
-
> All files are shown with proper imports/exports and folder organization.
|
|
214
|
-
|
|
215
|
-
### Complete Project Structure
|
|
216
|
-
|
|
217
|
-
```
|
|
218
|
-
generic-xml-order-ingestion/
|
|
219
|
-
├── package.json # Dependencies and Versori config
|
|
220
|
-
├── index.ts # Entry point - exports all workflows
|
|
221
|
-
└── src/
|
|
222
|
-
├── workflows/
|
|
223
|
-
│ └── webhook/
|
|
224
|
-
│ └── order-ingestion.ts # Webhook: Receive XML orders
|
|
225
|
-
│
|
|
226
|
-
├── services/
|
|
227
|
-
│ └── order-processing.service.ts # Shared orchestration logic (reusable)
|
|
228
|
-
│
|
|
229
|
-
├── config/
|
|
230
|
-
│ └── order-mapping.json # Mapping configuration (external JSON)
|
|
231
|
-
│
|
|
232
|
-
└── types/
|
|
233
|
-
└── order.types.ts # TypeScript interfaces
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Why This Structure?**
|
|
237
|
-
|
|
238
|
-
- ✅ **Clear separation**: Webhook handlers vs business logic
|
|
239
|
-
- ✅ **Reusable services**: Order processing logic can be reused
|
|
240
|
-
- ✅ **External config**: Mapping changes don't require code changes
|
|
241
|
-
- ✅ **Type safety**: TypeScript interfaces for better IDE support
|
|
242
|
-
- ✅ **Scalable**: Easy to add new webhooks or services
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
### File: `package.json`
|
|
247
|
-
|
|
248
|
-
```json
|
|
249
|
-
{
|
|
250
|
-
"name": "generic-xml-order-ingestion",
|
|
251
|
-
"version": "2.0.0",
|
|
252
|
-
"description": "Generic XML Order Ingestion Webhook to Fluent Commerce",
|
|
253
|
-
"type": "module",
|
|
254
|
-
"versori": {
|
|
255
|
-
"workflows": "./index.ts"
|
|
256
|
-
},
|
|
257
|
-
"scripts": {
|
|
258
|
-
"lint": "eslint . --ext .ts",
|
|
259
|
-
"typecheck": "tsc --noEmit"
|
|
260
|
-
},
|
|
261
|
-
"dependencies": {
|
|
262
|
-
"@fluentcommerce/fc-connect-sdk": "^0.1.39",
|
|
263
|
-
"@versori/run": "latest"
|
|
264
|
-
},
|
|
265
|
-
"devDependencies": {
|
|
266
|
-
"@types/node": "^20.0.0",
|
|
267
|
-
"typescript": "^5.0.0"
|
|
268
|
-
},
|
|
269
|
-
"engines": {
|
|
270
|
-
"node": ">=18.0.0"
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
### File: `index.ts`
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
/**
|
|
281
|
-
* Entry point - Export all workflows for Versori platform
|
|
282
|
-
*
|
|
283
|
-
* This file exports all workflows to be registered with Versori.
|
|
284
|
-
* Each workflow is defined in its own file for better organization.
|
|
285
|
-
*/
|
|
286
|
-
|
|
287
|
-
export { genericXmlOrder } from './src/workflows/webhook/order-ingestion';
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
---
|
|
291
|
-
|
|
292
|
-
### File: `src/types/order.types.ts`
|
|
293
|
-
|
|
294
|
-
```typescript
|
|
295
|
-
/**
|
|
296
|
-
* Type definitions for order ingestion
|
|
297
|
-
*/
|
|
298
|
-
export interface OrderIngestionResult {
|
|
299
|
-
success: boolean;
|
|
300
|
-
orderId?: string;
|
|
301
|
-
orderRef?: string;
|
|
302
|
-
error?: string;
|
|
303
|
-
recommendation?: string;
|
|
304
|
-
timestamp: string;
|
|
305
|
-
duration: number;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
export interface OrderMappingConfig {
|
|
309
|
-
mutation: string;
|
|
310
|
-
sourceFormat: 'xml' | 'json';
|
|
311
|
-
nodes?: {
|
|
312
|
-
[key: string]: {
|
|
313
|
-
extract: string;
|
|
314
|
-
parse: 'xml' | 'json';
|
|
315
|
-
required: boolean;
|
|
316
|
-
};
|
|
317
|
-
};
|
|
318
|
-
fields: {
|
|
319
|
-
[key: string]: any;
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
---
|
|
325
|
-
|
|
326
|
-
### File: `src/config/order-mapping.json`
|
|
327
|
-
|
|
328
|
-
```json
|
|
329
|
-
{
|
|
330
|
-
"mutation": "createOrder",
|
|
331
|
-
"sourceFormat": "xml",
|
|
332
|
-
"returnFields": ["id", "ref", "status"],
|
|
333
|
-
"nodes": {
|
|
334
|
-
"order": {
|
|
335
|
-
"extract": "Envelope.Body.OrderEnvelope",
|
|
336
|
-
"parse": "xml",
|
|
337
|
-
"required": false
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
"fields": {
|
|
341
|
-
"ref": {
|
|
342
|
-
"source": "$order.Order@id",
|
|
343
|
-
"resolver": "sdk.toString",
|
|
344
|
-
"required": true
|
|
345
|
-
},
|
|
346
|
-
"type": {
|
|
347
|
-
"source": "$order.Order@type",
|
|
348
|
-
"defaultValue": "HD"
|
|
349
|
-
},
|
|
350
|
-
"retailer": {
|
|
351
|
-
"fields": {
|
|
352
|
-
"id": {
|
|
353
|
-
"value": "2"
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
},
|
|
357
|
-
"customer": {
|
|
358
|
-
"fields": {
|
|
359
|
-
"firstName": {
|
|
360
|
-
"source": "$order.Order.Customer.FirstName"
|
|
361
|
-
},
|
|
362
|
-
"lastName": {
|
|
363
|
-
"source": "$order.Order.Customer.LastName"
|
|
364
|
-
},
|
|
365
|
-
"username": {
|
|
366
|
-
"source": "$order.Order.Customer.Email",
|
|
367
|
-
"resolver": "sdk.lowercase"
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
},
|
|
371
|
-
"items": {
|
|
372
|
-
"source": "$order.Order.Items.Item",
|
|
373
|
-
"isArray": true,
|
|
374
|
-
"fields": {
|
|
375
|
-
"ref": {
|
|
376
|
-
"source": "$.@id",
|
|
377
|
-
"resolver": "sdk.toString"
|
|
378
|
-
},
|
|
379
|
-
"productRef": {
|
|
380
|
-
"source": "$.Sku",
|
|
381
|
-
"resolver": "sdk.toString"
|
|
382
|
-
},
|
|
383
|
-
"quantity": {
|
|
384
|
-
"source": "$.Quantity",
|
|
385
|
-
"resolver": "sdk.parseInt"
|
|
386
|
-
},
|
|
387
|
-
"price": {
|
|
388
|
-
"source": "$.Price",
|
|
389
|
-
"resolver": "sdk.parseFloat"
|
|
390
|
-
},
|
|
391
|
-
"currency": {
|
|
392
|
-
"source": "$order.Order.Currency",
|
|
393
|
-
"defaultValue": "USD"
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
},
|
|
397
|
-
"totalPrice": {
|
|
398
|
-
"source": "$order.Order.Totals.Subtotal",
|
|
399
|
-
"resolver": "sdk.parseFloat"
|
|
400
|
-
},
|
|
401
|
-
"totalTaxPrice": {
|
|
402
|
-
"source": "$order.Order.Totals.Tax",
|
|
403
|
-
"resolver": "sdk.parseFloat",
|
|
404
|
-
"defaultValue": 0
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
### File: `src/services/order-processing.service.ts`
|
|
413
|
-
|
|
414
|
-
```typescript
|
|
415
|
-
/**
|
|
416
|
-
* Order Processing Service
|
|
417
|
-
*
|
|
418
|
-
* Orchestrates the complete order ingestion process:
|
|
419
|
-
* 1. Validate webhook payload
|
|
420
|
-
* 2. Extract and parse nested XML (if needed)
|
|
421
|
-
* 3. Apply field mapping with custom resolvers
|
|
422
|
-
* 4. Create order via GraphQL API
|
|
423
|
-
* 5. Audit trail (save input/output files)
|
|
424
|
-
*/
|
|
425
|
-
|
|
426
|
-
import { Buffer } from 'node:buffer';
|
|
427
|
-
import { createClient, GraphQLMutationMapper, classifyErrors } from '@fluentcommerce/fc-connect-sdk';
|
|
428
|
-
import type { OrderIngestionResult } from '../types/order.types';
|
|
429
|
-
import mappingConfig from '../config/order-mapping.json' with { type: 'json' };
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Process order ingestion (background processing)
|
|
433
|
-
*
|
|
434
|
-
* @param ctx - Versori context object containing fetch, connections, log, activation, data
|
|
435
|
-
* @param xmlData - Parsed XML order data
|
|
436
|
-
* @param executionStartTime - Workflow start time for duration tracking
|
|
437
|
-
*/
|
|
438
|
-
export async function processOrderInBackground(
|
|
439
|
-
ctx: any,
|
|
440
|
-
xmlData: any,
|
|
441
|
-
executionStartTime: number
|
|
442
|
-
): Promise<OrderIngestionResult> {
|
|
443
|
-
const { log, activation, connections, openKv } = ctx;
|
|
444
|
-
|
|
445
|
-
try {
|
|
446
|
-
log.info('🔄 [BACKGROUND] Starting background order processing', {
|
|
447
|
-
correlationId: activation?.id,
|
|
448
|
-
timestamp: new Date().toISOString(),
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
// ========================================
|
|
452
|
-
// STEP 2: CLIENT INITIALIZATION
|
|
453
|
-
// ========================================
|
|
454
|
-
|
|
455
|
-
// Optional: Validate connection immediately (fail-fast mode for webhooks)
|
|
456
|
-
// Set activation variable 'validateConnectionOnStart' = 'true' to enable
|
|
457
|
-
const validateConnection = activation?.getVariable('validateConnectionOnStart') === 'true';
|
|
458
|
-
|
|
459
|
-
if (validateConnection) {
|
|
460
|
-
log.info('🔍 [BACKGROUND] Connection validation enabled', {
|
|
461
|
-
note: 'This executes query { me { ref } } to verify authentication',
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
466
|
-
|
|
467
|
-
if (validateConnection) {
|
|
468
|
-
log.info('✅ [BACKGROUND] Connection validated successfully - authentication confirmed');
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
log.info('🔌 [BACKGROUND] Fluent client initialized');
|
|
472
|
-
|
|
473
|
-
// ========================================
|
|
474
|
-
// STEP 3: MAPPING AND TRANSFORMATION
|
|
475
|
-
// ========================================
|
|
476
|
-
|
|
477
|
-
log.info('🔄 [BACKGROUND] Applying mapping');
|
|
478
|
-
|
|
479
|
-
// Apply mapping with optional nodes processing
|
|
480
|
-
// RESOLVERS: Custom transformation logic (async allowed)
|
|
481
|
-
// CONTEXT: Pass fluentClient to resolvers for API calls
|
|
482
|
-
const mapper = new GraphQLMutationMapper(mappingConfig as any, log, { fluentClient: client as any });
|
|
483
|
-
|
|
484
|
-
// Optional custom resolvers
|
|
485
|
-
const customResolvers = {
|
|
486
|
-
'custom.ensureRef': (value: any) => String(value || `ORD-${Date.now()}`),
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// Use mapWithNodes() when custom resolvers are present (REQUIRED)
|
|
490
|
-
// map() does NOT accept custom resolvers parameter
|
|
491
|
-
// Returns MapWithNodesResult with query auto-generated!
|
|
492
|
-
const result = await mapper.mapWithNodes(xmlData, customResolvers as any, {
|
|
493
|
-
fluentClient: client as any,
|
|
494
|
-
config: {},
|
|
495
|
-
helpers: { fluentClient: client as any, logger: log },
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
if (!result.success) {
|
|
499
|
-
log.error('❌ [BACKGROUND] Mapping failed', {
|
|
500
|
-
errors: result.errors,
|
|
501
|
-
errorCount: result.errors?.length || 0,
|
|
502
|
-
});
|
|
503
|
-
return {
|
|
504
|
-
success: false,
|
|
505
|
-
error: 'Mapping validation failed',
|
|
506
|
-
recommendation: 'Check mapping configuration JSON and verify source paths match incoming XML structure',
|
|
507
|
-
timestamp: new Date().toISOString(),
|
|
508
|
-
duration: Date.now() - executionStartTime,
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const orderRef = (result.data as any)?.input?.ref || 'unknown';
|
|
513
|
-
log.info('✅ [BACKGROUND] Mapping completed', {
|
|
514
|
-
orderRef,
|
|
515
|
-
fieldsCount: Object.keys((result.data as any)?.input || {}).length,
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
// ========================================
|
|
519
|
-
// STEP 4: AUDIT TRAIL (SAVE INPUT DATA)
|
|
520
|
-
// ========================================
|
|
521
|
-
|
|
522
|
-
// Save audit trail to KV storage (Versori-compatible - file system is read-only)
|
|
523
|
-
try {
|
|
524
|
-
const kv = openKv(':project:');
|
|
525
|
-
const timestamp = new Date().toISOString();
|
|
526
|
-
const auditKey = ['orders', 'audit', orderRef, timestamp];
|
|
527
|
-
|
|
528
|
-
// Save 1: Original XML (parsed by Versori) - save BEFORE memory cleanup
|
|
529
|
-
await kv.set([...auditKey, 'incoming-xml'], xmlData);
|
|
530
|
-
|
|
531
|
-
// Save 2: Mapped Fluent variables (ready for GraphQL)
|
|
532
|
-
await kv.set([...auditKey, 'mapped-variables'], result.data);
|
|
533
|
-
|
|
534
|
-
log.info('Audit trail saved to KV storage', { orderRef, timestamp });
|
|
535
|
-
} catch (kvError: any) {
|
|
536
|
-
log.warn('Failed to save audit trail to KV', {
|
|
537
|
-
error: kvError.message,
|
|
538
|
-
note: 'Continuing with order creation',
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// ✅ PRODUCTION: Memory cleanup for large XML payloads (after saving audit trail)
|
|
543
|
-
try {
|
|
544
|
-
if (xmlData && typeof xmlData === 'object') {
|
|
545
|
-
// Clear large XML data from memory after mapping and audit trail
|
|
546
|
-
Object.keys(xmlData).forEach(key => delete (xmlData as any)[key]);
|
|
547
|
-
}
|
|
548
|
-
} catch (cleanupError) {
|
|
549
|
-
// Non-blocking - continue processing
|
|
550
|
-
log.debug('Memory cleanup skipped', { note: 'Non-critical' });
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// ========================================
|
|
554
|
-
// STEP 5: CREATE ORDER VIA GRAPHQL API
|
|
555
|
-
// ========================================
|
|
556
|
-
|
|
557
|
-
log.info('📡 [BACKGROUND] Creating order in Fluent Commerce', { orderRef });
|
|
558
|
-
|
|
559
|
-
// mapWithNodes() now auto-generates query - no need to call buildMutation()!
|
|
560
|
-
log.info('📝 [BACKGROUND] GraphQL mutation auto-generated', { orderRef });
|
|
561
|
-
|
|
562
|
-
// Execute mutation (query is auto-generated in result)
|
|
563
|
-
log.info('🚀 [BACKGROUND] Executing GraphQL mutation', { orderRef });
|
|
564
|
-
const response = await client.graphql({
|
|
565
|
-
query: result.query,
|
|
566
|
-
variables: result.variables // ✅ Use variables (wrapped if fields pattern)
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
if (response.errors?.length) {
|
|
570
|
-
// Classify GraphQL errors to determine retry strategy
|
|
571
|
-
const classification = classifyErrors(response.errors);
|
|
572
|
-
|
|
573
|
-
log.error('❌ [BACKGROUND] GraphQL execution errors', {
|
|
574
|
-
orderRef,
|
|
575
|
-
errorCode: classification.errorCode,
|
|
576
|
-
retryable: classification.retryable,
|
|
577
|
-
action: classification.action,
|
|
578
|
-
message: classification.userMessage,
|
|
579
|
-
errors: response.errors,
|
|
580
|
-
errorCount: response.errors.length,
|
|
581
|
-
});
|
|
582
|
-
return {
|
|
583
|
-
success: false,
|
|
584
|
-
error: 'GraphQL mutation execution failed',
|
|
585
|
-
recommendation: 'Review GraphQL errors and verify order data structure',
|
|
586
|
-
timestamp: new Date().toISOString(),
|
|
587
|
-
duration: Date.now() - executionStartTime,
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
const orderId = response.data?.createOrder?.id;
|
|
592
|
-
log.info('✅ [BACKGROUND] Order created successfully', {
|
|
593
|
-
orderRef,
|
|
594
|
-
orderId,
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
// Save GraphQL response to audit trail (KV storage)
|
|
598
|
-
try {
|
|
599
|
-
const kv = openKv(':project:');
|
|
600
|
-
const timestamp = new Date().toISOString();
|
|
601
|
-
const auditKey = ['orders', 'audit', orderRef, timestamp, 'graphql-response'];
|
|
602
|
-
await kv.set(auditKey, response);
|
|
603
|
-
log.info('GraphQL response saved to KV storage', { orderRef, timestamp });
|
|
604
|
-
} catch (kvError: any) {
|
|
605
|
-
log.warn('Failed to save GraphQL response to KV', {
|
|
606
|
-
error: kvError.message,
|
|
607
|
-
note: 'Non-critical',
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Duration tracking
|
|
612
|
-
const duration = Date.now() - executionStartTime;
|
|
613
|
-
log.info('🎉 [BACKGROUND] Order processed successfully', {
|
|
614
|
-
orderRef,
|
|
615
|
-
orderId,
|
|
616
|
-
duration: `${duration}ms`,
|
|
617
|
-
timestamp: new Date().toISOString(),
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
return {
|
|
621
|
-
success: true,
|
|
622
|
-
orderId,
|
|
623
|
-
orderRef,
|
|
624
|
-
timestamp: new Date().toISOString(),
|
|
625
|
-
duration,
|
|
626
|
-
};
|
|
627
|
-
} catch (error: any) {
|
|
628
|
-
const duration = Date.now() - executionStartTime;
|
|
629
|
-
log.error('❌ [BACKGROUND] Unhandled error in order processing', {
|
|
630
|
-
error: error instanceof Error ? error.message : String(error),
|
|
631
|
-
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
632
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
633
|
-
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
634
|
-
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
635
|
-
: error.message?.includes('mapping') || error.message?.includes('field')
|
|
636
|
-
? 'Check mapping configuration JSON and verify source paths match incoming XML structure'
|
|
637
|
-
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
638
|
-
? 'Check network connectivity and Fluent Commerce API availability'
|
|
639
|
-
: error.message?.includes('validation') || error.message?.includes('required')
|
|
640
|
-
? 'Ensure all required fields are present in the webhook payload'
|
|
641
|
-
: 'Review error details and check webhook payload structure',
|
|
642
|
-
correlationId: activation?.id,
|
|
643
|
-
duration,
|
|
644
|
-
});
|
|
645
|
-
|
|
646
|
-
return {
|
|
647
|
-
success: false,
|
|
648
|
-
error: error instanceof Error ? error.message : String(error),
|
|
649
|
-
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
650
|
-
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
651
|
-
: 'Review error details and check webhook payload structure',
|
|
652
|
-
timestamp: new Date().toISOString(),
|
|
653
|
-
duration,
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
---
|
|
660
|
-
|
|
661
|
-
### File: `src/workflows/webhook/order-ingestion.ts`
|
|
662
|
-
|
|
663
|
-
```typescript
|
|
664
|
-
/**
|
|
665
|
-
* Generic XML Order Ingestion Webhook
|
|
666
|
-
*
|
|
667
|
-
* Versori Endpoint: POST https://{workspace}.versori.run/generic-xml-order
|
|
668
|
-
* Content-Type: application/xml
|
|
669
|
-
*
|
|
670
|
-
* Pattern: Sync + Fire-and-Forget
|
|
671
|
-
* - Quick validation (synchronous)
|
|
672
|
-
* - Background processing (fire-and-forget)
|
|
673
|
-
* - Fast webhook response (~10-50ms)
|
|
674
|
-
*/
|
|
675
|
-
|
|
676
|
-
import { webhook, http } from '@versori/run';
|
|
677
|
-
import type { Context } from '@versori/run';
|
|
678
|
-
import { processOrderInBackground } from '../../services/order-processing.service';
|
|
679
|
-
|
|
680
|
-
/**
|
|
681
|
-
* Generic XML Order Ingestion Webhook
|
|
682
|
-
*
|
|
683
|
-
* Sync mode: Response sent when handler returns
|
|
684
|
-
* Fire-and-forget: Background processing continues after response
|
|
685
|
-
*/
|
|
686
|
-
export const genericXmlOrder = webhook('generic-xml-order', {
|
|
687
|
-
response: { mode: 'sync' }, // ✅ Sync mode: response sent when handler returns
|
|
688
|
-
}).then(
|
|
689
|
-
http('validate-and-process', { connection: 'fluent_commerce' }, async (ctx: Context<any>) => {
|
|
690
|
-
const { log, activation, connections, data } = ctx;
|
|
691
|
-
const executionStartTime = Date.now();
|
|
692
|
-
|
|
693
|
-
log.info('🚀 [WEBHOOK] Received generic XML order webhook', {
|
|
694
|
-
correlationId: activation?.id,
|
|
695
|
-
timestamp: new Date().toISOString(),
|
|
696
|
-
});
|
|
697
|
-
|
|
698
|
-
// Quick validation (synchronous)
|
|
699
|
-
if (!connections || !connections.fluent_commerce) {
|
|
700
|
-
log.error('❌ [WEBHOOK] Configuration error: Missing fluent_commerce connection', {
|
|
701
|
-
recommendation: 'Configure fluent_commerce connection in Connections section with OAuth2 credentials',
|
|
702
|
-
});
|
|
703
|
-
return {
|
|
704
|
-
status: 500,
|
|
705
|
-
body: {
|
|
706
|
-
success: false,
|
|
707
|
-
message: 'Missing fluent_commerce connection',
|
|
708
|
-
recommendation: 'Configure fluent_commerce connection in Connections section with OAuth2 credentials',
|
|
709
|
-
timestamp: new Date().toISOString(),
|
|
710
|
-
},
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// Get webhook payload (Versori pre-parses XML)
|
|
715
|
-
const xmlData = activation.body || data;
|
|
716
|
-
|
|
717
|
-
if (!xmlData) {
|
|
718
|
-
log.error('❌ [WEBHOOK] Validation error: No XML data received in webhook', {
|
|
719
|
-
recommendation: 'Ensure webhook payload contains valid XML order data',
|
|
720
|
-
});
|
|
721
|
-
return {
|
|
722
|
-
status: 400,
|
|
723
|
-
body: {
|
|
724
|
-
success: false,
|
|
725
|
-
message: 'No XML data received',
|
|
726
|
-
recommendation: 'Ensure webhook payload contains valid XML order data',
|
|
727
|
-
timestamp: new Date().toISOString(),
|
|
728
|
-
},
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
log.info('✅ [WEBHOOK] Validation passed, starting background processing', {
|
|
733
|
-
correlationId: activation?.id,
|
|
734
|
-
});
|
|
735
|
-
|
|
736
|
-
// ✅ Fire-and-forget: Start background processing WITHOUT await
|
|
737
|
-
// The promise continues execution after we return the response
|
|
738
|
-
processOrderInBackground(ctx, xmlData, executionStartTime)
|
|
739
|
-
.then((result) => {
|
|
740
|
-
if (result.success) {
|
|
741
|
-
log.info('✅ [BACKGROUND] Order processing completed successfully', {
|
|
742
|
-
orderId: result.orderId,
|
|
743
|
-
orderRef: result.orderRef,
|
|
744
|
-
duration: result.duration,
|
|
745
|
-
correlationId: activation?.id,
|
|
746
|
-
});
|
|
747
|
-
} else {
|
|
748
|
-
log.error('❌ [BACKGROUND] Order processing failed', {
|
|
749
|
-
error: result.error,
|
|
750
|
-
recommendation: result.recommendation,
|
|
751
|
-
correlationId: activation?.id,
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
|
-
})
|
|
755
|
-
.catch((error: unknown) => {
|
|
756
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
757
|
-
log.error('❌ [BACKGROUND] Order processing failed with exception', {
|
|
758
|
-
error: errorMessage,
|
|
759
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
760
|
-
errorType: error instanceof Error ? error.constructor.name : typeof error,
|
|
761
|
-
correlationId: activation?.id,
|
|
762
|
-
});
|
|
763
|
-
});
|
|
764
|
-
|
|
765
|
-
// Return immediately (response sent with this return value)
|
|
766
|
-
return {
|
|
767
|
-
status: 200,
|
|
768
|
-
body: {
|
|
769
|
-
success: true,
|
|
770
|
-
message: 'Order ingestion started in background',
|
|
771
|
-
timestamp: new Date().toISOString(),
|
|
772
|
-
},
|
|
773
|
-
};
|
|
774
|
-
})
|
|
775
|
-
);
|
|
776
|
-
```
|
|
777
|
-
|
|
778
|
-
---
|
|
779
|
-
|
|
780
|
-
## STEP 5: Configuration
|
|
781
|
-
|
|
782
|
-
### Activation Variables
|
|
783
|
-
|
|
784
|
-
Configure these in Versori Activation Variables:
|
|
785
|
-
|
|
786
|
-
| Variable | Description | Required | Default | Example |
|
|
787
|
-
|----------|-------------|----------|---------|---------|
|
|
788
|
-
| `OUTPUT_DIR` | Directory for audit trail files | No | `./output` | `./audit-trail` |
|
|
789
|
-
| `validateConnectionOnStart` | Validate Fluent connection on startup (fail-fast mode) | No | `false` | `true` |
|
|
790
|
-
|
|
791
|
-
**Usage in Code:**
|
|
792
|
-
```typescript
|
|
793
|
-
const outputDir = activation?.getVariable('OUTPUT_DIR') || './output';
|
|
794
|
-
const validateConnection = activation?.getVariable('validateConnectionOnStart') === 'true';
|
|
795
|
-
```
|
|
796
|
-
|
|
797
|
-
### Connection Configuration
|
|
798
|
-
|
|
799
|
-
**Required Connection:** `fluent_commerce`
|
|
800
|
-
|
|
801
|
-
- **Type**: OAuth2
|
|
802
|
-
- **Credentials**: Client ID, Client Secret, Base URL
|
|
803
|
-
- **Scope**: Order creation permissions
|
|
804
|
-
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
## STEP 6: Testing
|
|
808
|
-
|
|
809
|
-
### Test Webhook Request
|
|
810
|
-
|
|
811
|
-
```bash
|
|
812
|
-
curl -X POST https://{workspace}.versori.run/generic-xml-order \
|
|
813
|
-
-H "Content-Type: application/xml" \
|
|
814
|
-
-d '<Order>
|
|
815
|
-
<Order id="ORD-001" type="HD">
|
|
816
|
-
<Customer>
|
|
817
|
-
<FirstName>John</FirstName>
|
|
818
|
-
<LastName>Doe</LastName>
|
|
819
|
-
<Email>john.doe@example.com</Email>
|
|
820
|
-
</Customer>
|
|
821
|
-
<Items>
|
|
822
|
-
<Item id="ITEM-001">
|
|
823
|
-
<Sku>SKU-12345</Sku>
|
|
824
|
-
<Quantity>2</Quantity>
|
|
825
|
-
<Price>29.99</Price>
|
|
826
|
-
</Item>
|
|
827
|
-
</Items>
|
|
828
|
-
<Totals>
|
|
829
|
-
<Subtotal>59.98</Subtotal>
|
|
830
|
-
<Tax>4.80</Tax>
|
|
831
|
-
</Totals>
|
|
832
|
-
<Currency>USD</Currency>
|
|
833
|
-
</Order>
|
|
834
|
-
</Order>'
|
|
835
|
-
```
|
|
836
|
-
|
|
837
|
-
### Expected Response
|
|
838
|
-
|
|
839
|
-
```json
|
|
840
|
-
{
|
|
841
|
-
"success": true,
|
|
842
|
-
"message": "Order ingestion started in background",
|
|
843
|
-
"timestamp": "2025-01-25T10:30:00.000Z"
|
|
844
|
-
}
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
**Response Time**: ~10-50ms (fast acknowledgment)
|
|
848
|
-
|
|
849
|
-
**Background Processing**: Order creation happens asynchronously (~500-2000ms)
|
|
850
|
-
|
|
851
|
-
---
|
|
852
|
-
|
|
853
|
-
## STEP 7: Troubleshooting
|
|
854
|
-
|
|
855
|
-
### Common Issues
|
|
856
|
-
|
|
857
|
-
**1. Missing fluent_commerce connection**
|
|
858
|
-
- **Error**: `Missing fluent_commerce connection`
|
|
859
|
-
- **Solution**: Configure `fluent_commerce` connection in Versori Connections section
|
|
860
|
-
|
|
861
|
-
**2. Mapping validation failed**
|
|
862
|
-
- **Error**: `Mapping validation failed`
|
|
863
|
-
- **Solution**: Check `config/order-mapping.json` and verify source paths match XML structure
|
|
864
|
-
|
|
865
|
-
**3. GraphQL execution errors**
|
|
866
|
-
- **Error**: `GraphQL mutation execution failed`
|
|
867
|
-
- **Solution**: Review GraphQL errors in logs, verify order data structure
|
|
868
|
-
|
|
869
|
-
**4. Slow webhook response**
|
|
870
|
-
- **Error**: Webhook takes >100ms to respond
|
|
871
|
-
- **Solution**: Ensure using sync mode + fire-and-forget pattern (not awaiting background processing)
|
|
872
|
-
|
|
873
|
-
---
|
|
874
|
-
|
|
875
|
-
## STEP 8: Next Steps
|
|
876
|
-
|
|
877
|
-
1. **Customize Mapping**: Edit `src/config/order-mapping.json` for your XML structure
|
|
878
|
-
2. **Add Custom Resolvers**: Extend `customResolvers` in `order-processing.service.ts`
|
|
879
|
-
3. **Enable Audit Trail**: Set `OUTPUT_DIR` activation variable
|
|
880
|
-
4. **Monitor Background Processing**: Check Versori logs for `[BACKGROUND]` tagged messages
|
|
881
|
-
5. **Add Error Notifications**: Integrate with monitoring/alerting systems
|
|
882
|
-
|
|
883
|
-
---
|
|
884
|
-
|
|
885
|
-
**Need Help?**
|
|
886
|
-
- Review SDK documentation: `/docs/readme.md`
|
|
887
|
-
- Check example connectors: `/connectors/Sample versori connectors/`
|
|
888
|
-
- Versori platform documentation: Check your platform's docs
|
|
1
|
+
---
|
|
2
|
+
template_id: tpl-webhook-generic-xml-order
|
|
3
|
+
canonical_filename: template-webhook-generic-xml-order.md
|
|
4
|
+
sdk_version: ^0.1.39
|
|
5
|
+
runtime: versori
|
|
6
|
+
direction: ingestion
|
|
7
|
+
source: webhook-xml
|
|
8
|
+
destination: fluent-graphql
|
|
9
|
+
entity: order
|
|
10
|
+
format: xml
|
|
11
|
+
logging: versori
|
|
12
|
+
status: stable
|
|
13
|
+
features:
|
|
14
|
+
- external-json-config
|
|
15
|
+
- memory-management
|
|
16
|
+
- enhanced-logging
|
|
17
|
+
- audit-trail
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Template: Webhook - Generic XML Order to Fluent GraphQL
|
|
21
|
+
|
|
22
|
+
**SDK Version:** @fluentcommerce/fc-connect-sdk@^0.1.39
|
|
23
|
+
**Last Updated:** 2025-01-24
|
|
24
|
+
**Deployment Target:** Versori Platform
|
|
25
|
+
|
|
26
|
+
**FC Connect SDK Use Case Guide**
|
|
27
|
+
|
|
28
|
+
> **SDK**: [@fluentcommerce/fc-connect-sdk](https://www.npmjs.com/package/@fluentcommerce/fc-connect-sdk)
|
|
29
|
+
> **Version**: Use latest - `npm install @fluentcommerce/fc-connect-sdk@latest`
|
|
30
|
+
|
|
31
|
+
**Context**: Receive generic XML orders via Versori HTTP webhook and create orders in Fluent Commerce using GraphQL mutations.
|
|
32
|
+
|
|
33
|
+
**Complexity**: Medium
|
|
34
|
+
|
|
35
|
+
**Runtime**: Versori Platform
|
|
36
|
+
|
|
37
|
+
**Estimated Lines**: ~600 lines (modular structure)
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## STEP 1: Understand This Template
|
|
42
|
+
|
|
43
|
+
**What This Template Does:**
|
|
44
|
+
|
|
45
|
+
- Versori HTTP webhook endpoint receiving XML order data
|
|
46
|
+
- XML parsing with optional nodes config for nested/escaped XML segments
|
|
47
|
+
- GraphQL mutation mapping from XML structure to Fluent schema
|
|
48
|
+
- Custom resolvers for data transformation and API calls
|
|
49
|
+
- Memory management (clears large XML payloads after mapping)
|
|
50
|
+
- Error handling and structured response formatting
|
|
51
|
+
- Audit trail (save input/output to filesystem for debugging)
|
|
52
|
+
- **Sync + Fire-and-Forget Pattern**: Fast webhook response, background processing
|
|
53
|
+
|
|
54
|
+
**Key SDK Components:**
|
|
55
|
+
|
|
56
|
+
- `createClient()` - Universal client factory (auto-detects Versori context)
|
|
57
|
+
- `GraphQLMutationMapper` - XML/JSON → GraphQL mutation mapping
|
|
58
|
+
- `XMLParserService` - XML parsing with nodes extraction
|
|
59
|
+
- Native Versori `log` - Use `log` from context
|
|
60
|
+
|
|
61
|
+
**Entity Type:**
|
|
62
|
+
|
|
63
|
+
- **Order** - Fluent entity for order creation
|
|
64
|
+
- **GraphQL Mutation** - Uses `createOrder` mutation (not Event API)
|
|
65
|
+
|
|
66
|
+
**Critical Patterns:**
|
|
67
|
+
|
|
68
|
+
- **Sync + Fire-and-Forget**: Webhook validates quickly, returns immediately, processes in background
|
|
69
|
+
- **External JSON Config**: Mapping configuration in separate JSON file (`config/order-mapping.json`)
|
|
70
|
+
- **Modular Architecture**: Separate services, workflows, config, types folders
|
|
71
|
+
- **Memory Management**: Clears large XML payloads from memory after mapping
|
|
72
|
+
- **Background Processing**: Long-running operations (GraphQL mutations) happen asynchronously
|
|
73
|
+
- **Error Handling**: Comprehensive error handling with structured logging and recommendations
|
|
74
|
+
- **Activation Variables**: Configuration via Versori activation variables (OUTPUT_DIR, validateConnectionOnStart)
|
|
75
|
+
|
|
76
|
+
**When to Use This Template:**
|
|
77
|
+
|
|
78
|
+
- ✅ Real-time order ingestion from external systems (SFCC, Shopify, custom)
|
|
79
|
+
- ✅ XML order format (can be adapted for JSON)
|
|
80
|
+
- ✅ Need fast webhook response (don't wait for order creation)
|
|
81
|
+
- ✅ Single order per webhook call
|
|
82
|
+
- ✅ Need audit trail for debugging
|
|
83
|
+
|
|
84
|
+
**When NOT to Use:**
|
|
85
|
+
|
|
86
|
+
- ❌ Bulk order processing (use Batch API or scheduled workflows)
|
|
87
|
+
- ❌ Order updates (use GraphQL `updateOrder` mutation)
|
|
88
|
+
- ❌ CSV/JSON formats (use appropriate format template)
|
|
89
|
+
- ❌ Need synchronous order creation (wait for result before responding)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## STEP 2: Implementation Prompt for Claude Code
|
|
94
|
+
|
|
95
|
+
**Copy this prompt and send to Claude Code to generate the complete implementation:**
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Create a Versori webhook workflow for generic XML order ingestion to Fluent Commerce GraphQL.
|
|
99
|
+
|
|
100
|
+
REQUIREMENTS:
|
|
101
|
+
1. Runtime: Versori Platform (HTTP webhook)
|
|
102
|
+
2. Source: XML order data via HTTP POST webhook
|
|
103
|
+
3. Destination: Fluent Commerce GraphQL API (createOrder mutation)
|
|
104
|
+
4. Format: XML with optional nodes extraction
|
|
105
|
+
5. Entity: Order (GraphQL mutation)
|
|
106
|
+
|
|
107
|
+
KEY FEATURES:
|
|
108
|
+
- Sync + fire-and-forget pattern (fast webhook response, background processing)
|
|
109
|
+
- External JSON mapping configuration (not inline TypeScript)
|
|
110
|
+
- Modular architecture (workflows/, services/, config/, types/)
|
|
111
|
+
- XML parsing with optional nodes config for nested XML segments
|
|
112
|
+
- GraphQLMutationMapper for XML → GraphQL transformation
|
|
113
|
+
- Custom resolvers for data transformation
|
|
114
|
+
- Audit trail (save input/output files)
|
|
115
|
+
- Comprehensive error handling with structured logging
|
|
116
|
+
|
|
117
|
+
CRITICAL REQUIREMENTS:
|
|
118
|
+
1. Webhook Mode: response: { mode: 'sync' } (fast response)
|
|
119
|
+
2. Background Processing: Fire-and-forget pattern (no await on long operations)
|
|
120
|
+
3. Mapping Config: External JSON file (config/order-mapping.json)
|
|
121
|
+
4. Modular Structure: Separate services/, config/, types/ folders
|
|
122
|
+
5. Native Logging: Use log from context (no LoggingService)
|
|
123
|
+
6. Error Handling: Structured error responses with recommendations
|
|
124
|
+
|
|
125
|
+
SDK METHODS TO USE:
|
|
126
|
+
- createClient({ ...ctx, log }) - Pass full Versori context
|
|
127
|
+
- new GraphQLMutationMapper(mappingConfig, log, { fluentClient: client }) - Initialize mapper
|
|
128
|
+
- mapper.mapWithNodes(xmlData, customResolvers, context) - Map XML with custom resolvers (REQUIRED for custom resolvers)
|
|
129
|
+
- mapper.map(xmlData) - Map XML without custom resolvers (built-in SDK resolvers only)
|
|
130
|
+
- mapWithNodes() now returns query automatically (no need for buildMutation())
|
|
131
|
+
- client.graphql({ query, variables }) - Execute GraphQL mutation
|
|
132
|
+
|
|
133
|
+
FORBIDDEN PATTERNS:
|
|
134
|
+
- ❌ Inline mapping config (use external JSON)
|
|
135
|
+
- ❌ await on background processing (use fire-and-forget)
|
|
136
|
+
- ❌ LoggingService (use native log from context)
|
|
137
|
+
- ❌ All code in one file (use modular structure)
|
|
138
|
+
- ❌ async mode webhook (use sync + fire-and-forget)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## STEP 3: Detailed Flow Documentation
|
|
144
|
+
|
|
145
|
+
### Complete Processing Flow
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
149
|
+
│ 1. WEBHOOK RECEIVED │
|
|
150
|
+
│ POST https://{workspace}.versori.run/generic-xml-order │
|
|
151
|
+
│ Content-Type: application/xml │
|
|
152
|
+
│ Body: <Order>...</Order> │
|
|
153
|
+
└────────────────────┬────────────────────────────────────────┘
|
|
154
|
+
│
|
|
155
|
+
▼
|
|
156
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
157
|
+
│ 2. QUICK VALIDATION (Synchronous, ~10-50ms) │
|
|
158
|
+
│ - Check fluent_commerce connection exists │
|
|
159
|
+
│ - Validate XML payload present │
|
|
160
|
+
│ - Return HTTP 200 OK immediately │
|
|
161
|
+
└────────────────────┬────────────────────────────────────────┘
|
|
162
|
+
│
|
|
163
|
+
▼
|
|
164
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
165
|
+
│ 3. BACKGROUND PROCESSING (Fire-and-Forget) │
|
|
166
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
167
|
+
│ │ 3a. Initialize Fluent Client │ │
|
|
168
|
+
│ │ - createClient({ ...ctx, log }) │ │
|
|
169
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
170
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
171
|
+
│ │ 3b. Parse XML (if needed) │ │
|
|
172
|
+
│ │ - Versori auto-parses XML to object │ │
|
|
173
|
+
│ │ - Optional: Extract nested XML segments │ │
|
|
174
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
175
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
176
|
+
│ │ 3c. Map XML to GraphQL Variables │ │
|
|
177
|
+
│ │ - Load mapping config from JSON │ │
|
|
178
|
+
│ │ - GraphQLMutationMapper.mapWithNodes() (REQUIRED for custom resolvers)│ │
|
|
179
|
+
│ │ - Apply custom resolvers │ │
|
|
180
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
181
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
182
|
+
│ │ 3d. Generate GraphQL Mutation │ │
|
|
183
|
+
│ │ - Query returned in result.query │ │
|
|
184
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
185
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
186
|
+
│ │ 3e. Execute GraphQL Mutation │ │
|
|
187
|
+
│ │ - client.graphql({ query, variables }) │ │
|
|
188
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
189
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
190
|
+
│ │ 3f. Save Audit Trail (Optional) │ │
|
|
191
|
+
│ │ - 1-incoming-xml.json │ │
|
|
192
|
+
│ │ - 2-mapped-variables.json │ │
|
|
193
|
+
│ │ - 3-graphql-response.json │ │
|
|
194
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
195
|
+
└─────────────────────────────────────────────────────────────┘
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Response Timing
|
|
199
|
+
|
|
200
|
+
| Stage | Timing | Blocking |
|
|
201
|
+
|-------|--------|----------|
|
|
202
|
+
| **Webhook Validation** | ~10-50ms | ✅ Yes (blocks response) |
|
|
203
|
+
| **Background Processing** | ~500-2000ms | ❌ No (fire-and-forget) |
|
|
204
|
+
| **Total Response Time** | ~10-50ms | ✅ Fast response |
|
|
205
|
+
|
|
206
|
+
**Key Benefit**: Webhook caller receives immediate acknowledgment (~50ms) while order creation happens in background (~2s).
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## STEP 4: Production Modular Structure
|
|
211
|
+
|
|
212
|
+
> **✅ This section shows the COMPLETE production-ready modular structure.**
|
|
213
|
+
> All files are shown with proper imports/exports and folder organization.
|
|
214
|
+
|
|
215
|
+
### Complete Project Structure
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
generic-xml-order-ingestion/
|
|
219
|
+
├── package.json # Dependencies and Versori config
|
|
220
|
+
├── index.ts # Entry point - exports all workflows
|
|
221
|
+
└── src/
|
|
222
|
+
├── workflows/
|
|
223
|
+
│ └── webhook/
|
|
224
|
+
│ └── order-ingestion.ts # Webhook: Receive XML orders
|
|
225
|
+
│
|
|
226
|
+
├── services/
|
|
227
|
+
│ └── order-processing.service.ts # Shared orchestration logic (reusable)
|
|
228
|
+
│
|
|
229
|
+
├── config/
|
|
230
|
+
│ └── order-mapping.json # Mapping configuration (external JSON)
|
|
231
|
+
│
|
|
232
|
+
└── types/
|
|
233
|
+
└── order.types.ts # TypeScript interfaces
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Why This Structure?**
|
|
237
|
+
|
|
238
|
+
- ✅ **Clear separation**: Webhook handlers vs business logic
|
|
239
|
+
- ✅ **Reusable services**: Order processing logic can be reused
|
|
240
|
+
- ✅ **External config**: Mapping changes don't require code changes
|
|
241
|
+
- ✅ **Type safety**: TypeScript interfaces for better IDE support
|
|
242
|
+
- ✅ **Scalable**: Easy to add new webhooks or services
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### File: `package.json`
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"name": "generic-xml-order-ingestion",
|
|
251
|
+
"version": "2.0.0",
|
|
252
|
+
"description": "Generic XML Order Ingestion Webhook to Fluent Commerce",
|
|
253
|
+
"type": "module",
|
|
254
|
+
"versori": {
|
|
255
|
+
"workflows": "./index.ts"
|
|
256
|
+
},
|
|
257
|
+
"scripts": {
|
|
258
|
+
"lint": "eslint . --ext .ts",
|
|
259
|
+
"typecheck": "tsc --noEmit"
|
|
260
|
+
},
|
|
261
|
+
"dependencies": {
|
|
262
|
+
"@fluentcommerce/fc-connect-sdk": "^0.1.39",
|
|
263
|
+
"@versori/run": "latest"
|
|
264
|
+
},
|
|
265
|
+
"devDependencies": {
|
|
266
|
+
"@types/node": "^20.0.0",
|
|
267
|
+
"typescript": "^5.0.0"
|
|
268
|
+
},
|
|
269
|
+
"engines": {
|
|
270
|
+
"node": ">=18.0.0"
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
### File: `index.ts`
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
/**
|
|
281
|
+
* Entry point - Export all workflows for Versori platform
|
|
282
|
+
*
|
|
283
|
+
* This file exports all workflows to be registered with Versori.
|
|
284
|
+
* Each workflow is defined in its own file for better organization.
|
|
285
|
+
*/
|
|
286
|
+
|
|
287
|
+
export { genericXmlOrder } from './src/workflows/webhook/order-ingestion';
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
### File: `src/types/order.types.ts`
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
/**
|
|
296
|
+
* Type definitions for order ingestion
|
|
297
|
+
*/
|
|
298
|
+
export interface OrderIngestionResult {
|
|
299
|
+
success: boolean;
|
|
300
|
+
orderId?: string;
|
|
301
|
+
orderRef?: string;
|
|
302
|
+
error?: string;
|
|
303
|
+
recommendation?: string;
|
|
304
|
+
timestamp: string;
|
|
305
|
+
duration: number;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export interface OrderMappingConfig {
|
|
309
|
+
mutation: string;
|
|
310
|
+
sourceFormat: 'xml' | 'json';
|
|
311
|
+
nodes?: {
|
|
312
|
+
[key: string]: {
|
|
313
|
+
extract: string;
|
|
314
|
+
parse: 'xml' | 'json';
|
|
315
|
+
required: boolean;
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
fields: {
|
|
319
|
+
[key: string]: any;
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### File: `src/config/order-mapping.json`
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"mutation": "createOrder",
|
|
331
|
+
"sourceFormat": "xml",
|
|
332
|
+
"returnFields": ["id", "ref", "status"],
|
|
333
|
+
"nodes": {
|
|
334
|
+
"order": {
|
|
335
|
+
"extract": "Envelope.Body.OrderEnvelope",
|
|
336
|
+
"parse": "xml",
|
|
337
|
+
"required": false
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
"fields": {
|
|
341
|
+
"ref": {
|
|
342
|
+
"source": "$order.Order@id",
|
|
343
|
+
"resolver": "sdk.toString",
|
|
344
|
+
"required": true
|
|
345
|
+
},
|
|
346
|
+
"type": {
|
|
347
|
+
"source": "$order.Order@type",
|
|
348
|
+
"defaultValue": "HD"
|
|
349
|
+
},
|
|
350
|
+
"retailer": {
|
|
351
|
+
"fields": {
|
|
352
|
+
"id": {
|
|
353
|
+
"value": "2"
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
"customer": {
|
|
358
|
+
"fields": {
|
|
359
|
+
"firstName": {
|
|
360
|
+
"source": "$order.Order.Customer.FirstName"
|
|
361
|
+
},
|
|
362
|
+
"lastName": {
|
|
363
|
+
"source": "$order.Order.Customer.LastName"
|
|
364
|
+
},
|
|
365
|
+
"username": {
|
|
366
|
+
"source": "$order.Order.Customer.Email",
|
|
367
|
+
"resolver": "sdk.lowercase"
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"items": {
|
|
372
|
+
"source": "$order.Order.Items.Item",
|
|
373
|
+
"isArray": true,
|
|
374
|
+
"fields": {
|
|
375
|
+
"ref": {
|
|
376
|
+
"source": "$.@id",
|
|
377
|
+
"resolver": "sdk.toString"
|
|
378
|
+
},
|
|
379
|
+
"productRef": {
|
|
380
|
+
"source": "$.Sku",
|
|
381
|
+
"resolver": "sdk.toString"
|
|
382
|
+
},
|
|
383
|
+
"quantity": {
|
|
384
|
+
"source": "$.Quantity",
|
|
385
|
+
"resolver": "sdk.parseInt"
|
|
386
|
+
},
|
|
387
|
+
"price": {
|
|
388
|
+
"source": "$.Price",
|
|
389
|
+
"resolver": "sdk.parseFloat"
|
|
390
|
+
},
|
|
391
|
+
"currency": {
|
|
392
|
+
"source": "$order.Order.Currency",
|
|
393
|
+
"defaultValue": "USD"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
"totalPrice": {
|
|
398
|
+
"source": "$order.Order.Totals.Subtotal",
|
|
399
|
+
"resolver": "sdk.parseFloat"
|
|
400
|
+
},
|
|
401
|
+
"totalTaxPrice": {
|
|
402
|
+
"source": "$order.Order.Totals.Tax",
|
|
403
|
+
"resolver": "sdk.parseFloat",
|
|
404
|
+
"defaultValue": 0
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
### File: `src/services/order-processing.service.ts`
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
/**
|
|
416
|
+
* Order Processing Service
|
|
417
|
+
*
|
|
418
|
+
* Orchestrates the complete order ingestion process:
|
|
419
|
+
* 1. Validate webhook payload
|
|
420
|
+
* 2. Extract and parse nested XML (if needed)
|
|
421
|
+
* 3. Apply field mapping with custom resolvers
|
|
422
|
+
* 4. Create order via GraphQL API
|
|
423
|
+
* 5. Audit trail (save input/output files)
|
|
424
|
+
*/
|
|
425
|
+
|
|
426
|
+
import { Buffer } from 'node:buffer';
|
|
427
|
+
import { createClient, GraphQLMutationMapper, classifyErrors } from '@fluentcommerce/fc-connect-sdk';
|
|
428
|
+
import type { OrderIngestionResult } from '../types/order.types';
|
|
429
|
+
import mappingConfig from '../config/order-mapping.json' with { type: 'json' };
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Process order ingestion (background processing)
|
|
433
|
+
*
|
|
434
|
+
* @param ctx - Versori context object containing fetch, connections, log, activation, data
|
|
435
|
+
* @param xmlData - Parsed XML order data
|
|
436
|
+
* @param executionStartTime - Workflow start time for duration tracking
|
|
437
|
+
*/
|
|
438
|
+
export async function processOrderInBackground(
|
|
439
|
+
ctx: any,
|
|
440
|
+
xmlData: any,
|
|
441
|
+
executionStartTime: number
|
|
442
|
+
): Promise<OrderIngestionResult> {
|
|
443
|
+
const { log, activation, connections, openKv } = ctx;
|
|
444
|
+
|
|
445
|
+
try {
|
|
446
|
+
log.info('🔄 [BACKGROUND] Starting background order processing', {
|
|
447
|
+
correlationId: activation?.id,
|
|
448
|
+
timestamp: new Date().toISOString(),
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// ========================================
|
|
452
|
+
// STEP 2: CLIENT INITIALIZATION
|
|
453
|
+
// ========================================
|
|
454
|
+
|
|
455
|
+
// Optional: Validate connection immediately (fail-fast mode for webhooks)
|
|
456
|
+
// Set activation variable 'validateConnectionOnStart' = 'true' to enable
|
|
457
|
+
const validateConnection = activation?.getVariable('validateConnectionOnStart') === 'true';
|
|
458
|
+
|
|
459
|
+
if (validateConnection) {
|
|
460
|
+
log.info('🔍 [BACKGROUND] Connection validation enabled', {
|
|
461
|
+
note: 'This executes query { me { ref } } to verify authentication',
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const client = await createClient(ctx, validateConnection ? { validateConnection: true } : undefined);
|
|
466
|
+
|
|
467
|
+
if (validateConnection) {
|
|
468
|
+
log.info('✅ [BACKGROUND] Connection validated successfully - authentication confirmed');
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
log.info('🔌 [BACKGROUND] Fluent client initialized');
|
|
472
|
+
|
|
473
|
+
// ========================================
|
|
474
|
+
// STEP 3: MAPPING AND TRANSFORMATION
|
|
475
|
+
// ========================================
|
|
476
|
+
|
|
477
|
+
log.info('🔄 [BACKGROUND] Applying mapping');
|
|
478
|
+
|
|
479
|
+
// Apply mapping with optional nodes processing
|
|
480
|
+
// RESOLVERS: Custom transformation logic (async allowed)
|
|
481
|
+
// CONTEXT: Pass fluentClient to resolvers for API calls
|
|
482
|
+
const mapper = new GraphQLMutationMapper(mappingConfig as any, log, { fluentClient: client as any });
|
|
483
|
+
|
|
484
|
+
// Optional custom resolvers
|
|
485
|
+
const customResolvers = {
|
|
486
|
+
'custom.ensureRef': (value: any) => String(value || `ORD-${Date.now()}`),
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// Use mapWithNodes() when custom resolvers are present (REQUIRED)
|
|
490
|
+
// map() does NOT accept custom resolvers parameter
|
|
491
|
+
// Returns MapWithNodesResult with query auto-generated!
|
|
492
|
+
const result = await mapper.mapWithNodes(xmlData, customResolvers as any, {
|
|
493
|
+
fluentClient: client as any,
|
|
494
|
+
config: {},
|
|
495
|
+
helpers: { fluentClient: client as any, logger: log },
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
if (!result.success) {
|
|
499
|
+
log.error('❌ [BACKGROUND] Mapping failed', {
|
|
500
|
+
errors: result.errors,
|
|
501
|
+
errorCount: result.errors?.length || 0,
|
|
502
|
+
});
|
|
503
|
+
return {
|
|
504
|
+
success: false,
|
|
505
|
+
error: 'Mapping validation failed',
|
|
506
|
+
recommendation: 'Check mapping configuration JSON and verify source paths match incoming XML structure',
|
|
507
|
+
timestamp: new Date().toISOString(),
|
|
508
|
+
duration: Date.now() - executionStartTime,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const orderRef = (result.data as any)?.input?.ref || 'unknown';
|
|
513
|
+
log.info('✅ [BACKGROUND] Mapping completed', {
|
|
514
|
+
orderRef,
|
|
515
|
+
fieldsCount: Object.keys((result.data as any)?.input || {}).length,
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
// ========================================
|
|
519
|
+
// STEP 4: AUDIT TRAIL (SAVE INPUT DATA)
|
|
520
|
+
// ========================================
|
|
521
|
+
|
|
522
|
+
// Save audit trail to KV storage (Versori-compatible - file system is read-only)
|
|
523
|
+
try {
|
|
524
|
+
const kv = openKv(':project:');
|
|
525
|
+
const timestamp = new Date().toISOString();
|
|
526
|
+
const auditKey = ['orders', 'audit', orderRef, timestamp];
|
|
527
|
+
|
|
528
|
+
// Save 1: Original XML (parsed by Versori) - save BEFORE memory cleanup
|
|
529
|
+
await kv.set([...auditKey, 'incoming-xml'], xmlData);
|
|
530
|
+
|
|
531
|
+
// Save 2: Mapped Fluent variables (ready for GraphQL)
|
|
532
|
+
await kv.set([...auditKey, 'mapped-variables'], result.data);
|
|
533
|
+
|
|
534
|
+
log.info('Audit trail saved to KV storage', { orderRef, timestamp });
|
|
535
|
+
} catch (kvError: any) {
|
|
536
|
+
log.warn('Failed to save audit trail to KV', {
|
|
537
|
+
error: kvError.message,
|
|
538
|
+
note: 'Continuing with order creation',
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// ✅ PRODUCTION: Memory cleanup for large XML payloads (after saving audit trail)
|
|
543
|
+
try {
|
|
544
|
+
if (xmlData && typeof xmlData === 'object') {
|
|
545
|
+
// Clear large XML data from memory after mapping and audit trail
|
|
546
|
+
Object.keys(xmlData).forEach(key => delete (xmlData as any)[key]);
|
|
547
|
+
}
|
|
548
|
+
} catch (cleanupError) {
|
|
549
|
+
// Non-blocking - continue processing
|
|
550
|
+
log.debug('Memory cleanup skipped', { note: 'Non-critical' });
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// ========================================
|
|
554
|
+
// STEP 5: CREATE ORDER VIA GRAPHQL API
|
|
555
|
+
// ========================================
|
|
556
|
+
|
|
557
|
+
log.info('📡 [BACKGROUND] Creating order in Fluent Commerce', { orderRef });
|
|
558
|
+
|
|
559
|
+
// mapWithNodes() now auto-generates query - no need to call buildMutation()!
|
|
560
|
+
log.info('📝 [BACKGROUND] GraphQL mutation auto-generated', { orderRef });
|
|
561
|
+
|
|
562
|
+
// Execute mutation (query is auto-generated in result)
|
|
563
|
+
log.info('🚀 [BACKGROUND] Executing GraphQL mutation', { orderRef });
|
|
564
|
+
const response = await client.graphql({
|
|
565
|
+
query: result.query,
|
|
566
|
+
variables: result.variables // ✅ Use variables (wrapped if fields pattern)
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
if (response.errors?.length) {
|
|
570
|
+
// Classify GraphQL errors to determine retry strategy
|
|
571
|
+
const classification = classifyErrors(response.errors);
|
|
572
|
+
|
|
573
|
+
log.error('❌ [BACKGROUND] GraphQL execution errors', {
|
|
574
|
+
orderRef,
|
|
575
|
+
errorCode: classification.errorCode,
|
|
576
|
+
retryable: classification.retryable,
|
|
577
|
+
action: classification.action,
|
|
578
|
+
message: classification.userMessage,
|
|
579
|
+
errors: response.errors,
|
|
580
|
+
errorCount: response.errors.length,
|
|
581
|
+
});
|
|
582
|
+
return {
|
|
583
|
+
success: false,
|
|
584
|
+
error: 'GraphQL mutation execution failed',
|
|
585
|
+
recommendation: 'Review GraphQL errors and verify order data structure',
|
|
586
|
+
timestamp: new Date().toISOString(),
|
|
587
|
+
duration: Date.now() - executionStartTime,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const orderId = response.data?.createOrder?.id;
|
|
592
|
+
log.info('✅ [BACKGROUND] Order created successfully', {
|
|
593
|
+
orderRef,
|
|
594
|
+
orderId,
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// Save GraphQL response to audit trail (KV storage)
|
|
598
|
+
try {
|
|
599
|
+
const kv = openKv(':project:');
|
|
600
|
+
const timestamp = new Date().toISOString();
|
|
601
|
+
const auditKey = ['orders', 'audit', orderRef, timestamp, 'graphql-response'];
|
|
602
|
+
await kv.set(auditKey, response);
|
|
603
|
+
log.info('GraphQL response saved to KV storage', { orderRef, timestamp });
|
|
604
|
+
} catch (kvError: any) {
|
|
605
|
+
log.warn('Failed to save GraphQL response to KV', {
|
|
606
|
+
error: kvError.message,
|
|
607
|
+
note: 'Non-critical',
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Duration tracking
|
|
612
|
+
const duration = Date.now() - executionStartTime;
|
|
613
|
+
log.info('🎉 [BACKGROUND] Order processed successfully', {
|
|
614
|
+
orderRef,
|
|
615
|
+
orderId,
|
|
616
|
+
duration: `${duration}ms`,
|
|
617
|
+
timestamp: new Date().toISOString(),
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
return {
|
|
621
|
+
success: true,
|
|
622
|
+
orderId,
|
|
623
|
+
orderRef,
|
|
624
|
+
timestamp: new Date().toISOString(),
|
|
625
|
+
duration,
|
|
626
|
+
};
|
|
627
|
+
} catch (error: any) {
|
|
628
|
+
const duration = Date.now() - executionStartTime;
|
|
629
|
+
log.error('❌ [BACKGROUND] Unhandled error in order processing', {
|
|
630
|
+
error: error instanceof Error ? error.message : String(error),
|
|
631
|
+
errorType: error instanceof Error ? error.constructor.name : 'Error',
|
|
632
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
633
|
+
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
634
|
+
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
635
|
+
: error.message?.includes('mapping') || error.message?.includes('field')
|
|
636
|
+
? 'Check mapping configuration JSON and verify source paths match incoming XML structure'
|
|
637
|
+
: error.message?.includes('connection') || error.message?.includes('timeout')
|
|
638
|
+
? 'Check network connectivity and Fluent Commerce API availability'
|
|
639
|
+
: error.message?.includes('validation') || error.message?.includes('required')
|
|
640
|
+
? 'Ensure all required fields are present in the webhook payload'
|
|
641
|
+
: 'Review error details and check webhook payload structure',
|
|
642
|
+
correlationId: activation?.id,
|
|
643
|
+
duration,
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
return {
|
|
647
|
+
success: false,
|
|
648
|
+
error: error instanceof Error ? error.message : String(error),
|
|
649
|
+
recommendation: error.message?.includes('authentication') || error.message?.includes('401')
|
|
650
|
+
? 'Verify fluent_commerce connection and OAuth2 credentials in Connections section'
|
|
651
|
+
: 'Review error details and check webhook payload structure',
|
|
652
|
+
timestamp: new Date().toISOString(),
|
|
653
|
+
duration,
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
### File: `src/workflows/webhook/order-ingestion.ts`
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
/**
|
|
665
|
+
* Generic XML Order Ingestion Webhook
|
|
666
|
+
*
|
|
667
|
+
* Versori Endpoint: POST https://{workspace}.versori.run/generic-xml-order
|
|
668
|
+
* Content-Type: application/xml
|
|
669
|
+
*
|
|
670
|
+
* Pattern: Sync + Fire-and-Forget
|
|
671
|
+
* - Quick validation (synchronous)
|
|
672
|
+
* - Background processing (fire-and-forget)
|
|
673
|
+
* - Fast webhook response (~10-50ms)
|
|
674
|
+
*/
|
|
675
|
+
|
|
676
|
+
import { webhook, http } from '@versori/run';
|
|
677
|
+
import type { Context } from '@versori/run';
|
|
678
|
+
import { processOrderInBackground } from '../../services/order-processing.service';
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Generic XML Order Ingestion Webhook
|
|
682
|
+
*
|
|
683
|
+
* Sync mode: Response sent when handler returns
|
|
684
|
+
* Fire-and-forget: Background processing continues after response
|
|
685
|
+
*/
|
|
686
|
+
export const genericXmlOrder = webhook('generic-xml-order', {
|
|
687
|
+
response: { mode: 'sync' }, // ✅ Sync mode: response sent when handler returns
|
|
688
|
+
}).then(
|
|
689
|
+
http('validate-and-process', { connection: 'fluent_commerce' }, async (ctx: Context<any>) => {
|
|
690
|
+
const { log, activation, connections, data } = ctx;
|
|
691
|
+
const executionStartTime = Date.now();
|
|
692
|
+
|
|
693
|
+
log.info('🚀 [WEBHOOK] Received generic XML order webhook', {
|
|
694
|
+
correlationId: activation?.id,
|
|
695
|
+
timestamp: new Date().toISOString(),
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
// Quick validation (synchronous)
|
|
699
|
+
if (!connections || !connections.fluent_commerce) {
|
|
700
|
+
log.error('❌ [WEBHOOK] Configuration error: Missing fluent_commerce connection', {
|
|
701
|
+
recommendation: 'Configure fluent_commerce connection in Connections section with OAuth2 credentials',
|
|
702
|
+
});
|
|
703
|
+
return {
|
|
704
|
+
status: 500,
|
|
705
|
+
body: {
|
|
706
|
+
success: false,
|
|
707
|
+
message: 'Missing fluent_commerce connection',
|
|
708
|
+
recommendation: 'Configure fluent_commerce connection in Connections section with OAuth2 credentials',
|
|
709
|
+
timestamp: new Date().toISOString(),
|
|
710
|
+
},
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// Get webhook payload (Versori pre-parses XML)
|
|
715
|
+
const xmlData = activation.body || data;
|
|
716
|
+
|
|
717
|
+
if (!xmlData) {
|
|
718
|
+
log.error('❌ [WEBHOOK] Validation error: No XML data received in webhook', {
|
|
719
|
+
recommendation: 'Ensure webhook payload contains valid XML order data',
|
|
720
|
+
});
|
|
721
|
+
return {
|
|
722
|
+
status: 400,
|
|
723
|
+
body: {
|
|
724
|
+
success: false,
|
|
725
|
+
message: 'No XML data received',
|
|
726
|
+
recommendation: 'Ensure webhook payload contains valid XML order data',
|
|
727
|
+
timestamp: new Date().toISOString(),
|
|
728
|
+
},
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
log.info('✅ [WEBHOOK] Validation passed, starting background processing', {
|
|
733
|
+
correlationId: activation?.id,
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
// ✅ Fire-and-forget: Start background processing WITHOUT await
|
|
737
|
+
// The promise continues execution after we return the response
|
|
738
|
+
processOrderInBackground(ctx, xmlData, executionStartTime)
|
|
739
|
+
.then((result) => {
|
|
740
|
+
if (result.success) {
|
|
741
|
+
log.info('✅ [BACKGROUND] Order processing completed successfully', {
|
|
742
|
+
orderId: result.orderId,
|
|
743
|
+
orderRef: result.orderRef,
|
|
744
|
+
duration: result.duration,
|
|
745
|
+
correlationId: activation?.id,
|
|
746
|
+
});
|
|
747
|
+
} else {
|
|
748
|
+
log.error('❌ [BACKGROUND] Order processing failed', {
|
|
749
|
+
error: result.error,
|
|
750
|
+
recommendation: result.recommendation,
|
|
751
|
+
correlationId: activation?.id,
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
})
|
|
755
|
+
.catch((error: unknown) => {
|
|
756
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
757
|
+
log.error('❌ [BACKGROUND] Order processing failed with exception', {
|
|
758
|
+
error: errorMessage,
|
|
759
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
760
|
+
errorType: error instanceof Error ? error.constructor.name : typeof error,
|
|
761
|
+
correlationId: activation?.id,
|
|
762
|
+
});
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
// Return immediately (response sent with this return value)
|
|
766
|
+
return {
|
|
767
|
+
status: 200,
|
|
768
|
+
body: {
|
|
769
|
+
success: true,
|
|
770
|
+
message: 'Order ingestion started in background',
|
|
771
|
+
timestamp: new Date().toISOString(),
|
|
772
|
+
},
|
|
773
|
+
};
|
|
774
|
+
})
|
|
775
|
+
);
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## STEP 5: Configuration
|
|
781
|
+
|
|
782
|
+
### Activation Variables
|
|
783
|
+
|
|
784
|
+
Configure these in Versori Activation Variables:
|
|
785
|
+
|
|
786
|
+
| Variable | Description | Required | Default | Example |
|
|
787
|
+
|----------|-------------|----------|---------|---------|
|
|
788
|
+
| `OUTPUT_DIR` | Directory for audit trail files | No | `./output` | `./audit-trail` |
|
|
789
|
+
| `validateConnectionOnStart` | Validate Fluent connection on startup (fail-fast mode) | No | `false` | `true` |
|
|
790
|
+
|
|
791
|
+
**Usage in Code:**
|
|
792
|
+
```typescript
|
|
793
|
+
const outputDir = activation?.getVariable('OUTPUT_DIR') || './output';
|
|
794
|
+
const validateConnection = activation?.getVariable('validateConnectionOnStart') === 'true';
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
### Connection Configuration
|
|
798
|
+
|
|
799
|
+
**Required Connection:** `fluent_commerce`
|
|
800
|
+
|
|
801
|
+
- **Type**: OAuth2
|
|
802
|
+
- **Credentials**: Client ID, Client Secret, Base URL
|
|
803
|
+
- **Scope**: Order creation permissions
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
## STEP 6: Testing
|
|
808
|
+
|
|
809
|
+
### Test Webhook Request
|
|
810
|
+
|
|
811
|
+
```bash
|
|
812
|
+
curl -X POST https://{workspace}.versori.run/generic-xml-order \
|
|
813
|
+
-H "Content-Type: application/xml" \
|
|
814
|
+
-d '<Order>
|
|
815
|
+
<Order id="ORD-001" type="HD">
|
|
816
|
+
<Customer>
|
|
817
|
+
<FirstName>John</FirstName>
|
|
818
|
+
<LastName>Doe</LastName>
|
|
819
|
+
<Email>john.doe@example.com</Email>
|
|
820
|
+
</Customer>
|
|
821
|
+
<Items>
|
|
822
|
+
<Item id="ITEM-001">
|
|
823
|
+
<Sku>SKU-12345</Sku>
|
|
824
|
+
<Quantity>2</Quantity>
|
|
825
|
+
<Price>29.99</Price>
|
|
826
|
+
</Item>
|
|
827
|
+
</Items>
|
|
828
|
+
<Totals>
|
|
829
|
+
<Subtotal>59.98</Subtotal>
|
|
830
|
+
<Tax>4.80</Tax>
|
|
831
|
+
</Totals>
|
|
832
|
+
<Currency>USD</Currency>
|
|
833
|
+
</Order>
|
|
834
|
+
</Order>'
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
### Expected Response
|
|
838
|
+
|
|
839
|
+
```json
|
|
840
|
+
{
|
|
841
|
+
"success": true,
|
|
842
|
+
"message": "Order ingestion started in background",
|
|
843
|
+
"timestamp": "2025-01-25T10:30:00.000Z"
|
|
844
|
+
}
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
**Response Time**: ~10-50ms (fast acknowledgment)
|
|
848
|
+
|
|
849
|
+
**Background Processing**: Order creation happens asynchronously (~500-2000ms)
|
|
850
|
+
|
|
851
|
+
---
|
|
852
|
+
|
|
853
|
+
## STEP 7: Troubleshooting
|
|
854
|
+
|
|
855
|
+
### Common Issues
|
|
856
|
+
|
|
857
|
+
**1. Missing fluent_commerce connection**
|
|
858
|
+
- **Error**: `Missing fluent_commerce connection`
|
|
859
|
+
- **Solution**: Configure `fluent_commerce` connection in Versori Connections section
|
|
860
|
+
|
|
861
|
+
**2. Mapping validation failed**
|
|
862
|
+
- **Error**: `Mapping validation failed`
|
|
863
|
+
- **Solution**: Check `config/order-mapping.json` and verify source paths match XML structure
|
|
864
|
+
|
|
865
|
+
**3. GraphQL execution errors**
|
|
866
|
+
- **Error**: `GraphQL mutation execution failed`
|
|
867
|
+
- **Solution**: Review GraphQL errors in logs, verify order data structure
|
|
868
|
+
|
|
869
|
+
**4. Slow webhook response**
|
|
870
|
+
- **Error**: Webhook takes >100ms to respond
|
|
871
|
+
- **Solution**: Ensure using sync mode + fire-and-forget pattern (not awaiting background processing)
|
|
872
|
+
|
|
873
|
+
---
|
|
874
|
+
|
|
875
|
+
## STEP 8: Next Steps
|
|
876
|
+
|
|
877
|
+
1. **Customize Mapping**: Edit `src/config/order-mapping.json` for your XML structure
|
|
878
|
+
2. **Add Custom Resolvers**: Extend `customResolvers` in `order-processing.service.ts`
|
|
879
|
+
3. **Enable Audit Trail**: Set `OUTPUT_DIR` activation variable
|
|
880
|
+
4. **Monitor Background Processing**: Check Versori logs for `[BACKGROUND]` tagged messages
|
|
881
|
+
5. **Add Error Notifications**: Integrate with monitoring/alerting systems
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
**Need Help?**
|
|
886
|
+
- Review SDK documentation: `/docs/readme.md`
|
|
887
|
+
- Check example connectors: `/connectors/Sample versori connectors/`
|
|
888
|
+
- Versori platform documentation: Check your platform's docs
|