@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,653 +1,653 @@
|
|
|
1
|
-
# Module 7: Monitoring
|
|
2
|
-
|
|
3
|
-
**Level:** Advanced
|
|
4
|
-
**Estimated Time:** 20 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module covers effective logging and monitoring strategies for error handling, including structured logging, metrics collection, and alerting patterns.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Implement structured error logging with full context
|
|
14
|
-
- ✅ Use `error.toJSON()` for complete error serialization
|
|
15
|
-
- ✅ Build error metrics and monitoring dashboards
|
|
16
|
-
- ✅ Set up alerting for high error rates
|
|
17
|
-
- ✅ Integrate with external monitoring systems
|
|
18
|
-
|
|
19
|
-
## Structured Logging
|
|
20
|
-
|
|
21
|
-
### Logging Setup
|
|
22
|
-
|
|
23
|
-
**First, configure logging based on your runtime:**
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
// Standalone (Node.js/Deno)
|
|
27
|
-
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
28
|
-
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
29
|
-
service: 'ErrorMonitoring',
|
|
30
|
-
environment: process.env.NODE_ENV
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Versori Platform
|
|
34
|
-
const { log: logger } = ctx; // Use native platform log
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Using error.toJSON()
|
|
38
|
-
|
|
39
|
-
All SDK errors provide a `toJSON()` method for structured logging:
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
import {
|
|
43
|
-
IngestionError,
|
|
44
|
-
MappingError,
|
|
45
|
-
createConsoleLogger,
|
|
46
|
-
toStructuredLogger
|
|
47
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
48
|
-
|
|
49
|
-
// Standalone
|
|
50
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'FileProcessor' });
|
|
51
|
-
|
|
52
|
-
// Versori Platform
|
|
53
|
-
// const { log: logger } = ctx;
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
await processFile(fileName);
|
|
57
|
-
} catch (error) {
|
|
58
|
-
if (error instanceof IngestionError) {
|
|
59
|
-
// Full structured error data
|
|
60
|
-
const errorData = error.toJSON();
|
|
61
|
-
|
|
62
|
-
logger.error('File processing failed:', errorData);
|
|
63
|
-
/*
|
|
64
|
-
{
|
|
65
|
-
name: "FileParsingError",
|
|
66
|
-
message: "Failed to parse XML: Unclosed tag 'order'",
|
|
67
|
-
code: "PARSE_ERROR",
|
|
68
|
-
fileName: "order-12345.xml",
|
|
69
|
-
lineNumber: 42,
|
|
70
|
-
context: { ... },
|
|
71
|
-
timestamp: "2025-01-10T12:34:56.789Z",
|
|
72
|
-
correlationId: "abc-123-def",
|
|
73
|
-
stack: "Error: ...\n at ..."
|
|
74
|
-
}
|
|
75
|
-
*/
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Adding Business Context
|
|
81
|
-
|
|
82
|
-
Enrich errors with business-specific information:
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
try {
|
|
86
|
-
await processOrder(xmlContent);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
const enrichedLog = {
|
|
89
|
-
// Base error data
|
|
90
|
-
...(error instanceof IngestionError ? error.toJSON() : { message: error.message }),
|
|
91
|
-
|
|
92
|
-
// Business context
|
|
93
|
-
orderId: metadata.orderId,
|
|
94
|
-
customerId: metadata.customerId,
|
|
95
|
-
source: metadata.source,
|
|
96
|
-
environment: process.env.NODE_ENV,
|
|
97
|
-
appVersion: process.env.APP_VERSION,
|
|
98
|
-
|
|
99
|
-
// Additional tracking
|
|
100
|
-
traceId: generateTraceId(),
|
|
101
|
-
sessionId: context.sessionId
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
logger.error('Order processing failed:', enrichedLog);
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Correlation IDs
|
|
109
|
-
|
|
110
|
-
Use correlation IDs to track errors across distributed systems:
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
114
|
-
|
|
115
|
-
async function processWithCorrelation(data: any, correlationId?: string) {
|
|
116
|
-
const id = correlationId || uuidv4();
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
logger.info('Processing started', { correlationId: id });
|
|
120
|
-
|
|
121
|
-
const result = await process(data);
|
|
122
|
-
|
|
123
|
-
logger.info('Processing completed', { correlationId: id });
|
|
124
|
-
return result;
|
|
125
|
-
|
|
126
|
-
} catch (error) {
|
|
127
|
-
const errorData = error instanceof IngestionError
|
|
128
|
-
? error.toJSON()
|
|
129
|
-
: { message: error.message };
|
|
130
|
-
|
|
131
|
-
logger.error('Processing failed', {
|
|
132
|
-
...errorData,
|
|
133
|
-
correlationId: id
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
throw error;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Error Metrics Collection
|
|
142
|
-
|
|
143
|
-
### Basic Error Counter
|
|
144
|
-
|
|
145
|
-
Track error counts by type:
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
import {
|
|
149
|
-
IngestionError,
|
|
150
|
-
MappingError,
|
|
151
|
-
PathResolutionError,
|
|
152
|
-
FluentAPIError,
|
|
153
|
-
AuthenticationError,
|
|
154
|
-
GraphQLExecutionError
|
|
155
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
156
|
-
|
|
157
|
-
class ErrorMetrics {
|
|
158
|
-
private errorCounts = new Map<string, number>();
|
|
159
|
-
private lastErrors = new Map<string, Date>();
|
|
160
|
-
|
|
161
|
-
recordError(error: Error): void {
|
|
162
|
-
let errorType = 'UNKNOWN';
|
|
163
|
-
|
|
164
|
-
if (error instanceof FluentAPIError) {
|
|
165
|
-
errorType = `API_ERROR_${error.statusCode}`;
|
|
166
|
-
} else if (error instanceof AuthenticationError) {
|
|
167
|
-
errorType = 'AUTH_ERROR';
|
|
168
|
-
} else if (error instanceof GraphQLExecutionError) {
|
|
169
|
-
errorType = 'GRAPHQL_ERROR';
|
|
170
|
-
} else if (error instanceof IngestionError) {
|
|
171
|
-
errorType = error.code;
|
|
172
|
-
} else if (error instanceof MappingError) {
|
|
173
|
-
errorType = 'MAPPING_ERROR';
|
|
174
|
-
} else if (error instanceof PathResolutionError) {
|
|
175
|
-
errorType = 'PATH_RESOLUTION_ERROR';
|
|
176
|
-
} else if (error instanceof FileParsingError) {
|
|
177
|
-
errorType = 'FILE_PARSING_ERROR';
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Increment counter
|
|
181
|
-
const count = this.errorCounts.get(errorType) || 0;
|
|
182
|
-
this.errorCounts.set(errorType, count + 1);
|
|
183
|
-
|
|
184
|
-
// Update last occurrence
|
|
185
|
-
this.lastErrors.set(errorType, new Date());
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
getMetrics() {
|
|
189
|
-
return {
|
|
190
|
-
errorCounts: Object.fromEntries(this.errorCounts),
|
|
191
|
-
lastErrors: Object.fromEntries(this.lastErrors),
|
|
192
|
-
timestamp: new Date().toISOString()
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
reset(): void {
|
|
197
|
-
this.errorCounts.clear();
|
|
198
|
-
this.lastErrors.clear();
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Usage
|
|
203
|
-
const metrics = new ErrorMetrics();
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
await processFile(fileName);
|
|
207
|
-
} catch (error) {
|
|
208
|
-
metrics.recordError(error);
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Get metrics periodically
|
|
213
|
-
setInterval(() => {
|
|
214
|
-
logger.info('Error metrics', metrics.getMetrics());
|
|
215
|
-
}, 60000); // Every minute
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Advanced Metrics with Rates
|
|
219
|
-
|
|
220
|
-
Track error rates over time windows:
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
interface TimeWindow {
|
|
224
|
-
start: Date;
|
|
225
|
-
end: Date;
|
|
226
|
-
errors: Map<string, number>;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
class AdvancedErrorMetrics {
|
|
230
|
-
private windows: TimeWindow[] = [];
|
|
231
|
-
private windowSizeMs: number;
|
|
232
|
-
private maxWindows: number;
|
|
233
|
-
|
|
234
|
-
constructor(windowSizeMs = 60000, maxWindows = 60) {
|
|
235
|
-
this.windowSizeMs = windowSizeMs;
|
|
236
|
-
this.maxWindows = maxWindows;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
recordError(error: Error): void {
|
|
240
|
-
const now = new Date();
|
|
241
|
-
const errorType = this.getErrorType(error);
|
|
242
|
-
|
|
243
|
-
// Get or create current window
|
|
244
|
-
let currentWindow = this.windows[this.windows.length - 1];
|
|
245
|
-
|
|
246
|
-
if (!currentWindow || now.getTime() - currentWindow.start.getTime() >= this.windowSizeMs) {
|
|
247
|
-
// Create new window
|
|
248
|
-
currentWindow = {
|
|
249
|
-
start: now,
|
|
250
|
-
end: new Date(now.getTime() + this.windowSizeMs),
|
|
251
|
-
errors: new Map()
|
|
252
|
-
};
|
|
253
|
-
this.windows.push(currentWindow);
|
|
254
|
-
|
|
255
|
-
// Trim old windows
|
|
256
|
-
if (this.windows.length > this.maxWindows) {
|
|
257
|
-
this.windows.shift();
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Increment error count in current window
|
|
262
|
-
const count = currentWindow.errors.get(errorType) || 0;
|
|
263
|
-
currentWindow.errors.set(errorType, count + 1);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
getErrorRate(errorType: string, periodMinutes = 5): number {
|
|
267
|
-
const periodMs = periodMinutes * 60 * 1000;
|
|
268
|
-
const now = Date.now();
|
|
269
|
-
let totalErrors = 0;
|
|
270
|
-
|
|
271
|
-
for (const window of this.windows) {
|
|
272
|
-
if (now - window.start.getTime() <= periodMs) {
|
|
273
|
-
totalErrors += window.errors.get(errorType) || 0;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Errors per minute
|
|
278
|
-
return totalErrors / periodMinutes;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
getMetrics() {
|
|
282
|
-
const now = new Date();
|
|
283
|
-
const recentWindows = this.windows.filter(w =>
|
|
284
|
-
now.getTime() - w.start.getTime() <= 300000 // Last 5 minutes
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
const errorCounts = new Map<string, number>();
|
|
288
|
-
for (const window of recentWindows) {
|
|
289
|
-
for (const [type, count] of window.errors.entries()) {
|
|
290
|
-
const current = errorCounts.get(type) || 0;
|
|
291
|
-
errorCounts.set(type, current + count);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
last5Minutes: Object.fromEntries(errorCounts),
|
|
297
|
-
errorRates: {
|
|
298
|
-
parsing: this.getErrorRate('FILE_PARSING_ERROR', 5),
|
|
299
|
-
mapping: this.getErrorRate('MAPPING_ERROR', 5),
|
|
300
|
-
network: this.getErrorRate('NETWORK_ERROR', 5)
|
|
301
|
-
},
|
|
302
|
-
timestamp: now.toISOString()
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
private getErrorType(error: Error): string {
|
|
307
|
-
if (error instanceof FluentAPIError) return `API_ERROR_${error.statusCode}`;
|
|
308
|
-
if (error instanceof AuthenticationError) return 'AUTH_ERROR';
|
|
309
|
-
if (error instanceof GraphQLExecutionError) return 'GRAPHQL_ERROR';
|
|
310
|
-
if (error instanceof IngestionError) return error.code;
|
|
311
|
-
if (error instanceof MappingError) return 'MAPPING_ERROR';
|
|
312
|
-
if (error instanceof PathResolutionError) return 'PATH_RESOLUTION_ERROR';
|
|
313
|
-
if (error instanceof FileParsingError) return 'FILE_PARSING_ERROR';
|
|
314
|
-
return 'UNKNOWN';
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
## Alerting Patterns
|
|
320
|
-
|
|
321
|
-
### Threshold-Based Alerting
|
|
322
|
-
|
|
323
|
-
Alert when error count exceeds threshold:
|
|
324
|
-
|
|
325
|
-
```typescript
|
|
326
|
-
class ErrorAlerting {
|
|
327
|
-
private metrics: ErrorMetrics;
|
|
328
|
-
private thresholds: Map<string, number>;
|
|
329
|
-
|
|
330
|
-
constructor(metrics: ErrorMetrics) {
|
|
331
|
-
this.metrics = metrics;
|
|
332
|
-
this.thresholds = new Map([
|
|
333
|
-
['PARSE_ERROR', 10],
|
|
334
|
-
['NETWORK_ERROR', 50],
|
|
335
|
-
['MAPPING_ERROR', 10]
|
|
336
|
-
]);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
checkThresholds(): void {
|
|
340
|
-
const current = this.metrics.getMetrics();
|
|
341
|
-
|
|
342
|
-
for (const [errorType, threshold] of this.thresholds.entries()) {
|
|
343
|
-
const count = current.errorCounts[errorType] || 0;
|
|
344
|
-
|
|
345
|
-
if (count >= threshold) {
|
|
346
|
-
this.sendAlert({
|
|
347
|
-
severity: 'HIGH',
|
|
348
|
-
message: `Error threshold exceeded: ${errorType}`,
|
|
349
|
-
count,
|
|
350
|
-
threshold,
|
|
351
|
-
timestamp: new Date().toISOString()
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
private async sendAlert(alert: any): Promise<void> {
|
|
358
|
-
logger.error('ALERT: Error threshold exceeded', alert);
|
|
359
|
-
|
|
360
|
-
// Send to monitoring service
|
|
361
|
-
await this.sendToSlack(alert);
|
|
362
|
-
await this.sendToPagerDuty(alert);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
private async sendToSlack(alert: any): Promise<void> {
|
|
366
|
-
// Slack webhook integration
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
private async sendToPagerDuty(alert: any): Promise<void> {
|
|
370
|
-
// PagerDuty integration
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### Rate-Based Alerting
|
|
376
|
-
|
|
377
|
-
Alert when error rate exceeds threshold:
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
class RateBasedAlerting {
|
|
381
|
-
private metrics: AdvancedErrorMetrics;
|
|
382
|
-
|
|
383
|
-
async checkRates(): Promise<void> {
|
|
384
|
-
const metrics = this.metrics.getMetrics();
|
|
385
|
-
|
|
386
|
-
// Alert if parsing errors > 2 per minute
|
|
387
|
-
if (metrics.errorRates.parsing > 2) {
|
|
388
|
-
await this.sendAlert({
|
|
389
|
-
type: 'PARSING_ERROR_RATE_HIGH',
|
|
390
|
-
rate: metrics.errorRates.parsing,
|
|
391
|
-
threshold: 2,
|
|
392
|
-
unit: 'per minute'
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Alert if network errors > 10 per minute
|
|
397
|
-
if (metrics.errorRates.network > 10) {
|
|
398
|
-
await this.sendAlert({
|
|
399
|
-
type: 'NETWORK_ERROR_RATE_HIGH',
|
|
400
|
-
rate: metrics.errorRates.network,
|
|
401
|
-
threshold: 10,
|
|
402
|
-
unit: 'per minute'
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
private async sendAlert(alert: any): Promise<void> {
|
|
408
|
-
logger.error('RATE ALERT: Error rate threshold exceeded', alert);
|
|
409
|
-
// Send to monitoring systems
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
## Integration with Monitoring Systems
|
|
415
|
-
|
|
416
|
-
### Datadog Integration
|
|
417
|
-
|
|
418
|
-
```typescript
|
|
419
|
-
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
420
|
-
|
|
421
|
-
async function sendToDatadog(error: Error, context: any): Promise<void> {
|
|
422
|
-
const metric = {
|
|
423
|
-
metric: 'ingestion.error',
|
|
424
|
-
type: 'count',
|
|
425
|
-
points: [[Date.now() / 1000, 1]],
|
|
426
|
-
tags: []
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
if (error instanceof IngestionError) {
|
|
430
|
-
metric.tags.push(
|
|
431
|
-
`error_code:${error.code}`,
|
|
432
|
-
`retryable:${error.isRetryable()}`,
|
|
433
|
-
`environment:${process.env.NODE_ENV}`
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
metric.tags.push(
|
|
438
|
-
`source:${context.source}`,
|
|
439
|
-
`customer:${context.customerId}`
|
|
440
|
-
);
|
|
441
|
-
|
|
442
|
-
// Send to Datadog API
|
|
443
|
-
// await datadogClient.submitMetric(metric);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// Usage
|
|
447
|
-
try {
|
|
448
|
-
await processFile(fileName);
|
|
449
|
-
} catch (error) {
|
|
450
|
-
await sendToDatadog(error, context);
|
|
451
|
-
throw error;
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### Sentry Integration
|
|
456
|
-
|
|
457
|
-
```typescript
|
|
458
|
-
import * as Sentry from '@sentry/node';
|
|
459
|
-
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
460
|
-
|
|
461
|
-
function reportToSentry(error: Error, context: any): void {
|
|
462
|
-
Sentry.withScope(scope => {
|
|
463
|
-
// Add context
|
|
464
|
-
scope.setContext('business', {
|
|
465
|
-
orderId: context.orderId,
|
|
466
|
-
customerId: context.customerId,
|
|
467
|
-
source: context.source
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
// Add tags
|
|
471
|
-
if (error instanceof IngestionError) {
|
|
472
|
-
scope.setTag('error_code', error.code);
|
|
473
|
-
scope.setTag('retryable', error.isRetryable().toString());
|
|
474
|
-
|
|
475
|
-
// Add extra data
|
|
476
|
-
scope.setExtra('error_details', error.toJSON());
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Set fingerprint for grouping
|
|
480
|
-
scope.setFingerprint([
|
|
481
|
-
error instanceof IngestionError ? error.code : error.name,
|
|
482
|
-
context.source
|
|
483
|
-
]);
|
|
484
|
-
|
|
485
|
-
// Capture exception
|
|
486
|
-
Sentry.captureException(error);
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Usage
|
|
491
|
-
try {
|
|
492
|
-
await processFile(fileName);
|
|
493
|
-
} catch (error) {
|
|
494
|
-
reportToSentry(error, context);
|
|
495
|
-
throw error;
|
|
496
|
-
}
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
### CloudWatch Integration
|
|
500
|
-
|
|
501
|
-
```typescript
|
|
502
|
-
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
|
|
503
|
-
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
504
|
-
|
|
505
|
-
async function sendToCloudWatch(error: Error): Promise<void> {
|
|
506
|
-
const cloudwatch = new CloudWatchClient({ region: 'us-east-1' });
|
|
507
|
-
|
|
508
|
-
const dimensions = [
|
|
509
|
-
{ Name: 'Environment', Value: process.env.NODE_ENV || 'unknown' }
|
|
510
|
-
];
|
|
511
|
-
|
|
512
|
-
if (error instanceof IngestionError) {
|
|
513
|
-
dimensions.push(
|
|
514
|
-
{ Name: 'ErrorCode', Value: error.code },
|
|
515
|
-
{ Name: 'Retryable', Value: error.isRetryable().toString() }
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
const command = new PutMetricDataCommand({
|
|
520
|
-
Namespace: 'FluentCommerce/Ingestion',
|
|
521
|
-
MetricData: [
|
|
522
|
-
{
|
|
523
|
-
MetricName: 'ErrorCount',
|
|
524
|
-
Value: 1,
|
|
525
|
-
Unit: 'Count',
|
|
526
|
-
Timestamp: new Date(),
|
|
527
|
-
Dimensions: dimensions
|
|
528
|
-
}
|
|
529
|
-
]
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
await cloudwatch.send(command);
|
|
533
|
-
}
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
## Logging Best Practices
|
|
537
|
-
|
|
538
|
-
### 1. Always Log Error Context
|
|
539
|
-
|
|
540
|
-
```typescript
|
|
541
|
-
// ❌ POOR - Missing context
|
|
542
|
-
logger.error('Error occurred');
|
|
543
|
-
|
|
544
|
-
// ✅ GOOD - Full context (Standalone)
|
|
545
|
-
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
546
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessor' });
|
|
547
|
-
|
|
548
|
-
// ✅ GOOD - Full context (Versori Platform)
|
|
549
|
-
const { log: logger } = ctx;
|
|
550
|
-
|
|
551
|
-
logger.error('Order processing failed', {
|
|
552
|
-
error: error instanceof IngestionError ? error.toJSON() : error.message,
|
|
553
|
-
orderId: metadata.orderId,
|
|
554
|
-
fileName,
|
|
555
|
-
attempt: retryAttempt,
|
|
556
|
-
correlationId
|
|
557
|
-
});
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### 2. Use Appropriate Log Levels
|
|
561
|
-
|
|
562
|
-
```typescript
|
|
563
|
-
// Debug: Detailed flow information
|
|
564
|
-
logger.debug('Parsing XML file', { fileName, size });
|
|
565
|
-
|
|
566
|
-
// Info: Normal operations
|
|
567
|
-
logger.info('Order processed successfully', { orderId, duration });
|
|
568
|
-
|
|
569
|
-
// Warn: Recoverable issues
|
|
570
|
-
logger.warn('Retrying after transient error', { attempt, error: error.code });
|
|
571
|
-
|
|
572
|
-
// Error: Failed operations
|
|
573
|
-
logger.error('Order processing failed', { error: error.toJSON() });
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
### 3. Include Timestamps and IDs
|
|
577
|
-
|
|
578
|
-
```typescript
|
|
579
|
-
logger.error('Processing failed', {
|
|
580
|
-
timestamp: new Date().toISOString(),
|
|
581
|
-
correlationId: context.correlationId,
|
|
582
|
-
traceId: context.traceId,
|
|
583
|
-
error: error.toJSON()
|
|
584
|
-
});
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### 4. Sanitize Sensitive Data
|
|
588
|
-
|
|
589
|
-
```typescript
|
|
590
|
-
function sanitizeForLogging(data: any): any {
|
|
591
|
-
const sanitized = { ...data };
|
|
592
|
-
|
|
593
|
-
// Remove sensitive fields
|
|
594
|
-
delete sanitized.password;
|
|
595
|
-
delete sanitized.apiKey;
|
|
596
|
-
delete sanitized.creditCard;
|
|
597
|
-
|
|
598
|
-
// Mask email
|
|
599
|
-
if (sanitized.email) {
|
|
600
|
-
sanitized.email = sanitized.email.replace(/(.{2})(.*)(@.*)/, '$1***$3');
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
return sanitized;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
logger.error('Processing failed', {
|
|
607
|
-
data: sanitizeForLogging(sourceData),
|
|
608
|
-
error: error.toJSON()
|
|
609
|
-
});
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
## Dashboard Examples
|
|
613
|
-
|
|
614
|
-
### Error Summary Dashboard
|
|
615
|
-
|
|
616
|
-
Track key metrics:
|
|
617
|
-
- Total errors (last hour, day, week)
|
|
618
|
-
- Error rate trend
|
|
619
|
-
- Top error types
|
|
620
|
-
- Retryable vs non-retryable ratio
|
|
621
|
-
- Mean time to resolution
|
|
622
|
-
|
|
623
|
-
### Error Distribution
|
|
624
|
-
|
|
625
|
-
Visualize error types:
|
|
626
|
-
```
|
|
627
|
-
Parsing Errors: ████████░░ 42%
|
|
628
|
-
Mapping Errors: ██████░░░░ 31%
|
|
629
|
-
Network Errors: ████░░░░░░ 19%
|
|
630
|
-
Validation Errors: ██░░░░░░░░ 8%
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
### Error Heatmap
|
|
634
|
-
|
|
635
|
-
Show error frequency by time of day and error type.
|
|
636
|
-
|
|
637
|
-
## Key Takeaways
|
|
638
|
-
|
|
639
|
-
- 🎯 **Use error.toJSON()** - Complete structured error data
|
|
640
|
-
- 🎯 **Add business context** - Enrich with IDs, metadata
|
|
641
|
-
- 🎯 **Track metrics** - Count errors, calculate rates
|
|
642
|
-
- 🎯 **Set up alerts** - Threshold and rate-based alerting
|
|
643
|
-
- 🎯 **Integrate monitoring** - Datadog, Sentry, CloudWatch
|
|
644
|
-
- 🎯 **Sanitize logs** - Remove sensitive data before logging
|
|
645
|
-
|
|
646
|
-
## Next Steps
|
|
647
|
-
|
|
648
|
-
Continue to [Module 8: API Reference →](./error-handling-08-api-reference.md) for complete error class documentation and best practices checklist.
|
|
649
|
-
|
|
650
|
-
---
|
|
651
|
-
|
|
652
|
-
**Previous:** [← Module 6: Retry Strategies](./error-handling-06-retry-strategies.md)
|
|
653
|
-
**Next:** [Module 8: API Reference →](./error-handling-08-api-reference.md)
|
|
1
|
+
# Module 7: Monitoring
|
|
2
|
+
|
|
3
|
+
**Level:** Advanced
|
|
4
|
+
**Estimated Time:** 20 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module covers effective logging and monitoring strategies for error handling, including structured logging, metrics collection, and alerting patterns.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Implement structured error logging with full context
|
|
14
|
+
- ✅ Use `error.toJSON()` for complete error serialization
|
|
15
|
+
- ✅ Build error metrics and monitoring dashboards
|
|
16
|
+
- ✅ Set up alerting for high error rates
|
|
17
|
+
- ✅ Integrate with external monitoring systems
|
|
18
|
+
|
|
19
|
+
## Structured Logging
|
|
20
|
+
|
|
21
|
+
### Logging Setup
|
|
22
|
+
|
|
23
|
+
**First, configure logging based on your runtime:**
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Standalone (Node.js/Deno)
|
|
27
|
+
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
28
|
+
const logger = toStructuredLogger(createConsoleLogger(), {
|
|
29
|
+
service: 'ErrorMonitoring',
|
|
30
|
+
environment: process.env.NODE_ENV
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Versori Platform
|
|
34
|
+
const { log: logger } = ctx; // Use native platform log
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Using error.toJSON()
|
|
38
|
+
|
|
39
|
+
All SDK errors provide a `toJSON()` method for structured logging:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import {
|
|
43
|
+
IngestionError,
|
|
44
|
+
MappingError,
|
|
45
|
+
createConsoleLogger,
|
|
46
|
+
toStructuredLogger
|
|
47
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
48
|
+
|
|
49
|
+
// Standalone
|
|
50
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'FileProcessor' });
|
|
51
|
+
|
|
52
|
+
// Versori Platform
|
|
53
|
+
// const { log: logger } = ctx;
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
await processFile(fileName);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error instanceof IngestionError) {
|
|
59
|
+
// Full structured error data
|
|
60
|
+
const errorData = error.toJSON();
|
|
61
|
+
|
|
62
|
+
logger.error('File processing failed:', errorData);
|
|
63
|
+
/*
|
|
64
|
+
{
|
|
65
|
+
name: "FileParsingError",
|
|
66
|
+
message: "Failed to parse XML: Unclosed tag 'order'",
|
|
67
|
+
code: "PARSE_ERROR",
|
|
68
|
+
fileName: "order-12345.xml",
|
|
69
|
+
lineNumber: 42,
|
|
70
|
+
context: { ... },
|
|
71
|
+
timestamp: "2025-01-10T12:34:56.789Z",
|
|
72
|
+
correlationId: "abc-123-def",
|
|
73
|
+
stack: "Error: ...\n at ..."
|
|
74
|
+
}
|
|
75
|
+
*/
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Adding Business Context
|
|
81
|
+
|
|
82
|
+
Enrich errors with business-specific information:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
try {
|
|
86
|
+
await processOrder(xmlContent);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const enrichedLog = {
|
|
89
|
+
// Base error data
|
|
90
|
+
...(error instanceof IngestionError ? error.toJSON() : { message: error.message }),
|
|
91
|
+
|
|
92
|
+
// Business context
|
|
93
|
+
orderId: metadata.orderId,
|
|
94
|
+
customerId: metadata.customerId,
|
|
95
|
+
source: metadata.source,
|
|
96
|
+
environment: process.env.NODE_ENV,
|
|
97
|
+
appVersion: process.env.APP_VERSION,
|
|
98
|
+
|
|
99
|
+
// Additional tracking
|
|
100
|
+
traceId: generateTraceId(),
|
|
101
|
+
sessionId: context.sessionId
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
logger.error('Order processing failed:', enrichedLog);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Correlation IDs
|
|
109
|
+
|
|
110
|
+
Use correlation IDs to track errors across distributed systems:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
114
|
+
|
|
115
|
+
async function processWithCorrelation(data: any, correlationId?: string) {
|
|
116
|
+
const id = correlationId || uuidv4();
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
logger.info('Processing started', { correlationId: id });
|
|
120
|
+
|
|
121
|
+
const result = await process(data);
|
|
122
|
+
|
|
123
|
+
logger.info('Processing completed', { correlationId: id });
|
|
124
|
+
return result;
|
|
125
|
+
|
|
126
|
+
} catch (error) {
|
|
127
|
+
const errorData = error instanceof IngestionError
|
|
128
|
+
? error.toJSON()
|
|
129
|
+
: { message: error.message };
|
|
130
|
+
|
|
131
|
+
logger.error('Processing failed', {
|
|
132
|
+
...errorData,
|
|
133
|
+
correlationId: id
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Error Metrics Collection
|
|
142
|
+
|
|
143
|
+
### Basic Error Counter
|
|
144
|
+
|
|
145
|
+
Track error counts by type:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import {
|
|
149
|
+
IngestionError,
|
|
150
|
+
MappingError,
|
|
151
|
+
PathResolutionError,
|
|
152
|
+
FluentAPIError,
|
|
153
|
+
AuthenticationError,
|
|
154
|
+
GraphQLExecutionError
|
|
155
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
156
|
+
|
|
157
|
+
class ErrorMetrics {
|
|
158
|
+
private errorCounts = new Map<string, number>();
|
|
159
|
+
private lastErrors = new Map<string, Date>();
|
|
160
|
+
|
|
161
|
+
recordError(error: Error): void {
|
|
162
|
+
let errorType = 'UNKNOWN';
|
|
163
|
+
|
|
164
|
+
if (error instanceof FluentAPIError) {
|
|
165
|
+
errorType = `API_ERROR_${error.statusCode}`;
|
|
166
|
+
} else if (error instanceof AuthenticationError) {
|
|
167
|
+
errorType = 'AUTH_ERROR';
|
|
168
|
+
} else if (error instanceof GraphQLExecutionError) {
|
|
169
|
+
errorType = 'GRAPHQL_ERROR';
|
|
170
|
+
} else if (error instanceof IngestionError) {
|
|
171
|
+
errorType = error.code;
|
|
172
|
+
} else if (error instanceof MappingError) {
|
|
173
|
+
errorType = 'MAPPING_ERROR';
|
|
174
|
+
} else if (error instanceof PathResolutionError) {
|
|
175
|
+
errorType = 'PATH_RESOLUTION_ERROR';
|
|
176
|
+
} else if (error instanceof FileParsingError) {
|
|
177
|
+
errorType = 'FILE_PARSING_ERROR';
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Increment counter
|
|
181
|
+
const count = this.errorCounts.get(errorType) || 0;
|
|
182
|
+
this.errorCounts.set(errorType, count + 1);
|
|
183
|
+
|
|
184
|
+
// Update last occurrence
|
|
185
|
+
this.lastErrors.set(errorType, new Date());
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
getMetrics() {
|
|
189
|
+
return {
|
|
190
|
+
errorCounts: Object.fromEntries(this.errorCounts),
|
|
191
|
+
lastErrors: Object.fromEntries(this.lastErrors),
|
|
192
|
+
timestamp: new Date().toISOString()
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
reset(): void {
|
|
197
|
+
this.errorCounts.clear();
|
|
198
|
+
this.lastErrors.clear();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Usage
|
|
203
|
+
const metrics = new ErrorMetrics();
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
await processFile(fileName);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
metrics.recordError(error);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Get metrics periodically
|
|
213
|
+
setInterval(() => {
|
|
214
|
+
logger.info('Error metrics', metrics.getMetrics());
|
|
215
|
+
}, 60000); // Every minute
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Advanced Metrics with Rates
|
|
219
|
+
|
|
220
|
+
Track error rates over time windows:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface TimeWindow {
|
|
224
|
+
start: Date;
|
|
225
|
+
end: Date;
|
|
226
|
+
errors: Map<string, number>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
class AdvancedErrorMetrics {
|
|
230
|
+
private windows: TimeWindow[] = [];
|
|
231
|
+
private windowSizeMs: number;
|
|
232
|
+
private maxWindows: number;
|
|
233
|
+
|
|
234
|
+
constructor(windowSizeMs = 60000, maxWindows = 60) {
|
|
235
|
+
this.windowSizeMs = windowSizeMs;
|
|
236
|
+
this.maxWindows = maxWindows;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
recordError(error: Error): void {
|
|
240
|
+
const now = new Date();
|
|
241
|
+
const errorType = this.getErrorType(error);
|
|
242
|
+
|
|
243
|
+
// Get or create current window
|
|
244
|
+
let currentWindow = this.windows[this.windows.length - 1];
|
|
245
|
+
|
|
246
|
+
if (!currentWindow || now.getTime() - currentWindow.start.getTime() >= this.windowSizeMs) {
|
|
247
|
+
// Create new window
|
|
248
|
+
currentWindow = {
|
|
249
|
+
start: now,
|
|
250
|
+
end: new Date(now.getTime() + this.windowSizeMs),
|
|
251
|
+
errors: new Map()
|
|
252
|
+
};
|
|
253
|
+
this.windows.push(currentWindow);
|
|
254
|
+
|
|
255
|
+
// Trim old windows
|
|
256
|
+
if (this.windows.length > this.maxWindows) {
|
|
257
|
+
this.windows.shift();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Increment error count in current window
|
|
262
|
+
const count = currentWindow.errors.get(errorType) || 0;
|
|
263
|
+
currentWindow.errors.set(errorType, count + 1);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
getErrorRate(errorType: string, periodMinutes = 5): number {
|
|
267
|
+
const periodMs = periodMinutes * 60 * 1000;
|
|
268
|
+
const now = Date.now();
|
|
269
|
+
let totalErrors = 0;
|
|
270
|
+
|
|
271
|
+
for (const window of this.windows) {
|
|
272
|
+
if (now - window.start.getTime() <= periodMs) {
|
|
273
|
+
totalErrors += window.errors.get(errorType) || 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Errors per minute
|
|
278
|
+
return totalErrors / periodMinutes;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
getMetrics() {
|
|
282
|
+
const now = new Date();
|
|
283
|
+
const recentWindows = this.windows.filter(w =>
|
|
284
|
+
now.getTime() - w.start.getTime() <= 300000 // Last 5 minutes
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const errorCounts = new Map<string, number>();
|
|
288
|
+
for (const window of recentWindows) {
|
|
289
|
+
for (const [type, count] of window.errors.entries()) {
|
|
290
|
+
const current = errorCounts.get(type) || 0;
|
|
291
|
+
errorCounts.set(type, current + count);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
last5Minutes: Object.fromEntries(errorCounts),
|
|
297
|
+
errorRates: {
|
|
298
|
+
parsing: this.getErrorRate('FILE_PARSING_ERROR', 5),
|
|
299
|
+
mapping: this.getErrorRate('MAPPING_ERROR', 5),
|
|
300
|
+
network: this.getErrorRate('NETWORK_ERROR', 5)
|
|
301
|
+
},
|
|
302
|
+
timestamp: now.toISOString()
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private getErrorType(error: Error): string {
|
|
307
|
+
if (error instanceof FluentAPIError) return `API_ERROR_${error.statusCode}`;
|
|
308
|
+
if (error instanceof AuthenticationError) return 'AUTH_ERROR';
|
|
309
|
+
if (error instanceof GraphQLExecutionError) return 'GRAPHQL_ERROR';
|
|
310
|
+
if (error instanceof IngestionError) return error.code;
|
|
311
|
+
if (error instanceof MappingError) return 'MAPPING_ERROR';
|
|
312
|
+
if (error instanceof PathResolutionError) return 'PATH_RESOLUTION_ERROR';
|
|
313
|
+
if (error instanceof FileParsingError) return 'FILE_PARSING_ERROR';
|
|
314
|
+
return 'UNKNOWN';
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Alerting Patterns
|
|
320
|
+
|
|
321
|
+
### Threshold-Based Alerting
|
|
322
|
+
|
|
323
|
+
Alert when error count exceeds threshold:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
class ErrorAlerting {
|
|
327
|
+
private metrics: ErrorMetrics;
|
|
328
|
+
private thresholds: Map<string, number>;
|
|
329
|
+
|
|
330
|
+
constructor(metrics: ErrorMetrics) {
|
|
331
|
+
this.metrics = metrics;
|
|
332
|
+
this.thresholds = new Map([
|
|
333
|
+
['PARSE_ERROR', 10],
|
|
334
|
+
['NETWORK_ERROR', 50],
|
|
335
|
+
['MAPPING_ERROR', 10]
|
|
336
|
+
]);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
checkThresholds(): void {
|
|
340
|
+
const current = this.metrics.getMetrics();
|
|
341
|
+
|
|
342
|
+
for (const [errorType, threshold] of this.thresholds.entries()) {
|
|
343
|
+
const count = current.errorCounts[errorType] || 0;
|
|
344
|
+
|
|
345
|
+
if (count >= threshold) {
|
|
346
|
+
this.sendAlert({
|
|
347
|
+
severity: 'HIGH',
|
|
348
|
+
message: `Error threshold exceeded: ${errorType}`,
|
|
349
|
+
count,
|
|
350
|
+
threshold,
|
|
351
|
+
timestamp: new Date().toISOString()
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private async sendAlert(alert: any): Promise<void> {
|
|
358
|
+
logger.error('ALERT: Error threshold exceeded', alert);
|
|
359
|
+
|
|
360
|
+
// Send to monitoring service
|
|
361
|
+
await this.sendToSlack(alert);
|
|
362
|
+
await this.sendToPagerDuty(alert);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private async sendToSlack(alert: any): Promise<void> {
|
|
366
|
+
// Slack webhook integration
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private async sendToPagerDuty(alert: any): Promise<void> {
|
|
370
|
+
// PagerDuty integration
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Rate-Based Alerting
|
|
376
|
+
|
|
377
|
+
Alert when error rate exceeds threshold:
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
class RateBasedAlerting {
|
|
381
|
+
private metrics: AdvancedErrorMetrics;
|
|
382
|
+
|
|
383
|
+
async checkRates(): Promise<void> {
|
|
384
|
+
const metrics = this.metrics.getMetrics();
|
|
385
|
+
|
|
386
|
+
// Alert if parsing errors > 2 per minute
|
|
387
|
+
if (metrics.errorRates.parsing > 2) {
|
|
388
|
+
await this.sendAlert({
|
|
389
|
+
type: 'PARSING_ERROR_RATE_HIGH',
|
|
390
|
+
rate: metrics.errorRates.parsing,
|
|
391
|
+
threshold: 2,
|
|
392
|
+
unit: 'per minute'
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Alert if network errors > 10 per minute
|
|
397
|
+
if (metrics.errorRates.network > 10) {
|
|
398
|
+
await this.sendAlert({
|
|
399
|
+
type: 'NETWORK_ERROR_RATE_HIGH',
|
|
400
|
+
rate: metrics.errorRates.network,
|
|
401
|
+
threshold: 10,
|
|
402
|
+
unit: 'per minute'
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private async sendAlert(alert: any): Promise<void> {
|
|
408
|
+
logger.error('RATE ALERT: Error rate threshold exceeded', alert);
|
|
409
|
+
// Send to monitoring systems
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Integration with Monitoring Systems
|
|
415
|
+
|
|
416
|
+
### Datadog Integration
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
420
|
+
|
|
421
|
+
async function sendToDatadog(error: Error, context: any): Promise<void> {
|
|
422
|
+
const metric = {
|
|
423
|
+
metric: 'ingestion.error',
|
|
424
|
+
type: 'count',
|
|
425
|
+
points: [[Date.now() / 1000, 1]],
|
|
426
|
+
tags: []
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
if (error instanceof IngestionError) {
|
|
430
|
+
metric.tags.push(
|
|
431
|
+
`error_code:${error.code}`,
|
|
432
|
+
`retryable:${error.isRetryable()}`,
|
|
433
|
+
`environment:${process.env.NODE_ENV}`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
metric.tags.push(
|
|
438
|
+
`source:${context.source}`,
|
|
439
|
+
`customer:${context.customerId}`
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
// Send to Datadog API
|
|
443
|
+
// await datadogClient.submitMetric(metric);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Usage
|
|
447
|
+
try {
|
|
448
|
+
await processFile(fileName);
|
|
449
|
+
} catch (error) {
|
|
450
|
+
await sendToDatadog(error, context);
|
|
451
|
+
throw error;
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Sentry Integration
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import * as Sentry from '@sentry/node';
|
|
459
|
+
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
460
|
+
|
|
461
|
+
function reportToSentry(error: Error, context: any): void {
|
|
462
|
+
Sentry.withScope(scope => {
|
|
463
|
+
// Add context
|
|
464
|
+
scope.setContext('business', {
|
|
465
|
+
orderId: context.orderId,
|
|
466
|
+
customerId: context.customerId,
|
|
467
|
+
source: context.source
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// Add tags
|
|
471
|
+
if (error instanceof IngestionError) {
|
|
472
|
+
scope.setTag('error_code', error.code);
|
|
473
|
+
scope.setTag('retryable', error.isRetryable().toString());
|
|
474
|
+
|
|
475
|
+
// Add extra data
|
|
476
|
+
scope.setExtra('error_details', error.toJSON());
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Set fingerprint for grouping
|
|
480
|
+
scope.setFingerprint([
|
|
481
|
+
error instanceof IngestionError ? error.code : error.name,
|
|
482
|
+
context.source
|
|
483
|
+
]);
|
|
484
|
+
|
|
485
|
+
// Capture exception
|
|
486
|
+
Sentry.captureException(error);
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Usage
|
|
491
|
+
try {
|
|
492
|
+
await processFile(fileName);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
reportToSentry(error, context);
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### CloudWatch Integration
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
|
|
503
|
+
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
504
|
+
|
|
505
|
+
async function sendToCloudWatch(error: Error): Promise<void> {
|
|
506
|
+
const cloudwatch = new CloudWatchClient({ region: 'us-east-1' });
|
|
507
|
+
|
|
508
|
+
const dimensions = [
|
|
509
|
+
{ Name: 'Environment', Value: process.env.NODE_ENV || 'unknown' }
|
|
510
|
+
];
|
|
511
|
+
|
|
512
|
+
if (error instanceof IngestionError) {
|
|
513
|
+
dimensions.push(
|
|
514
|
+
{ Name: 'ErrorCode', Value: error.code },
|
|
515
|
+
{ Name: 'Retryable', Value: error.isRetryable().toString() }
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const command = new PutMetricDataCommand({
|
|
520
|
+
Namespace: 'FluentCommerce/Ingestion',
|
|
521
|
+
MetricData: [
|
|
522
|
+
{
|
|
523
|
+
MetricName: 'ErrorCount',
|
|
524
|
+
Value: 1,
|
|
525
|
+
Unit: 'Count',
|
|
526
|
+
Timestamp: new Date(),
|
|
527
|
+
Dimensions: dimensions
|
|
528
|
+
}
|
|
529
|
+
]
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
await cloudwatch.send(command);
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
## Logging Best Practices
|
|
537
|
+
|
|
538
|
+
### 1. Always Log Error Context
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// ❌ POOR - Missing context
|
|
542
|
+
logger.error('Error occurred');
|
|
543
|
+
|
|
544
|
+
// ✅ GOOD - Full context (Standalone)
|
|
545
|
+
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
546
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessor' });
|
|
547
|
+
|
|
548
|
+
// ✅ GOOD - Full context (Versori Platform)
|
|
549
|
+
const { log: logger } = ctx;
|
|
550
|
+
|
|
551
|
+
logger.error('Order processing failed', {
|
|
552
|
+
error: error instanceof IngestionError ? error.toJSON() : error.message,
|
|
553
|
+
orderId: metadata.orderId,
|
|
554
|
+
fileName,
|
|
555
|
+
attempt: retryAttempt,
|
|
556
|
+
correlationId
|
|
557
|
+
});
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### 2. Use Appropriate Log Levels
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
// Debug: Detailed flow information
|
|
564
|
+
logger.debug('Parsing XML file', { fileName, size });
|
|
565
|
+
|
|
566
|
+
// Info: Normal operations
|
|
567
|
+
logger.info('Order processed successfully', { orderId, duration });
|
|
568
|
+
|
|
569
|
+
// Warn: Recoverable issues
|
|
570
|
+
logger.warn('Retrying after transient error', { attempt, error: error.code });
|
|
571
|
+
|
|
572
|
+
// Error: Failed operations
|
|
573
|
+
logger.error('Order processing failed', { error: error.toJSON() });
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### 3. Include Timestamps and IDs
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
logger.error('Processing failed', {
|
|
580
|
+
timestamp: new Date().toISOString(),
|
|
581
|
+
correlationId: context.correlationId,
|
|
582
|
+
traceId: context.traceId,
|
|
583
|
+
error: error.toJSON()
|
|
584
|
+
});
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### 4. Sanitize Sensitive Data
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
function sanitizeForLogging(data: any): any {
|
|
591
|
+
const sanitized = { ...data };
|
|
592
|
+
|
|
593
|
+
// Remove sensitive fields
|
|
594
|
+
delete sanitized.password;
|
|
595
|
+
delete sanitized.apiKey;
|
|
596
|
+
delete sanitized.creditCard;
|
|
597
|
+
|
|
598
|
+
// Mask email
|
|
599
|
+
if (sanitized.email) {
|
|
600
|
+
sanitized.email = sanitized.email.replace(/(.{2})(.*)(@.*)/, '$1***$3');
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return sanitized;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
logger.error('Processing failed', {
|
|
607
|
+
data: sanitizeForLogging(sourceData),
|
|
608
|
+
error: error.toJSON()
|
|
609
|
+
});
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
## Dashboard Examples
|
|
613
|
+
|
|
614
|
+
### Error Summary Dashboard
|
|
615
|
+
|
|
616
|
+
Track key metrics:
|
|
617
|
+
- Total errors (last hour, day, week)
|
|
618
|
+
- Error rate trend
|
|
619
|
+
- Top error types
|
|
620
|
+
- Retryable vs non-retryable ratio
|
|
621
|
+
- Mean time to resolution
|
|
622
|
+
|
|
623
|
+
### Error Distribution
|
|
624
|
+
|
|
625
|
+
Visualize error types:
|
|
626
|
+
```
|
|
627
|
+
Parsing Errors: ████████░░ 42%
|
|
628
|
+
Mapping Errors: ██████░░░░ 31%
|
|
629
|
+
Network Errors: ████░░░░░░ 19%
|
|
630
|
+
Validation Errors: ██░░░░░░░░ 8%
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Error Heatmap
|
|
634
|
+
|
|
635
|
+
Show error frequency by time of day and error type.
|
|
636
|
+
|
|
637
|
+
## Key Takeaways
|
|
638
|
+
|
|
639
|
+
- 🎯 **Use error.toJSON()** - Complete structured error data
|
|
640
|
+
- 🎯 **Add business context** - Enrich with IDs, metadata
|
|
641
|
+
- 🎯 **Track metrics** - Count errors, calculate rates
|
|
642
|
+
- 🎯 **Set up alerts** - Threshold and rate-based alerting
|
|
643
|
+
- 🎯 **Integrate monitoring** - Datadog, Sentry, CloudWatch
|
|
644
|
+
- 🎯 **Sanitize logs** - Remove sensitive data before logging
|
|
645
|
+
|
|
646
|
+
## Next Steps
|
|
647
|
+
|
|
648
|
+
Continue to [Module 8: API Reference →](./error-handling-08-api-reference.md) for complete error class documentation and best practices checklist.
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
**Previous:** [← Module 6: Retry Strategies](./error-handling-06-retry-strategies.md)
|
|
653
|
+
**Next:** [Module 8: API Reference →](./error-handling-08-api-reference.md)
|