Repository: metriport/metriport
Pull request #3782: ENG-237 Retry CW patient create on 500
Author: login: leite08
Created: 2025-05-05T12:10:52Z | Merged: 2025-05-05T15:39:18Z

### Dependencies

none

### Description

Retry CW patient create on 500.

### Testing

- Local
  - [x] Patient create works
  - [x] Simulated `500` retries correctly
- Staging
  - [x] Patient create works
- Sandbox
  - none
- Production
  - none

### Release Plan

- [x] Release NPM packages
- [ ] Merge this


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
	- Added configurable retry behavior for certain API requests, improving reliability in the event of server errors.
	- Introduced a utility to help identify specific error types at runtime.

- **Bug Fixes**
	- Enhanced error handling to ensure consistent status reporting across different error formats.
	- Improved extraction of HTTP status codes from custom error types.

- **Chores**
	- Updated multiple package versions to new alpha pre-releases and aligned dependencies across packages.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/package-lock.json b/package-lock.json
index 202dce9018..dca9040541 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35537,7 +35537,7 @@
       }
     },
     "packages/api": {
-      "version": "1.27.1",
+      "version": "1.27.2-alpha.0",
       "license": "ISC",
       "dependencies": {
         "@aws-sdk/client-cloudwatch": "^3.338.0",
@@ -35621,12 +35621,12 @@
     },
     "packages/api-sdk": {
       "name": "@metriport/api-sdk",
-      "version": "14.14.1",
+      "version": "14.14.2-alpha.0",
       "license": "MIT",
       "dependencies": {
         "@medplum/fhirtypes": "^2.0.32",
-        "@metriport/commonwell-sdk": "^5.8.1",
-        "@metriport/shared": "^0.23.1",
+        "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
+        "@metriport/shared": "^0.23.2-alpha.0",
         "axios": "^1.8.2",
         "dayjs": "^1.11.7",
         "dotenv": "^16.3.1",
@@ -35683,11 +35683,11 @@
     "packages/api/packages/shared": {},
     "packages/carequality-cert-runner": {
       "name": "@metriport/carequality-cert-runner",
-      "version": "1.18.1",
+      "version": "1.18.2-alpha.0",
       "license": "MIT",
       "dependencies": {
-        "@metriport/ihe-gateway-sdk": "^0.19.1",
-        "@metriport/shared": "^0.23.1"
+        "@metriport/ihe-gateway-sdk": "^0.19.2-alpha.0",
+        "@metriport/shared": "^0.23.2-alpha.0"
       },
       "bin": {
         "carequality-cert-runner": "dist/index.js"
@@ -35695,7 +35695,7 @@
     },
     "packages/carequality-sdk": {
       "name": "@metriport/carequality-sdk",
-      "version": "1.6.1",
+      "version": "1.6.2-alpha.0",
       "license": "MIT",
       "dependencies": {
         "axios": "^1.8.2",
@@ -35719,10 +35719,10 @@
     },
     "packages/commonwell-cert-runner": {
       "name": "@metriport/commonwell-cert-runner",
-      "version": "1.26.1",
+      "version": "1.26.2-alpha.0",
       "license": "MIT",
       "dependencies": {
-        "@metriport/commonwell-sdk": "^5.8.1",
+        "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
         "axios": "^1.8.2",
         "commander": "^9.5.0",
         "dayjs": "^1.11.7",
@@ -35761,10 +35761,10 @@
     },
     "packages/commonwell-jwt-maker": {
       "name": "@metriport/commonwell-jwt-maker",
-      "version": "1.24.1",
+      "version": "1.24.2-alpha.0",
       "license": "MIT",
       "dependencies": {
-        "@metriport/commonwell-sdk": "^5.8.1",
+        "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
         "commander": "^9.5.0"
       },
       "bin": {
@@ -35796,10 +35796,10 @@
     },
     "packages/commonwell-sdk": {
       "name": "@metriport/commonwell-sdk",
-      "version": "5.8.1",
+      "version": "5.9.0-alpha.0",
       "license": "MIT",
       "dependencies": {
-        "@metriport/shared": "^0.23.1",
+        "@metriport/shared": "^0.23.2-alpha.0",
         "axios": "^1.8.2",
         "http-status": "~1.7.0",
         "jsonwebtoken": "^9.0.0",
@@ -35847,7 +35847,7 @@
     },
     "packages/core": {
       "name": "@metriport/core",
-      "version": "1.24.1",
+      "version": "1.24.2-alpha.0",
       "license": "MIT",
       "dependencies": {
         "@aws-crypto/sha256-js": "5.0.0",
@@ -37093,17 +37093,17 @@
     "packages/core/packages/shared": {},
     "packages/ihe-gateway-sdk": {
       "name": "@metriport/ihe-gateway-sdk",
-      "version": "0.19.1",
+      "version": "0.19.2-alpha.0",
       "license": "MIT",
       "dependencies": {
-        "@metriport/shared": "^0.23.1",
+        "@metriport/shared": "^0.23.2-alpha.0",
         "axios": "^1.8.2",
         "zod": "^3.22.1"
       }
     },
     "packages/infra": {
       "name": "infrastructure",
-      "version": "1.22.1",
+      "version": "1.22.2-alpha.0",
       "dependencies": {
         "@metriport/shared": "file:packages/shared",
         "aws-cdk-lib": "~2.133.0",
@@ -37156,7 +37156,7 @@
     },
     "packages/infra/packages/shared": {},
     "packages/mllp-server": {
-      "version": "0.3.1",
+      "version": "0.3.2-alpha.0",
       "license": "ISC",
       "dependencies": {
         "@medplum/core": "^3.2.33",
@@ -37312,7 +37312,7 @@
     },
     "packages/shared": {
       "name": "@metriport/shared",
-      "version": "0.23.1",
+      "version": "0.23.2-alpha.0",
       "license": "MIT",
       "dependencies": {
         "@medplum/core": "^2.2.10",
@@ -37361,7 +37361,7 @@
       }
     },
     "packages/utils": {
-      "version": "1.25.1",
+      "version": "1.25.2-alpha.0",
       "license": "ISC",
       "dependencies": {
         "@aws-sdk/client-athena": "^3.658.1",
diff --git a/packages/api-sdk/package.json b/packages/api-sdk/package.json
index 8e37b0304a..1d8c3d71bd 100644
--- a/packages/api-sdk/package.json
+++ b/packages/api-sdk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/api-sdk",
-  "version": "14.14.1",
+  "version": "14.14.2-alpha.0",
   "description": "Metriport helps you access and manage health and medical data, through a single open source API.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -58,8 +58,8 @@
   },
   "dependencies": {
     "@medplum/fhirtypes": "^2.0.32",
-    "@metriport/commonwell-sdk": "^5.8.1",
-    "@metriport/shared": "^0.23.1",
+    "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
+    "@metriport/shared": "^0.23.2-alpha.0",
     "axios": "^1.8.2",
     "dayjs": "^1.11.7",
     "dotenv": "^16.3.1",
diff --git a/packages/api/package.json b/packages/api/package.json
index b795d0bdd3..b0ad805213 100755
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,6 +1,6 @@
 {
   "name": "api",
-  "version": "1.27.1",
+  "version": "1.27.2-alpha.0",
   "description": "",
   "main": "app.js",
   "private": true,
diff --git a/packages/api/src/external/commonwell/api.ts b/packages/api/src/external/commonwell/api.ts
index 29083d23b6..350163d86d 100644
--- a/packages/api/src/external/commonwell/api.ts
+++ b/packages/api/src/external/commonwell/api.ts
@@ -6,6 +6,7 @@ import {
   CommonWellAPI,
   RequestMetadata,
 } from "@metriport/commonwell-sdk";
+import { CommonWellOptions } from "@metriport/commonwell-sdk/client/commonwell";
 import { CookieManagerOnSecrets } from "@metriport/core/domain/auth/cookie-management/cookie-manager-on-secrets";
 import { CommonWellManagementAPI } from "@metriport/core/external/commonwell/management/api";
 import { makeApi } from "@metriport/core/external/commonwell/management/api-factory";
@@ -44,6 +45,14 @@ export function makeCommonWellAPI(orgName: string, orgOID: string): CommonWellAP
     return new CommonWellMock(orgName, orgOID);
   }
 
+  const options: CommonWellOptions = {
+    onError500: {
+      retry: true,
+      maxAttempts: 3,
+      initialDelay: 1_000,
+    },
+  };
+
   const isMemberAPI = orgOID === Config.getCWMemberOID();
   if (isMemberAPI) {
     return new CommonWell(
@@ -51,7 +60,8 @@ export function makeCommonWellAPI(orgName: string, orgOID: string): CommonWellAP
       Config.getCWMemberPrivateKey(),
       orgName,
       orgOID,
-      apiMode
+      apiMode,
+      options
     );
   }
 
@@ -60,7 +70,8 @@ export function makeCommonWellAPI(orgName: string, orgOID: string): CommonWellAP
     Config.getCWOrgPrivateKey(),
     orgName,
     orgOID,
-    apiMode
+    apiMode,
+    options
   );
 }
 
diff --git a/packages/api/src/routes/helpers/default-error-handler.ts b/packages/api/src/routes/helpers/default-error-handler.ts
index e5b229fd8b..c88797f5ba 100644
--- a/packages/api/src/routes/helpers/default-error-handler.ts
+++ b/packages/api/src/routes/helpers/default-error-handler.ts
@@ -105,17 +105,18 @@ export const errorHandler: ErrorRequestHandler = (err, req, res, next) => {
         );
     }
   }
-  if (err.statusCode) {
+  const status = err.statusCode || err.status;
+  if (status) {
     return res
       .contentType("json")
-      .status(err.statusCode)
+      .status(status)
       .send({
         ...defaultResponseBody({
-          status: err.statusCode,
+          status,
           title: "MetriportError",
           detail: err.message,
         }),
-        name: httpStatus[err.statusCode],
+        name: httpStatus[status],
       });
   }
   log(`Error: ${err}`);
diff --git a/packages/carequality-cert-runner/package.json b/packages/carequality-cert-runner/package.json
index d7e258c6d2..84eee410f1 100644
--- a/packages/carequality-cert-runner/package.json
+++ b/packages/carequality-cert-runner/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/carequality-cert-runner",
-  "version": "1.18.1",
+  "version": "1.18.2-alpha.0",
   "description": "Tool to run through Carequality certification test cases - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -41,7 +41,7 @@
     "url": "https://github.com/metriport/metriport/issues"
   },
   "dependencies": {
-    "@metriport/ihe-gateway-sdk": "^0.19.1",
-    "@metriport/shared": "^0.23.1"
+    "@metriport/ihe-gateway-sdk": "^0.19.2-alpha.0",
+    "@metriport/shared": "^0.23.2-alpha.0"
   }
 }
diff --git a/packages/carequality-sdk/package.json b/packages/carequality-sdk/package.json
index e9cef08aa1..c5f3455c18 100644
--- a/packages/carequality-sdk/package.json
+++ b/packages/carequality-sdk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/carequality-sdk",
-  "version": "1.6.1",
+  "version": "1.6.2-alpha.0",
   "description": "SDK to interact with the Carequality directory - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
diff --git a/packages/commonwell-cert-runner/package.json b/packages/commonwell-cert-runner/package.json
index 2fc2bb7b5b..28827b69d3 100644
--- a/packages/commonwell-cert-runner/package.json
+++ b/packages/commonwell-cert-runner/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/commonwell-cert-runner",
-  "version": "1.26.1",
+  "version": "1.26.2-alpha.0",
   "description": "Tool to run through Edge System CommonWell certification test cases - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -42,7 +42,7 @@
     "url": "https://github.com/metriport/metriport/issues"
   },
   "dependencies": {
-    "@metriport/commonwell-sdk": "^5.8.1",
+    "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
     "axios": "^1.8.2",
     "commander": "^9.5.0",
     "dayjs": "^1.11.7",
diff --git a/packages/commonwell-jwt-maker/package.json b/packages/commonwell-jwt-maker/package.json
index f864b229e2..1f229e59d8 100644
--- a/packages/commonwell-jwt-maker/package.json
+++ b/packages/commonwell-jwt-maker/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/commonwell-jwt-maker",
-  "version": "1.24.1",
+  "version": "1.24.2-alpha.0",
   "description": "CLI to create a JWT for use in CommonWell queries - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -41,7 +41,7 @@
     "url": "https://github.com/metriport/metriport/issues"
   },
   "dependencies": {
-    "@metriport/commonwell-sdk": "^5.8.1",
+    "@metriport/commonwell-sdk": "^5.9.0-alpha.0",
     "commander": "^9.5.0"
   },
   "devDependencies": {
diff --git a/packages/commonwell-sdk/package.json b/packages/commonwell-sdk/package.json
index d0e7b819e8..cb5f8f87ef 100644
--- a/packages/commonwell-sdk/package.json
+++ b/packages/commonwell-sdk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/commonwell-sdk",
-  "version": "5.8.1",
+  "version": "5.9.0-alpha.0",
   "description": "SDK to simplify CommonWell API integration - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -60,7 +60,7 @@
     "url": "https://github.com/metriport/metriport/issues"
   },
   "dependencies": {
-    "@metriport/shared": "^0.23.1",
+    "@metriport/shared": "^0.23.2-alpha.0",
     "axios": "^1.8.2",
     "http-status": "~1.7.0",
     "jsonwebtoken": "^9.0.0",
diff --git a/packages/commonwell-sdk/src/client/commonwell.ts b/packages/commonwell-sdk/src/client/commonwell.ts
index 130b472641..72cc545d34 100644
--- a/packages/commonwell-sdk/src/client/commonwell.ts
+++ b/packages/commonwell-sdk/src/client/commonwell.ts
@@ -1,11 +1,16 @@
-import { PurposeOfUse } from "@metriport/shared";
+import {
+  defaultOptionsRequestNotAccepted,
+  executeWithNetworkRetries,
+  ExecuteWithRetriesOptions,
+  PurposeOfUse,
+  MetriportError,
+} from "@metriport/shared";
 import axios, { AxiosInstance, AxiosResponse } from "axios";
 import httpStatus from "http-status";
 import { Agent } from "https";
 import * as stream from "stream";
 import { CommonWellAPI } from "..";
 import { makeJwt } from "../common/make-jwt";
-import MetriportError from "../common/metriport-error";
 import { CertificateParam, CertificateResp, certificateRespSchema } from "../models/certificates";
 import { DocumentQueryFullResponse, DocumentQueryResponse } from "../models/document";
 import { Identifier, StrongId } from "../models/identifier";
@@ -40,6 +45,12 @@ import * as document from "./document";
 
 const DEFAULT_AXIOS_TIMEOUT_SECONDS = 120;
 
+const defaultOnError500: OnError500Options = {
+  retry: false,
+  maxAttempts: 1,
+  initialDelay: 0,
+};
+
 export enum APIMode {
   integration = "integration",
   production = "production",
@@ -53,6 +64,15 @@ export interface RequestMetadata {
   payloadHash?: string;
 }
 
+export type OnError500Options = Omit<ExecuteWithRetriesOptions<unknown>, "shouldRetry"> & {
+  retry: boolean;
+};
+
+export interface CommonWellOptions {
+  timeout?: number;
+  onError500?: OnError500Options;
+}
+
 export class CommonWell implements CommonWellAPI {
   static integrationUrl = "https://integration.rest.api.commonwellalliance.org";
   static productionUrl = "https://rest.api.commonwellalliance.org";
@@ -71,6 +91,7 @@ export class CommonWell implements CommonWellAPI {
   private _oid: string;
   private httpsAgent: Agent;
   private _lastReferenceHeader: string | undefined;
+  private onError500: OnError500Options;
 
   /**
    * Creates a new instance of the CommonWell API client pertaining to an
@@ -89,7 +110,7 @@ export class CommonWell implements CommonWellAPI {
     orgName: string,
     oid: string,
     apiMode: APIMode,
-    options: { timeout?: number } = {}
+    options: CommonWellOptions = {}
   ) {
     this.rsaPrivateKey = rsaPrivateKey;
     this.httpsAgent = new Agent({ cert: orgCert, key: rsaPrivateKey });
@@ -105,6 +126,7 @@ export class CommonWell implements CommonWellAPI {
     );
     this.orgName = orgName;
     this._oid = oid;
+    this.onError500 = { ...defaultOnError500, ...options.onError500 };
   }
 
   get oid() {
@@ -611,9 +633,11 @@ export class CommonWell implements CommonWellAPI {
    */
   async registerPatient(meta: RequestMetadata, patient: Patient): Promise<Patient> {
     const headers = await this.buildQueryHeaders(meta);
-    const resp = await this.api.post(`${CommonWell.ORG_ENDPOINT}/${this.oid}/patient`, patient, {
-      headers,
-    });
+    const resp = await this.executeWithRetriesOn500(() =>
+      this.api.post(`${CommonWell.ORG_ENDPOINT}/${this.oid}/patient`, patient, {
+        headers,
+      })
+    );
     return patientSchema.parse(resp.data);
   }
 
@@ -977,4 +1001,17 @@ export class CommonWell implements CommonWellAPI {
     );
     return { Authorization: `Bearer ${jwt}` };
   }
+
+  private async executeWithRetriesOn500<T>(fn: () => Promise<T>): Promise<T> {
+    return this.onError500.retry
+      ? executeWithNetworkRetries(fn, {
+          ...this.onError500,
+          httpCodesToRetry: [...defaultOptionsRequestNotAccepted.httpCodesToRetry],
+          httpStatusCodesToRetry: [
+            ...defaultOptionsRequestNotAccepted.httpStatusCodesToRetry,
+            httpStatus.INTERNAL_SERVER_ERROR,
+          ],
+        })
+      : fn();
+  }
 }
diff --git a/packages/commonwell-sdk/src/common/metriport-error.ts b/packages/commonwell-sdk/src/common/metriport-error.ts
deleted file mode 100644
index 5aa46d52a8..0000000000
--- a/packages/commonwell-sdk/src/common/metriport-error.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as httpStatus from "http-status";
-
-export default class MetriportError extends Error {
-  status: number;
-  constructor(message: string, status: number = httpStatus.INTERNAL_SERVER_ERROR) {
-    super(message);
-    this.status = status;
-  }
-}
diff --git a/packages/core/package.json b/packages/core/package.json
index caaa3527f7..139f9fe234 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/core",
-  "version": "1.24.1",
+  "version": "1.24.2-alpha.0",
   "private": true,
   "description": "Metriport helps you access and manage health and medical data, through a single open source API. Common code shared across packages.",
   "author": "Metriport Inc. <contact@metriport.com>",
diff --git a/packages/ihe-gateway-sdk/package.json b/packages/ihe-gateway-sdk/package.json
index a253e5c356..04846e7ec6 100644
--- a/packages/ihe-gateway-sdk/package.json
+++ b/packages/ihe-gateway-sdk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/ihe-gateway-sdk",
-  "version": "0.19.1",
+  "version": "0.19.2-alpha.0",
   "description": "SDK to interact with other IHE Gateways - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
@@ -53,7 +53,7 @@
     "url": "https://github.com/metriport/metriport/issues"
   },
   "dependencies": {
-    "@metriport/shared": "^0.23.1",
+    "@metriport/shared": "^0.23.2-alpha.0",
     "axios": "^1.8.2",
     "zod": "^3.22.1"
   }
diff --git a/packages/infra/package.json b/packages/infra/package.json
index 367826feaa..5888b2e123 100644
--- a/packages/infra/package.json
+++ b/packages/infra/package.json
@@ -1,6 +1,6 @@
 {
   "name": "infrastructure",
-  "version": "1.22.1",
+  "version": "1.22.2-alpha.0",
   "private": true,
   "bin": {
     "infrastructure": "bin/infrastructure.js"
diff --git a/packages/mllp-server/package.json b/packages/mllp-server/package.json
index 90b94e41e4..818620c7ca 100644
--- a/packages/mllp-server/package.json
+++ b/packages/mllp-server/package.json
@@ -1,6 +1,6 @@
 {
   "name": "mllp-server",
-  "version": "0.3.1",
+  "version": "0.3.2-alpha.0",
   "description": "MLLP server that reads HL7 messages off of a raw tcp connection",
   "main": "app.js",
   "private": true,
diff --git a/packages/shared/package.json b/packages/shared/package.json
index b73d7d437b..31badee3df 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@metriport/shared",
-  "version": "0.23.1",
+  "version": "0.23.2-alpha.0",
   "description": "Common code shared across packages - by Metriport Inc.",
   "author": "Metriport Inc. <contact@metriport.com>",
   "homepage": "https://metriport.com/",
diff --git a/packages/shared/src/error/metriport-error.ts b/packages/shared/src/error/metriport-error.ts
index 040d5e7955..5259512ceb 100644
--- a/packages/shared/src/error/metriport-error.ts
+++ b/packages/shared/src/error/metriport-error.ts
@@ -9,3 +9,7 @@ export class MetriportError extends Error {
     this.cause = cause;
   }
 }
+
+export function isMetriportError(err: unknown): err is MetriportError {
+  return err instanceof MetriportError;
+}
diff --git a/packages/shared/src/net/retry.ts b/packages/shared/src/net/retry.ts
index e94deb4c5a..b8e743eadb 100644
--- a/packages/shared/src/net/retry.ts
+++ b/packages/shared/src/net/retry.ts
@@ -7,6 +7,7 @@ import {
   GetTimeToWaitParams,
 } from "../common/retry";
 import { NetworkError, networkTimeoutErrors } from "./error";
+import { isMetriportError } from "../error/metriport-error";
 
 export const tooManyRequestsStatus = 429;
 const tooManyRequestsMultiplier = 3;
@@ -47,7 +48,8 @@ const defaultOptions: ExecuteWithNetworkRetriesOptions = {
 export function getHttpStatusFromError(error: any): number | undefined {
   if (!error) return undefined;
   if (axios.isAxiosError(error)) return error.response?.status;
-  if ("cause" in error) return getHttpStatusFromError(error.cause);
+  if (error.cause) return getHttpStatusFromError(error.cause);
+  if (isMetriportError(error)) return error.status;
   return undefined;
 }
 
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 79121cca10..a713835e8e 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -1,6 +1,6 @@
 {
   "name": "utils",
-  "version": "1.25.1",
+  "version": "1.25.2-alpha.0",
   "description": "",
   "private": true,
   "scripts": {


Reviews:
user: login: leite08
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T12:11:49Z
user: login: leite08
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T12:12:20Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>packages/commonwell-sdk/src/client/commonwell.ts (2)</summary><blockquote>

`67-74`: **Well-defined options interface for retry configuration.**

The interface clearly defines available options for retry behavior. Consider adding JSDoc comments on the interface properties to provide more context about each configuration option.

```diff
 export interface CommonWellOptions {
+  /** Connection timeout in milliseconds, default 120 seconds */
   timeout?: number;
+  /** Configuration for retry behavior on HTTP 500 errors */
   onError500?: OnError500Options;
 }
```

---

`1005-1016`: **Well-implemented private retry method.**

The `executeWithRetriesOn500` method is well designed:
1. It respects the configuration to enable/disable retries
2. It merges default retry options with 500-specific settings
3. It maintains the original function execution pattern when retries are disabled

Consider adding this retry mechanism to other critical API methods that might benefit from retry behavior.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 7e57e079f5b1822c39f0fc7293cec392e1f7eb90 and c488ed51799a67ebab70d53045b754a8502a547f.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `package-lock.json` is excluded by `!**/package-lock.json`

</details>

<details>
<summary>📒 Files selected for processing (19)</summary>

* `packages/api-sdk/package.json` (2 hunks)
* `packages/api/package.json` (1 hunks)
* `packages/api/src/external/commonwell/api.ts` (3 hunks)
* `packages/api/src/routes/helpers/default-error-handler.ts` (1 hunks)
* `packages/carequality-cert-runner/package.json` (2 hunks)
* `packages/carequality-sdk/package.json` (1 hunks)
* `packages/commonwell-cert-runner/package.json` (2 hunks)
* `packages/commonwell-jwt-maker/package.json` (2 hunks)
* `packages/commonwell-sdk/package.json` (2 hunks)
* `packages/commonwell-sdk/src/client/commonwell.ts` (8 hunks)
* `packages/commonwell-sdk/src/common/metriport-error.ts` (0 hunks)
* `packages/core/package.json` (1 hunks)
* `packages/ihe-gateway-sdk/package.json` (2 hunks)
* `packages/infra/package.json` (1 hunks)
* `packages/mllp-server/package.json` (1 hunks)
* `packages/shared/package.json` (1 hunks)
* `packages/shared/src/error/metriport-error.ts` (1 hunks)
* `packages/shared/src/net/retry.ts` (2 hunks)
* `packages/utils/package.json` (1 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* packages/commonwell-sdk/src/common/metriport-error.ts

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (1)</summary>

<details>
<summary>`**/*.ts`: - Use the Onion Pattern to organize a package's code in layers
- Try to use immutable code and avoid sharing state across different functions, objects, and systems
- Try...</summary>

> `**/*.ts`: - Use the Onion Pattern to organize a package's code in layers
> - Try to use immutable code and avoid sharing state across different functions, objects, and systems
> - Try to build code that's idempotent whenever possible
> - Prefer functional programming style functions: small, deterministic, 1 input, 1 output
> - Minimize coupling / dependencies
> - Avoid modifying objects received as parameter
> - Only add comments to code to explain why something was done, not how it works
> - Naming
>   - classes, enums: `PascalCase`
>   - constants, variables, functions: `camelCase`
>   - file names: `kebab-case`
>   - table and column names: `snake_case`
>   - Use meaningful names, so whoever is reading the code understands what it means
>   - Don’t use negative names, like `notEnabled`, prefer `isDisabled`
>   - For numeric values, if the type doesn’t convey the unit, add the unit to the name
> - Typescript
>   - Use types
>   - Prefer `const` instead of `let`
>   - Avoid `any` and casting from `any` to other types
>   - Type predicates: only applicable to narrow down the type, not to force a complete type conversion
>   - Prefer deconstructing parameters for functions instead of multiple parameters that might be of
>     the same type
>   - Don’t use `null` inside the app, only on code interacting with external interfaces/services,
>     like DB and HTTP; convert to `undefined` before sending inwards into the code
>   - Use `async/await` instead of `.then()`
>   - Use the strict equality operator `===`, don’t use abstract equality operator `==`
>   - When calling a Promise-returning function asynchronously (i.e., not awaiting), use `.catch()` to
>     handle errors (see `processAsyncError` and `emptyFunction` depending on the case)
>   - Date and Time
>     - Always use `buildDayjs()` to create `dayjs` instances
>     - Prefer `dayjs.duration(...)` to create duration consts and keep them as `duration`
> - Prefer Nullish Coalesce (??) than the OR operator (||) to provide a default value
> - Avoid creating arrow functions
> - Use truthy syntax instead of `in` - i.e., `if (data.link)` not `if ('link' in data)`
> - Error handling
>   - Pass the original error as the new one’s `cause` so the stack trace is persisted
>   - Error messages should have a static message - add dynamic data to MetriportError's `additionalInfo` prop
>   - Avoid sending multiple events to Sentry for a single error
> - Global constants and variables
>   - Move literals to constants declared after imports when possible (avoid magic numbers)
>   - Avoid shared, global objects
> - Avoid using `console.log` and `console.error` in packages other than utils, infra and shared,
>   and try to use `out().log` instead
> - Avoid multi-line logs
>   - don't send objects as a second parameter to `console.log()` or `out().log()`
>   - don't create multi-line strings when using `JSON.stringify()`
> - Use `eslint` to enforce code style
> - Use `prettier` to format code
> - max column length is 100 chars
> - multi-line comments use `/** */`
> - scripts: top-level comments go after the import
> 

- `packages/shared/src/error/metriport-error.ts`
- `packages/shared/src/net/retry.ts`
- `packages/api/src/routes/helpers/default-error-handler.ts`
- `packages/api/src/external/commonwell/api.ts`
- `packages/commonwell-sdk/src/client/commonwell.ts`

</details>

</details><details>
<summary>🧠 Learnings (6)</summary>

<details>
<summary>📓 Common learnings</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>
<details>
<summary>packages/ihe-gateway-sdk/package.json (1)</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>
<details>
<summary>packages/carequality-cert-runner/package.json (1)</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>
<details>
<summary>packages/api-sdk/package.json (1)</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>
<details>
<summary>packages/carequality-sdk/package.json (1)</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>
<details>
<summary>packages/commonwell-sdk/package.json (1)</summary>

```
Learnt from: leite08
PR: metriport/metriport#3463
File: packages/api-sdk/src/medical/models/patient.ts:1-1
Timestamp: 2025-03-19T13:58:17.253Z
Learning: When changes are made to SDK packages (`api-sdk`, `commonwell-sdk`, `carequality-sdk`) or `packages/shared` in the Metriport codebase, alpha versions need to be published to NPM before merging the PR.
```

</details>

</details><details>
<summary>🧬 Code Graph Analysis (2)</summary>

<details>
<summary>packages/shared/src/net/retry.ts (1)</summary><blockquote>

<details>
<summary>packages/shared/src/error/metriport-error.ts (1)</summary>

* `isMetriportError` (13-15)

</details>

</blockquote></details>
<details>
<summary>packages/api/src/external/commonwell/api.ts (1)</summary><blockquote>

<details>
<summary>packages/commonwell-sdk/src/client/commonwell.ts (2)</summary>

* `CommonWellOptions` (71-74)
* `CommonWell` (76-1017)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (28)</summary><blockquote>

<details>
<summary>packages/infra/package.json (1)</summary>

`3-3`: **Verify alpha version bump alignment and publication**  
The version has been updated to `1.22.2-alpha.0`. Please confirm this pre-release bump is in sync with the coordinated alpha release across all packages and that the `infrastructure` package will be published to NPM as per our release process.

</details>
<details>
<summary>packages/mllp-server/package.json (1)</summary>

`3-3`: **Confirm version bump aligns with release strategy**  
The package is marked `"private": true`, so bumping to an `alpha.0` pre-release won’t be published to NPM. Please verify this change is intentional for internal coordination and consistent with the alpha version cycle across other packages.

</details>
<details>
<summary>packages/core/package.json (1)</summary>

`3-3`: **Version bump to 1.24.2-alpha.0**  
This update aligns `@metriport/core` with the coordinated alpha release of related packages for the new retry-on-500 feature.

</details>
<details>
<summary>packages/utils/package.json (1)</summary>

`3-3`: **Bump version for pre-release alignment**  
The package version has been updated from `1.25.1` to `1.25.2-alpha.0` to prepare for the upcoming alpha release cycle. Since `"private": true`, confirm that your monorepo tooling and any internal CI/CD steps correctly handle this pre-release tag.

</details>
<details>
<summary>packages/carequality-sdk/package.json (1)</summary>

`3-3`: <details>
<summary>✅ Verification successful</summary>

**Confirm alpha version publication**  
Version bumped to `1.6.2-alpha.0` aligns with our pre-release strategy for SDK packages. Per the retrieved learning, please ensure this alpha version is published to NPM before merging.  
  
Run the following to verify it’s available on the registry:

---

🏁 Script executed:

```shell
#!/bin/bash
npm view @metriport/carequality-sdk@1.6.2-alpha.0 version
```

Length of output: 73

---



</details>

**Alpha version publication confirmed**  
The `1.6.2-alpha.0` release of `@metriport/carequality-sdk` is available on NPM:
```bash
npm view @metriport/carequality-sdk@1.6.2-alpha.0 version
# => 1.6.2-alpha.0
```  
You can proceed with merging this PR.

</details>
<details>
<summary>packages/shared/package.json (1)</summary>

`3-3`: **Update shared package version to 0.23.2-alpha.0**

This version bump is correct. Please verify that this pre-release has been published to NPM before merging.

</details>
<details>
<summary>packages/api/package.json (1)</summary>

`3-3`: **Bump API service version to 1.27.2-alpha.0**

The version bump aligns with the coordinated pre-release across the monorepo.

</details>
<details>
<summary>packages/commonwell-jwt-maker/package.json (2)</summary>

`3-3`: **Update commonwell-jwt-maker to 1.24.2-alpha.0**

Ensure this pre-release is published to NPM so downstream consumers can resolve the new version.

---

`44-44`: **Upgrade @metriport/commonwell-sdk dependency to ^5.9.0-alpha.0**

Confirm that the corresponding @metriport/commonwell-sdk prerelease is available on NPM and resolveable.

</details>
<details>
<summary>packages/commonwell-cert-runner/package.json (2)</summary>

`3-3`: **Update commonwell-cert-runner to 1.26.2-alpha.0**

Please verify that this alpha version has been published to NPM for the certification runner package.

---

`45-45`: **Upgrade @metriport/commonwell-sdk dependency to ^5.9.0-alpha.0**

Ensure the prerelease of @metriport/commonwell-sdk is published and can be installed.

</details>
<details>
<summary>packages/api-sdk/package.json (2)</summary>

`3-3`: **Bump api-sdk package version to 14.14.2-alpha.0**

This version aligns with coordinated alpha releases. Please ensure it is published to NPM prior to merging.

---

`61-62`: **Update api-sdk dependencies to pre-release versions**

- @metriport/commonwell-sdk: ^5.9.0-alpha.0  
- @metriport/shared: ^0.23.2-alpha.0  

Verify these prerelease dependencies are available on NPM and resolve correctly.

</details>
<details>
<summary>packages/ihe-gateway-sdk/package.json (1)</summary>

`3-3`: **Version updates aligned with the retry mechanism implementation.**

The version bump to alpha and the dependency update on @metriport/shared are necessary for publishing the packages with the new retry mechanism implementation before merging the PR, which aligns with the established pattern for SDK packages.



Also applies to: 56-56

</details>
<details>
<summary>packages/shared/src/error/metriport-error.ts (1)</summary>

`13-15`: **Good addition of type guard for enhanced error handling.**

The addition of the `isMetriportError` type guard function improves type safety and enables more precise error handling in the retry mechanism, allowing the system to properly identify and extract status codes from Metriport-specific errors.

</details>
<details>
<summary>packages/commonwell-sdk/package.json (1)</summary>

`3-3`: **Version updates support the new retry functionality.**

The version bump to alpha and the dependency update on @metriport/shared are appropriate for incorporating the new retry mechanism for CW patient creation on 500 errors, following the required pattern for SDK package updates.



Also applies to: 63-63

</details>
<details>
<summary>packages/carequality-cert-runner/package.json (1)</summary>

`3-3`: **Version updates maintain dependency consistency.**

The version bumps and dependency updates ensure that all related packages are consistently using the same alpha versions, which is necessary for the proper functioning of the retry mechanism implementation across the ecosystem.



Also applies to: 44-45

</details>
<details>
<summary>packages/shared/src/net/retry.ts (2)</summary>

`10-10`: **Appropriate import for the new type guard.**

The import of `isMetriportError` from the error module aligns with the implementation of enhanced error handling for the retry mechanism.

---

`51-52`: **Improved error status extraction for retry logic.**

The enhanced implementation now correctly:
1. Recursively checks `error.cause` to extract status from nested errors
2. Identifies Metriport errors using the type guard and extracts their status

This improvement supports the PR's objective of implementing retries for CW patient creation on 500 errors by ensuring the retry mechanism can properly identify error status codes from various error types.

</details>
<details>
<summary>packages/api/src/routes/helpers/default-error-handler.ts (2)</summary>

`108-109`: **Improved error handling by unifying status code extraction.**

The code now consistently extracts HTTP status codes from errors by checking both `err.statusCode` and `err.status`, which ensures compatibility with different error types.

---

`112-120`: **Status code consistency in response construction.**

Good change - using the extracted status variable consistently throughout the response construction creates a more predictable error handling behavior.

</details>
<details>
<summary>packages/api/src/external/commonwell/api.ts (2)</summary>

`48-54`: **Implemented retry mechanism for 500 server errors.**

The configuration enables automatic retry on HTTP 500 errors with 3 retry attempts and a 1-second initial delay, aligning with the PR objective to retry CW patient creation on 500 errors.

---

`58-65`: **Applied retry configuration to all CommonWell API instances.**

The retry configuration is correctly applied to both member and non-member API instances, ensuring consistent behavior regardless of which API instance is used.



Also applies to: 68-75

</details>
<details>
<summary>packages/commonwell-sdk/src/client/commonwell.ts (5)</summary>

`1-7`: **Updated imports to support retry functionality.**

Good addition of imports from shared package to enable retry functionality and error handling.

---

`48-52`: **Default configuration for 500 error handling.**

The defaults are sensible - retry is disabled by default, which prevents unexpected behavior for consumers not explicitly opting into retries.

---

`113-129`: **Constructor updated to accept and apply retry options.**

The constructor properly initializes the retry configuration with defaults, ensuring backward compatibility with existing code that doesn't pass options.

---

`634-642`: **Enhanced registerPatient method with retry capabilities.**

The `registerPatient` method now uses the retry mechanism for handling 500 errors, which aligns perfectly with the PR objective.

---

`71-74`: <details>
<summary>✅ Verification successful</summary>

**Remember to publish alpha versions before merging.**

As indicated in the learnings, SDK package changes require publishing alpha versions to NPM before merging the PR.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check for package.json version naming conventions in the affected packages
grep -r "version.*alpha" --include="package.json" ./packages/
```

Length of output: 1007

---



</details>

**Alpha release ready—publish before merge**  
- Verified that `packages/commonwell-sdk/package.json` is already bumped to version `5.9.0-alpha.0`.  
- After merging, don’t forget to publish this alpha release to NPM (e.g. `npm publish --tag alpha`).

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-05T13:58:25Z
user: login: Orta21
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-05T15:27:15Z

Review comments:
diff_hunk: @@ -47,7 +48,8 @@ const defaultOptions: ExecuteWithNetworkRetriesOptions = {
 export function getHttpStatusFromError(error: any): number | undefined {
   if (!error) return undefined;
   if (axios.isAxiosError(error)) return error.response?.status;
-  if ("cause" in error) return getHttpStatusFromError(error.cause);
+  if (error.cause) return getHttpStatusFromError(error.cause);
path: packages/shared/src/net/retry.ts
user: login: leite08
body: 🐛  - if it existed w/ `undefined` it would consider as truthy
created_at: 2025-05-05T12:11:49Z
author_association: MEMBER
path: packages/commonwell-sdk/src/common/metriport-error.ts
user: login: leite08
body: No reason to have this here, CW SDK already imports from shared
created_at: 2025-05-05T12:12:20Z
author_association: MEMBER

PR comments:
user: login: linear[bot]
created_at: 2025-05-05T12:10:55Z
body: <p><a href="https://linear.app/metriport/issue/ENG-237/retry-patient-createupdate-cw-upon-error-500">ENG-237 Retry patient create/update @ CW upon error 500</a></p>
author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-05-05T12:10:58Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This set of changes introduces new alpha pre-release versions across multiple packages by updating their version numbers and, where relevant, upgrading dependencies to corresponding alpha versions. In the `commonwell-sdk`, a new retry mechanism for HTTP 500 errors is added, allowing configurable retry behavior via new options passed to the `CommonWell` class. The `registerPatient` method now supports automatic retries on server errors. The error handling logic in the API is refined to better unify status code extraction. Additionally, a type guard for `MetriportError` is introduced in the shared error module, and error status extraction is improved to recognize this error type.

## Changes

| File(s)                                                                                  | Change Summary                                                                                                                      |
|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
| `packages/api-sdk/package.json`,<br>`packages/api/package.json`,<br>`packages/carequality-cert-runner/package.json`,<br>`packages/carequality-sdk/package.json`,<br>`packages/commonwell-cert-runner/package.json`,<br>`packages/commonwell-jwt-maker/package.json`,<br>`packages/commonwell-sdk/package.json`,<br>`packages/core/package.json`,<br>`packages/ihe-gateway-sdk/package.json`,<br>`packages/infra/package.json`,<br>`packages/mllp-server/package.json`,<br>`packages/shared/package.json`,<br>`packages/utils/package.json` | Updated package versions to new alpha pre-release versions; upgraded dependencies to alpha versions where applicable.                |
| `packages/commonwell-sdk/src/client/commonwell.ts`                                       | Added configurable retry logic for HTTP 500 errors in the `CommonWell` class; introduced new options and retry method.              |
| `packages/commonwell-sdk/src/common/metriport-error.ts`                                  | Removed the `MetriportError` class definition (file deleted).                                                                       |
| `packages/api/src/external/commonwell/api.ts`                                            | Passed new retry options to `CommonWell` constructor in `makeCommonWellAPI` function.                                               |
| `packages/api/src/routes/helpers/default-error-handler.ts`                               | Unified error status code handling by checking both `statusCode` and `status` properties.                                           |
| `packages/shared/src/error/metriport-error.ts`                                           | Added `isMetriportError` type guard function for runtime error type checking.                                                       |
| `packages/shared/src/net/retry.ts`                                                       | Enhanced error status extraction to recognize `MetriportError` and improved cause property check.                                   |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Caller
    participant API
    participant CommonWell
    participant Network

    Caller->>API: makeCommonWellAPI(...)
    API->>CommonWell: new CommonWell(..., options)
    Caller->>CommonWell: registerPatient(...)
    CommonWell->>CommonWell: executeWithRetriesOn500(fn)
    loop Retry up to N times on HTTP 500
        CommonWell->>Network: API request
        Network-->>CommonWell: Response (possibly 500)
        alt HTTP 500 and retries left
            CommonWell->>CommonWell: Wait, then retry
        else Success or no retries left
            CommonWell-->>Caller: Result or error
        end
    end
```

## Possibly related PRs

- [metriport/metriport#3627](https://github.com/metriport/metriport/pull/3627): Updates package versions to stable releases; related due to overlapping package version changes.
- [metriport/metriport#3750](https://github.com/metriport/metriport/pull/3750): Updates package versions from alpha to stable; related in purpose to the current version and dependency updates.
- [metriport/metriport#3641](https://github.com/metriport/metriport/pull/3641): Similar package version updates, moving from alpha to stable, related at the metadata/versioning level.

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKNxU3bABsvkCiQBHbGlcABpIcVwvOkgAIgBRADkAcTAAJgBmAHZIGxJcF0gAYQB1Hmp4dkZ/ahJ+LABWAAYm0NjIAHc0ZAcBZnUaejlIbERKSGj1EiaADnRkW0gMRwFx7Jm0jRhYOuZtLAZYTFIUDALFbAYY1FwdlGZuaLYzivwsfAAzdD98wrZDzBIZiQD74PgMGriDBEb6lcriKodHZYNCQZpNeyUKR8SgUMH8BgMbAURBbOCUOrOOoYfBLEgdSBKbhkJQYBiVZBoWhKejdcoUXD8L63VDYbi0WoaNwheDQzp8pgYWiXQboCH4RDIZjecSPOpkCTwPEYZ64ZAESDY+AfeS3OofbBs8RvNBedSyDgGKAAGXwDFdXlk4W4FSqEJIrywXWQio+RrY9AtHTBAGtwph6P4Chz6vZ4NqvLV6OjILiwcgOhSIiEYg5CdJEA6fLIpVAAPJYO32XBoIiymEGo1vU3B0NnaoR51RvmuxC0q1xmJJ1OtyCJWk0RBQmHRniUUEUBO5ruIDMCfAAD34fF4FzE8DepYwhuNptJbju/mi3Tqj0wpwYLxsCUZAvwjRB+zXKwAFlygYFNe2kdAlUgNgKD7OUuwBaFpHCDp1FgCIdjGbsSG4LVnBTGI+WZJV+zJO5PB8H4ghCFBOXrTV4AEaJ0EFWBcFwciOAAehEvtbmwAQNCYZgRLYbNuDBXB5N+eAlIFESmK8ET1k2Ix9GMcAoBZIUcAIYgyGUVVZNNLheH4YRRHEKQZHkJglCoVR1C0HRDJMKB3GQVB/zQPBCFIcgqBslg7L8NAGQcJxCmGDzlG8zRtF0MBDCM0wDBDeDEMQES0G4eAwEQWgUy0tAitIDQhDnDBPViNqDAsSAAEEAElLKiot7EcPZCk+RgjhwxAP1/OqEJObEIMfMaAAMAAEFIodTlNK8rKuq5b5WQMUJVVD48WBZaAEYABYNBuu6DotVFyAZXgSDAMCf0tShFqwK7bvutIwFdbgjg0Jplq2IowX8RAlLo6FA3CXBk0ZMiWTIdkkMrfwRm4IgqB5CINx2I10C8UHUTej6SG/EiFofDBEC4NaNq2zTbLeSsfD2lMDrOlhIGWgA9BoNBmB7iaF0WNAATnB4GKbBiHkPoVm1I0lTECOfxaH587paaDRMkli0RaNk2gZB5XIbXWl8DtcEJtIc1aSZDG2Q5cJEAhdSzXCfEFK5ahURx3YuRIKUjA6ywuq8GhosZ12iLqJRAOcSNkDGkgL01mJ8U8Hj4AYJ9Ig5Ay7fIKU2tiAz8sKubpB2+BavqyOmreVr2s63r+us2thuceQxuwl3pu+klGZBSovHoWUU6FhvEMa5r+fgXiDwX5ayvgA6l5OXdjsGgWLtiS7jayO7Yke2llrPi/jcVynwevrZ134R3xuOJCLXdpVMa9vYX23B/bXlQvkYOPZOhVj2EoKO5hY7x2sknKWXY06FkTm8LOXwc553oAXKSboS7sHUOXL0lc6gAAoaRf0mlLXByl843kIcXUupDpAAG56iBjgo3cBPYTqogZo+I+gwACUBga51zAEYfeTcd4iUQBQBgIkc4JwwK6ESnMMDcx0jvDQZou61x7n1SK/d6BJRGsPL4o9pDj1sacc4yoricjpAyZa0NWBvBKLTLwbYQFJwOoIEQYglhoCPMtfAASsEHXwrcb4sZ4BEGJJGEE+IJq0DdHKAAEtAaAVg0QtFLBQPEJJIDDCzC4SCYopYZAiPmbGBFkKnFIa6NGhZrGQEui0DE/QfBIFEG8WgpJtioEidEpmQSnKhJuMicompqKchRNyUhLpfDOGSaaVBdwPGxW8b4g6iotwUBVPif0Phgqdh2XsKinjmD7J8F1KwPV+aOnvI+Te554lsGYKsPgGYlhvDAD8v53VnmnC3JgFxDE6iw0FGNLsDonRTy8PgPsJd/B7FlEdNkzs6DhFlIBYCkETxnkvONUQKZVYLyUAnfoGipxmSRPkHYfAuxPJ6uxb4ILxgcqjj3JBmCmbbNTqIDBmczIMIFEwngLDiFnHYVNch79bHJxPEkhlxIkLZ1zow/BzCi7yrLtIGFII3mMuWjckgdyHleA5ZQsERBEjhJIFwY5/YA7oTbD1AAIm67M0IxFcBtRgHxjznkHUxfsHFti55YAgkQTV/gA4YB4eoS56i2n5j1KaVJqB7m0GtJURMtJCVASUAvF6QsolTkQHvDOClxjMoOFggoKpIK7K8aGg5EKexshNZI9qXp66zWKs3RRyiRJ4jwE3HYFMfoiSUB8MK8cwBlgoGADJ0QKAGOZoO4xsdTFWWigPZKnTVXj3XZALdlAADkyBUXorSXwLdkF10Viabk/J3ZqCjAUCBQ6qFFBFqXLSR01pbSfjUiQCQbSEV3EhbgP9aUthWH8IafAowkYoHham9yOx4IxE3stXEGhEOjGhkoZaXCaQMnUBS+CyBN4kAIuMEjJSyM9iQ4gSjJAgl8HYzu8jdbqXdATcKkUydUSovOULYTB1YObRUNEU1sN4YkWE9Srsy15PT1pnGheamsF1HPLQeQVIU7xvyCMCCmEEA4pA2rXTin4DKbqNimgXIzKFv8GIHhowO2keE7x22ABlfM69nDYe0xotga99OnEM9IdTJnFDyFFOKQaFpRh1GWgJISoWuOjAANrCYALoHQ8xGfBXw8uCW4IV39iBitBaKzxxQJAKsMVQA4sgDhYZEWoMU0pH74ksc/jptrIWwGTaa3vPEzIBQ5gsze+gRykA0DOIGeBMduqColRaNBYqM61slbq6V+rZWGrYQiJVUAVV4orDAiOIq0bpyFVnPg4nf0DZ1XgsBhciE3ZzPPSTjJrQfGrkOiAMiCqjpdloqkQRXTujAFcAUH1HRRVbo3Fend927d7mYk9FjB6jRsY98eciJ6/TMurRS21/T+GR26XAsg0eUFwJjjAUVYl8lEURg2V07oS0ujfb4VbqafXpj9KewvLoSytkrNA4NbbQxKcloZ/Zot3D/qyLGyB6ebU1iJeAOxiC1C6OzqqfNqVG/ZlrHWdBYlVgF/QE+P6eJ1GEcK82d15Zi7t8LC2GRTYkxY3wNTzlJCUmVzwfwNM6be9l1gw2/vH7WxVyrAFfvLZPxtm/e2n9VVSx9sb0BQdBGeoUBgOMyShXQNxrAyO0dCf7dO4d3Xx2Ptnf+wQ67JDbsVwe9/ZOUrVT96B4Pjkt63vitO2HVCL3Qf2fBx8SHBPh2w7kSVJngRsAo7Z7zHHy8O4tQJyYvuJOhpnrMhegw5IadT2WL88YK+Zptzx1gOMG98TafWhrIzkjgfqztbvtLwohIBm7iCELufAAGxh5CzwEZ7K6q6F4fysq0IuxSxIrvIaKgHhB64AK4RALl6IDV6V4hyN7hxwKt4CoJwHbh5z4nYoJ/Z6oA5yrA52LKq0gl4Wjj4yqA6sLT7SCz7oIsGp6L7N5Q61xb6yLw5NzaK6Ic4Y4nI86UAn4NRn5GKE5HoDSqiWJDx36U4P6MQKFP5LS1YAEM4cx7I6K+IqFc5qG85QGZanSwHGwIGB5PTx4UhJ4WF/TnxpAIFK7PwQxbBdQrJTgBhBg0roz/xsjDx/TWHG6M52HKE2585HT4yEyC6Cw+7Sxiyi7i5Uz+DS7J6TyPgixizyxND55Z62zvwOyYF8G0hl5+zkFoy0T66AKBwQKCLUFL60HRz0HIKp6d6irvYSpsEXYcED4KpD48HkCQDUK8GPb0LnYT4GpT4LEz7MEfZiIyHSLyFty77pEOFCAdBc5WoUCaHtzNQ6GX7E6DSGHk5YHcGP7U4FErQpEO5aLnE8yXHXFoBUQUBZF4wnR5EXRBEAwlG+HlEBFIHGy3ShEF7FBvBEga5baxFHbdGYxJFCy/Em5KEOGZGuEEwRzu4GwFHVHiyIGlF+HgQVG060m1H1FoF2wYHjCtGkEdGEHxE9EkF9ECJUFSERw7ajE94TH7HTE4KbGCGcEiF3YUJHFyFw6nH/FdoZHVR3Ff6PGHpX4vFk7nomGfHmHfFWFszEkAleC8zgnQEe7LRFGIFOlywKyZ6q4Ep0T+jbgS70jkyUw/BJ4RFRGMwxHIxd54mJGInEZEnbTaxUh6yAaxowGCy56h7eG3zB7Gyh6okNHhD+AfDRD3hyj/higUkVo+EvTjCZ6InwZDZyLoHNHcnrG/wCnEGdHtEgKdHCmQKhzPbDEIJ7YMEd5MHiE94zFbFXY7HGrKkj50L8HymXZCFGqKpiHd4SpikVor6oCFrr6qkw4nGNxnFamkk6lKIqKASVBnCan3L2E+C7r6ndR6HmI35WLGGj7jydp3lhpeCHKFiaiAZkATRXAlpDTcCaw1514pJe4/AFDyCrBHAYZ8CPhfoFIlg9RnCUD4GQChZYjjDxAlL4hGZMwmrdRuJCwhq/n+K1qVZYUUDLpXCAayhOKXD4rkyor4SlnvATJtKRIYCEWlLoiHJvDQUN63BDaKjnBeCgS/DmaCQkAPCgKyitK+BKAdLpgoR7AXj5iOB8Q0BKVMb4gljvqmrpyAW0bdhgg/zER1A1ooLzylGSC1DVoCVEUUDCXx5RKc6xFLorq+kWg0KVIcimrLT+B9hbiUBWBji4AHQKSwCKCAYFqOZSwdBUDcA4bIAcqMABidBNLPT+m8DOU0D8IJVqw5yiAzolAER5DZjSAdjCV4QICHA16FrRHNhwWbQ2Wwr75sSPgmXuVHS2YwgnhO7lUXiVU0DVW3CJD5DJgUApi1VdUiZ4DrzujdayXwUTBoqsJoTYF+U6idXDwTJGWR69VbhgA0hc51RXAgIxDvp5XxKhTcgxCVIEloWFIYjCampVrxWJUVVEibgLwhgLLu7mpTw+bORppfDBVIQWaFqnhe60BbA9QPDKRPa4zQEWhlrAR1BdhvUjDiCs7LYoRXrmVjAjJNGfzZV/XDKDEpnZYkRg4E3/ATRAgSmIIjkoLSnjmymlhLlzEzmKoVyRFEzLQdiCVgjog0WBIRCyDMhcBqIsiG7xATWA0kDTWwBLUcgy0xIrE5xEqFpyg6YJXeC0BLWyDLRiKPWESoh7BKjUBgjyBhVyUHTnj4DfgYCrii0xDfm2q62TKOL7h1R1BxKET2VrJCziBsCYaxUrEv5/LW055vCS0eUtAHSUIS3uXS0nWHHkLQTAaLhratonJiD4grRUU9rk1Sw3VkSCjjK1rBp2HUUnV0WRVeYrQADe9SMdeAAA/FwAneMAAL6QzkI+30BFWwYlW3iLZs6uWp3ohcBZ1CUtAB0iZmyV0+D/libe0vWT2bTT27AsqJUkZq1VU1XQaIANUtDADQB6CUIfAtQrHW0AC8eg1g50Ayd9egQan9LA3999dFlFzdVdAF74UiapO+t5XMZ5NUF5MDGAqkNhXO66j5F+BpzxBhxpH5k0486l+QRG68oqcY5AvIjAowBAwIZN4DYSES0EgBAoqdj0RwgoSt/8iYdwAg2A68XO88y0zDjA4DG1QjYmAE5a1EyybVYZvgs9PlcmbW4uCVs8zSH1mmaU/Jy6OoJKtIJYlCmFmavgeFFA2IkAqd1t1ogKgot4hoPIZlJdpy/y9Yd15DbAmokB7q3FvIPF7VP63G/6JAo4XEdmx97jJw0pAgX0Aj7lIlTMbaZd/yKEYwgkJKOyumcjAo5mhIYIRtRA222wdQ1du4IEGqoGPwb0Yw44D1Yd8wc47Ig0ajbWATp1Nm7mVylIEFRCkYHNw5YxEmY5G5p2k5Cp8xs5Fc8QCquM1dy0DDKDgjmK+AUgVJaZ0DJJPMNuE6l5dhyDqRGOaDZoy0m+h56px5/x/gup2hGDz5hp2Dt+I8ppdwBRi4Kj7+i8ChX+a8v+bKOycZth/g9abcrhkJyzp8MJV84ud8YLeZL8jRReLRrZbs7ZnsJBXZoC4+PZfAlBUCW5LeIxnNfTaqXeUxQzcpfe2xwhux3B92bwVCNCPJAhy5iplLiA65xLScEikDxz0DZu70RAluaAYBNUjZlzUiTxx6RpdzFOn5phH+fCFphJVp20PLFuNAVudpQLx8QuRsl0AecJkuCeCJNJ2r8s0L4R6JGucMWuiMOJkZHsDABJ9uJuCZus4Js4YGbhUJiJ6Z9JvhieTJXr2ZeeHpZrVN8Lo+UsRByLnZwCoCvZAxOLPTccXN4xAzbLqewzjLozwtPB7xY+Atk+FLs5rL8+KCOLiWYOe5G+nLI6GpsoZ0aAFzDxVzRO4rtz759z0rj+TzM8Bm2mwrq808XzW8dbVAxyKoWqALfCh8HrILQs98aQmwl018NdvrhrKef087mwprr8nJzZTs4bbZUZBu3sMbGLUFSSKSjKCbdB+LUpqbJb6bpL7BBbq5ix1LubGxZL05hba5MptaB5NbpzzAPg3AlU+Ftx/b+OormDrbp67bUreDMrMZPb5bOykHGAnz9of+1yIHYHJjlAk7kB07wLqZp8RsGZy7ZssQ5HKBYRO7obLZB7iLR7gCqLZ7WL/ZTe4pN7vTd7cRabwqGbgtP7b7FC8daxTH/NX7K5XBPZeG3wBRnjMIAuiW1OHHHL0OgHY6zrdAjbUH3cMH+hcHRhHbiHXb67SwKwb+7TEBWhzUg7WH3zuWvzjuiZhHB8/OM7pHQsIeLpvnprsLXJ+7C5tIuB7V7o/JLHKLp7FB/RopA5uLQ5SbBLr2vNJLUnz75Lr7ZC64VcRzWnCOOntAmzqi7lOzDua67l6D0H1zWDxnbx9+XUctzIkAySzgYNyKVRSAszuzuAgju4XIRM0pBa3gkcoyTG4Nj4PYVESyIwGAKYtGWAV6wSzk1KWYxIwqqI7tntpwhaPpkEzKn8XYV6IUWAHmUKdlwoOyPXDugj5NIjg3qyWANj8AAGqIxy2gRAAkB4XQFA9AVuUshwlKC8V6bOLXQ2ah0diXbeyb/T/HD7gnT7sxL7snFcAAYpN1I3QCzOPmap12d4gDd5rKnZQriFwI6At/gB0BgH/biFykT8pII/w9A0VyV+uuV5rJV6Uruoc9W9vgoSVKzwg+QCpG9dVwZ7V7B6TpK7m/YniugNyLN9mspGZNpt14w31zE3j3gd59phoBoKV6Uhz8pFz2CHFRcCppAJhVvKQLgNkvVo1txmj+dII2F4zBGYU1roykD/BJBJvP+OuvekLP6DlvNt5Zk1yslUXd5wFiE3OyH2MO0PPOugdIgLIC8FeD4ZDaEm2iKOQIBT71SoJmCDJGFGMLbKLU9+GX6QyIqNI4+CFPvYDwRlSpY8d+5VyqiAzwKMNviLHzCMtOr3M+5aT+5WIrbD1MKCcoEzhnBRt+aGk4o15XPfIB7l2N32w1V+N/zZtnTe36Un43+molQDr4+qwhaA4BBSrwVQyKD/LXUHDKIEWiXBaBv73ySIm+3tzfexIYjxl8j1l1R45seS6qRND9m1RI8pyMnJUqaij7FxUkbwHhGgHXzOQF+bTQxttSfTwZ9QOlLcG+gFpu8qitve3gVjazO8WAzDADvzw1KrUZKenc/DVxbZGdpe8HWXkh27YJZXmy0dDph2fRbxaBImanMR01Zpl52YsJdnCSly0x/WNJMQbR2Vj0c4WjHELl0TtascYuYCDjoMWkI8dkufHI7AJ2wT/8oBTLMZksVpYScVBDLYTtl1EJ/t2W+XXKAFCfA1ZzIEUKXgoFYDsAuAVARKDg1SgdYvIagTKH5BygGBnBtkdQAAH1XuiAKIehkqCVhaAUQyFD30MjhDjIjAa6DMBmB0AGgl0LILLFlhoA4CWQEgJEwEBZAmgtABoBkCaDXQGglQhoNdDQAzBmgaQNAM0KyBfB0hEQ2KNENiHxCYMiQugFENMj6AgAA=== -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=metriport/metriport&utm_content=3782):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE