Skip to content

Conversation

RamilGaripov
Copy link
Contributor

@RamilGaripov RamilGaripov commented Aug 20, 2025

Issues:

Dependencies

Description

  • Some updates to the commonwell-cert-runner - all of @leite08's work
  • This doesn't handle the initiatorOnly scenario - that's addressed in the downstream PR

Testing

  • Refer to downstream PR

Release Plan

  • Merge this

Summary by CodeRabbit

  • New Features

    • Added initiator-only organization management flow to the certification runner.
  • Changes

    • Environment variables updated to use Root OID and new existing-org OIDs; support reusing a consumer org.
    • Document metadata now derives from the organization ID.
    • Server logs standardized with “[server]” prefix.
    • Removed artificial wait delays for faster flows; added an extra link-check for clearer results.
  • Documentation

    • README updated to reflect ROOT_OID and environment variable changes.

Ref eng-513

Signed-off-by: Rafael Leite <2132564+leite08@users.noreply.github.com>
Ref eng-513

Signed-off-by: Rafael Leite <2132564+leite08@users.noreply.github.com>
Ref eng-200

Signed-off-by: Rafael Leite <2132564+leite08@users.noreply.github.com>
Copy link

linear bot commented Aug 20, 2025

Copy link

coderabbitai bot commented Aug 20, 2025

Walkthrough

Blocks use of member and system root OIDs for organization OIDs, switches cert-runner from memberOID to rootOID, refactors env variables and ID generation, updates document-reference meta.source, standardizes server logs, removes artificial waits, adds initiator-only org-management flow, and integrates it into the runner.

Changes

Cohort / File(s) Summary of changes
API OID validation
packages/api/src/external/commonwell-v2/api.ts
Disallowed OID check now tests against both member and system root OIDs and throws a MetriportError with orgOID in payload when blocked.
Config deprecation
packages/api/src/shared/config.ts
Added JSDoc @deprecated to Config.getCWMemberOID() (no signature/runtime change).
Cert-runner env & README
packages/commonwell-cert-runner/README.md, packages/commonwell-cert-runner/src/env.ts
Replace CW_MEMBER_OID with ROOT_OID in README; add exported rootOID, remove memberOID, rename existingOrgIdexistingOrgOid, and add existingInitiatorOnlyOrgOid and contribExistingOrgOid.
ID generation / payloads
packages/commonwell-cert-runner/src/payloads.ts
makeOrgId now prefixes IDs with rootOID instead of memberOID.
Document reference & contribution server
packages/commonwell-cert-runner/src/flows/contribution/document-reference.ts, packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts
Removed memberOID param/import; meta.source derived from orgId (prefix urn:oid: if missing); server logs standardized with “[server]” prefixes; makeDocumentReference signature updated.
Document consumption
packages/commonwell-cert-runner/src/flows/document-consumption.ts
Removed artificial 5s wait before querying documents.
Link management
packages/commonwell-cert-runner/src/flows/link-management.ts
Removed waits; added second getPatientLinksByPatientId call (extra API fetch/log).
Document contribution flow
packages/commonwell-cert-runner/src/flows/document-contribution.ts
Import contribExistingOrgOid; optionally reuse consumer org OID; adjust step numbering and logs; create demographics just before first contributor patient; add patient linking (2.4) and document query (2.5).
Org management (main)
packages/commonwell-cert-runner/src/flows/org-management.ts
Use existingOrgOid instead of existingOrgId; remove auto NPI generation; add check that created org returns organizationId.
Org management (initiator-only)
packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts
New module: orgManagementInitiatorOnly() added to create/update initiator-only orgs; defines OrgManagementResponse type; aggregates errors.
Runner integration
packages/commonwell-cert-runner/src/index.ts
Import and invoke orgManagementInitiatorOnly() in main runner; capture failure in failedFlows.
Single-command init
packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts
Switch imports/use to existingOrgOid; remove memberOID usage and set homeCommunityId from org.organizationId.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Runner
  participant Env
  participant CertRunner
  participant CW

  Note over Runner,CertRunner: New initiator-only org-management flow
  Runner->>CertRunner: orgManagementInitiatorOnly()
  CertRunner->>Env: read member cert/key, memberId/name, existingInitiatorOnlyOrgOid
  rect rgba(220,240,255,0.35)
    Note right of CertRunner: Flow 1 — create initiator-only org
    CertRunner->>CW: createOrg(makeOrganization(initiator-only))
    CW-->>CertRunner: respCreate (transactionId, organizationId)
    CertRunner->>CW: getOneOrg(organizationId)
    CW-->>CertRunner: org details
    CertRunner->>CW: updateOrg(organizationId, modified location)
    CW-->>CertRunner: respUpdate
  end
  rect rgba(220,255,220,0.35)
    Note right of CertRunner: Flow 2 — update existing initiator-only org
    alt existingInitiatorOnlyOrgOid present
      CertRunner->>CW: getOneOrg(existingInitiatorOnlyOrgOid)
      CW-->>CertRunner: org details
      CertRunner->>CW: updateOrg(existingInitiatorOnlyOrgOid, modified location)
      CW-->>CertRunner: respUpdate
    else
      CertRunner-->>Runner: error "existingInitiatorOnlyOrgOid required"
    end
  end
  CertRunner-->>Runner: done or aggregated error
Loading
sequenceDiagram
  autonumber
  actor Runner
  participant Env
  participant ContributionFlow
  participant CW

  Note over Runner,ContributionFlow: Contribution flow — optional reuse of consumer org OID
  Runner->>ContributionFlow: documentContribution()
  ContributionFlow->>Env: read contribExistingOrgOid (optional)
  alt contribExistingOrgOid provided
    ContributionFlow->>ContributionFlow: orgId = contribExistingOrgOid
  else
    ContributionFlow->>CW: createOrg() -> organizationId
    CW-->>ContributionFlow: organizationId
  end
  ContributionFlow->>CW: createPatient (contributor) -> patientId_2_2
  CW-->>ContributionFlow: resp_2_2
  ContributionFlow->>CW: createPatient (consumer) -> patientId_2_3
  CW-->>ContributionFlow: resp_2_3
  ContributionFlow->>CW: linkPatients(patientId_2_2, patientId_2_3)
  CW-->>ContributionFlow: link status
  ContributionFlow->>CW: queryDocuments(consumer org, patientId_2_3)
  CW-->>ContributionFlow: documents
  ContributionFlow-->>Runner: done
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cccad59 and 49c1a23.

📒 Files selected for processing (2)
  • packages/commonwell-cert-runner/src/flows/document-consumption.ts (1 hunks)
  • packages/commonwell-cert-runner/src/flows/link-management.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/commonwell-cert-runner/src/flows/document-consumption.ts
  • packages/commonwell-cert-runner/src/flows/link-management.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: check-pr / lint-build-test
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch eng-200-cert-runner-updated

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/commonwell-cert-runner/src/flows/document-contribution.ts (1)

85-101: Fix potential TS compile/runtime issues: orgId and commonWellConsumer can be undefined where used.

  • orgId is typed as string | undefined and is passed to getOneOrg without a guard.
  • commonWellConsumer is typed as CommonWell | undefined but is used unguarded.

Add explicit guards to satisfy the compiler and prevent runtime surprises.

-    let orgId: string | undefined = contribExistingOrgOid;
+    let orgId: string | undefined = contribExistingOrgOid;
@@
-    const org = await getOneOrg(commonWellMember, orgId);
+    if (!orgId) {
+      throw new Error("Failed to determine consumer org OID");
+    }
+    const org = await getOneOrg(commonWellMember, orgId);
@@
-    commonWellConsumer = new CommonWell({
+    commonWellConsumer = new CommonWell({
       orgCert: orgCertificateString,
       rsaPrivateKey: orgPrivateKeyString,
       orgName: org.name,
       oid: org.organizationId,
       homeCommunityId: org.homeCommunityId,
       npi,
       apiMode: APIMode.integration,
     });
+    if (!commonWellConsumer) {
+      throw new Error("Failed to initialize CommonWell client for consumer org");
+    }
@@
-    const resp_2_3 = await commonWellConsumer.createOrUpdatePatient(patientCreateConsumerOrg);
+    const resp_2_3 = await commonWellConsumer.createOrUpdatePatient(patientCreateConsumerOrg);

Also applies to: 102-114, 139-147

🧹 Nitpick comments (12)
packages/commonwell-cert-runner/README.md (1)

98-108: Clarify whether ROOT_OID expects raw OID (no urn:oid:)

The rest of the repo generally treats OIDs without the urn:oid: prefix (and adds it only where required). To prevent confusion, explicitly document the expected format here.

Apply this change to make the requirement explicit:

 # Member (Service Adopter) credentials
-ROOT_OID=1.2.3.4.5.678
+# Root OID (numeric only; do NOT include 'urn:oid:' prefix)
+ROOT_OID=1.2.3.4.5.678
packages/commonwell-cert-runner/src/flows/link-management.ts (2)

41-41: Removing waits can introduce flakiness; prefer bounded polling with backoff

Commenting out the waits will speed up the flow but may cause intermittent empty results due to eventual consistency on CW endpoints (you already call some endpoints twice to compensate). Consider replacing fixed sleeps with a small polling helper (bounded retries with delay) to keep runs fast but more reliable.

Example helper (place in ../util or similar) and usage:

// util/poll.ts
export async function poll<T>({
  fn,
  until,
  retries = 5,
  delayMs = 1500,
}: {
  fn: () => Promise<T>;
  until: (value: T) => boolean;
  retries?: number;
  delayMs?: number;
}): Promise<T> {
  let last: T;
  for (let i = 0; i < retries; i++) {
    last = await fn();
    if (until(last)) return last;
    await new Promise(r => setTimeout(r, delayMs));
  }
  return last!;
}

Usage example replacing a plain GET:

const resp_2_3_3 = await poll({
  fn: () => commonWell.getPatientLinksByPatientId(patientWithProbableLinksIdEnconded),
  until: r => Boolean(r.Patients && r.Patients.length > 0),
  retries: 4,
  delayMs: 2000,
});

Also applies to: 74-74, 137-137, 153-153, 174-174


81-85: Duplicate getPatientLinks call needs rationale or removal

This second immediate call to getPatientLinksByPatientId isn't accompanied by a comment (unlike the probable links call below). If it's intentionally mitigating eventual consistency, prefer the bounded polling approach, or add a short comment to explain why this duplication is needed.

packages/api/src/external/commonwell-v2/api.ts (1)

60-66: Normalize OIDs before checking to avoid 'urn:oid:' mismatches

The function docstring says orgOID is passed without urn:oid:, but in practice callers can slip a prefixed value. Normalizing once makes this robust and avoids false negatives in the disallowed check.

Apply:

-export function makeCommonWellAPI(orgName: string, orgOID: string, npi: string): CommonWellAPI {
+export function makeCommonWellAPI(orgName: string, orgOID: string, npi: string): CommonWellAPI {
   if (Config.isSandbox()) {
     return new CommonWellMock(orgName, orgOID);
   }
 
-  const isMemberAPI = [Config.getCWMemberOID(), Config.getSystemRootOID()].includes(orgOID);
-  if (isMemberAPI) {
+  // Normalize: accept both plain and 'urn:oid:'-prefixed inputs
+  const normalizedOID = orgOID.replace(/^urn:oid:/, "");
+  const isDisallowed = [Config.getCWMemberOID(), Config.getSystemRootOID()].includes(normalizedOID);
+  if (isDisallowed) {
     throw new MetriportError("Cannot use the member/root OID as an organization OID", undefined, {
-      orgOID,
+      orgOID,
     });
   }
 
   return new CommonWell({
     orgCert: Config.getCWOrgCertificate(),
     rsaPrivateKey: Config.getCWOrgPrivateKey(),
     orgName,
-    oid: orgOID,
-    homeCommunityId: orgOID,
+    oid: normalizedOID,
+    homeCommunityId: normalizedOID,
     npi,
     apiMode,
   });
 }
packages/commonwell-cert-runner/src/payloads.ts (2)

38-41: Double-check orgId normalization with ROOT_OID

makeOrgId now returns ${rootOID}.5.<org>. If ROOT_OID sometimes includes "urn:oid:" and sometimes not, orgId will vary in shape. Downstream code (e.g., DocumentReference meta.source) compensates for this, but other consumers might not.

Consider either:

  • guaranteeing ROOT_OID format (documented expectation), or
  • normalizing here (e.g., stripping trailing dots and/or optionally adding/removing "urn:oid:" once).

Given the surrounding code, a small comment noting the expected ROOT_OID format would also help future maintainers.


173-175: Minor: Update TODO to include actionable detail or tracking link

The ENG-541 TODO is fine; consider adding a brief “what/why” to ease triage later (e.g., exact networks change expected), or link to spec section if applicable.

packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts (1)

139-140: Duplicate express.json() middleware — remove the second registration

express.json() is already registered on Line 32. The second registration is redundant.

Apply this diff:

-app.use(express.json({ limit: "2mb" }));
+// app.use(express.json({ limit: "2mb" })); // already registered above
packages/commonwell-cert-runner/src/flows/document-consumption.ts (1)

51-51: Reconsider removing the wait — query may race with eventual consistency

Removing the delay can make the document query flaky if the system isn’t immediately consistent after patient creation. Prefer a short, bounded retry/poll instead of a fixed sleep.

Example approach (requires adding a small helper; replace the commented line):

-    // await waitSeconds(5);
+    // Retry querying docs up to 3 times with small backoff to avoid flakiness
+    const maxAttempts = 3;
+    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+      const docs = await queryDocuments(commonWell, encodedPatientId);
+      if (docs.length > 0) {
+        // proceed with documents already fetched
+        console.log(`>>> Got ${docs.length} documents (attempt ${attempt})`);
+        break;
+      }
+      if (attempt < maxAttempts) {
+        await new Promise(r => setTimeout(r, attempt * 1000));
+      }
+      // On last attempt, fall through to the normal flow
+    }

If you prefer to keep current structure, at minimum, note this change in the test instructions since it can affect timing expectations when validating the flow.

packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts (3)

13-15: Remove unused exported type and drop unused import.

OrgManagementResponse isn’t used in this module, and CommonWell is imported only for that type. Clean it up to avoid dead code.

-import { APIMode, CommonWell, CommonWellMember } from "@metriport/commonwell-sdk";
+import { APIMode, CommonWellMember } from "@metriport/commonwell-sdk";
@@
-export type OrgManagementResponse = {
-  commonWell: CommonWell;
-};

Also applies to: 2-2


42-46: Add post-create orgId guard (mirrors org-management.ts).

Ensure createOrg returned an organizationId before proceeding.

-    const initiatorOnlyOrgId = respCreateInitiatorOnly.organizationId;
+    const initiatorOnlyOrgId = respCreateInitiatorOnly.organizationId;
+    if (!initiatorOnlyOrgId) {
+      throw new Error("No orgId on response from createOrg (initiator-only)");
+    }

72-82: Avoid in checks and delete; prefer truthy checks and explicit nulling for external payloads.

Coding guideline favors truthy checks over 'in' in obj. Also, since we're shaping a payload for an external API, setting fields to null (as you already do on create) is clearer and avoids potential type issues with delete.

-    if ("securityTokenKeyType" in initiatorOnlyOrg && initiatorOnlyOrg.securityTokenKeyType) {
+    if (initiatorOnlyOrg.securityTokenKeyType) {
       console.log(`HEADS UP: Security token key type is not null`);
-      delete initiatorOnlyOrg.securityTokenKeyType;
+      initiatorOnlyOrg.securityTokenKeyType = null;
     }
-    if (
-      "authorizationInformation" in initiatorOnlyOrg &&
-      initiatorOnlyOrg.authorizationInformation
-    ) {
+    if (initiatorOnlyOrg.authorizationInformation) {
       console.log(`HEADS UP: Authorization information is not null`);
-      delete initiatorOnlyOrg.authorizationInformation;
+      initiatorOnlyOrg.authorizationInformation = null;
     }
packages/commonwell-cert-runner/src/flows/document-contribution.ts (1)

223-241: Don’t mutate the shared patientShirleyDouglas object; clone before customizing.

Mutating the imported constant violates immutability/idempotency expectations and can leak state across runs. Clone then override fields.

-function makeNewDemographics() {
-  const demographics = patientShirleyDouglas;
+function makeNewDemographics() {
+  const demographics = { ...patientShirleyDouglas };
   demographics.name = [
     {
       use: NameUseCodes.official,
       given: [faker.person.firstName()],
       family: [faker.person.lastName()],
     },
   ];
   demographics.birthDate = faker.date.birthdate().toISOString().split("T")[0];
   demographics.gender = GenderCodes.M;
   demographics.address = [
     {
       use: AddressUseCodes.home,
       postalCode: faker.location.zipCode(),
       state: faker.location.state(),
     },
   ];
   return demographics;
 }
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 78602cd and cccad59.

📒 Files selected for processing (14)
  • packages/api/src/external/commonwell-v2/api.ts (1 hunks)
  • packages/api/src/shared/config.ts (1 hunks)
  • packages/commonwell-cert-runner/README.md (1 hunks)
  • packages/commonwell-cert-runner/src/env.ts (2 hunks)
  • packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts (7 hunks)
  • packages/commonwell-cert-runner/src/flows/contribution/document-reference.ts (1 hunks)
  • packages/commonwell-cert-runner/src/flows/document-consumption.ts (2 hunks)
  • packages/commonwell-cert-runner/src/flows/document-contribution.ts (6 hunks)
  • packages/commonwell-cert-runner/src/flows/link-management.ts (6 hunks)
  • packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts (1 hunks)
  • packages/commonwell-cert-runner/src/flows/org-management.ts (3 hunks)
  • packages/commonwell-cert-runner/src/index.ts (2 hunks)
  • packages/commonwell-cert-runner/src/payloads.ts (3 hunks)
  • packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursorrules)

**/*.{js,jsx,ts,tsx}: 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 const whenever possible
Use async/await instead of .then()
Naming: classes, enums: PascalCase
Naming: constants, variables, functions: camelCase
Naming: file names: kebab-case
Naming: Don’t use negative names, like notEnabled, prefer isDisabled
If possible, use decomposing objects for function parameters
Prefer Nullish Coalesce (??) than the OR operator (||) when you want 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)
While handling errors, keep the stack trace around: if you create a new Error (e.g., MetriportError), make sure to pass the original error as the new one’s cause so the stack trace is available upstream.
max column length is 100 chars
multi-line comments use /** */
top-level comments go after the import (save pre-import to basic file header, like license)
move literals to constants declared after imports when possible

Files:

  • packages/commonwell-cert-runner/src/flows/document-consumption.ts
  • packages/api/src/external/commonwell-v2/api.ts
  • packages/commonwell-cert-runner/src/flows/contribution/document-reference.ts
  • packages/commonwell-cert-runner/src/index.ts
  • packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts
  • packages/commonwell-cert-runner/src/payloads.ts
  • packages/api/src/shared/config.ts
  • packages/commonwell-cert-runner/src/flows/org-management.ts
  • packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts
  • packages/commonwell-cert-runner/src/env.ts
  • packages/commonwell-cert-runner/src/flows/link-management.ts
  • packages/commonwell-cert-runner/src/flows/document-contribution.ts
  • packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursorrules)

Use types whenever possible

Files:

  • packages/commonwell-cert-runner/src/flows/document-consumption.ts
  • packages/api/src/external/commonwell-v2/api.ts
  • packages/commonwell-cert-runner/src/flows/contribution/document-reference.ts
  • packages/commonwell-cert-runner/src/index.ts
  • packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts
  • packages/commonwell-cert-runner/src/payloads.ts
  • packages/api/src/shared/config.ts
  • packages/commonwell-cert-runner/src/flows/org-management.ts
  • packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts
  • packages/commonwell-cert-runner/src/env.ts
  • packages/commonwell-cert-runner/src/flows/link-management.ts
  • packages/commonwell-cert-runner/src/flows/document-contribution.ts
  • packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts
**/*.ts

⚙️ CodeRabbit Configuration File

**/*.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
  • U...

Files:

  • packages/commonwell-cert-runner/src/flows/document-consumption.ts
  • packages/api/src/external/commonwell-v2/api.ts
  • packages/commonwell-cert-runner/src/flows/contribution/document-reference.ts
  • packages/commonwell-cert-runner/src/index.ts
  • packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts
  • packages/commonwell-cert-runner/src/payloads.ts
  • packages/api/src/shared/config.ts
  • packages/commonwell-cert-runner/src/flows/org-management.ts
  • packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts
  • packages/commonwell-cert-runner/src/env.ts
  • packages/commonwell-cert-runner/src/flows/link-management.ts
  • packages/commonwell-cert-runner/src/flows/document-contribution.ts
  • packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: RamilGaripov
PR: metriport/metriport#4176
File: packages/fhir-converter/src/lib/handlebars-converter/handlebars-helpers.js:296-320
Timestamp: 2025-07-17T21:24:37.077Z
Learning: RamilGaripov prefers to maintain consistency with existing patterns in a file rather than making isolated fixes to coding guideline violations like var vs const declarations, when the pattern is already established throughout the codebase.
📚 Learning: 2025-06-03T21:02:23.374Z
Learnt from: leite08
PR: metriport/metriport#3953
File: packages/core/src/command/consolidated/search/fhir-resource/__tests__/search-consolidated-setup.ts:28-30
Timestamp: 2025-06-03T21:02:23.374Z
Learning: The `makePatient()` function returns `PatientWithId` type which requires the `id` field to be present, ensuring `patient.id` is never undefined.

Applied to files:

  • packages/commonwell-cert-runner/src/flows/document-consumption.ts
  • packages/commonwell-cert-runner/src/flows/link-management.ts
📚 Learning: 2025-07-16T19:02:26.395Z
Learnt from: leite08
PR: metriport/metriport#4095
File: packages/commonwell-cert-runner/src/flows/org-management.ts:79-85
Timestamp: 2025-07-16T19:02:26.395Z
Learning: In packages/commonwell-cert-runner/src/flows/org-management.ts, the silent error handling in the certificate retrieval catch block is intentional to allow the certification flow to continue processing even when certificate operations fail, as this is a testing tool rather than production code.

Applied to files:

  • packages/commonwell-cert-runner/src/index.ts
  • packages/commonwell-cert-runner/src/flows/org-management.ts
  • packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts
📚 Learning: 2025-05-27T15:54:47.774Z
Learnt from: lucasdellabella
PR: metriport/metriport#3866
File: packages/api/src/routes/internal/medical/organization.ts:95-98
Timestamp: 2025-05-27T15:54:47.774Z
Learning: The conversion of the GET `/internal/organization` endpoint from returning a single organization to returning an array of organizations (batch retrieval) in `packages/api/src/routes/internal/medical/organization.ts` was an intentional breaking change planned by the team.

Applied to files:

  • packages/commonwell-cert-runner/src/payloads.ts
  • packages/commonwell-cert-runner/src/flows/org-management.ts
📚 Learning: 2025-05-20T21:26:26.804Z
Learnt from: leite08
PR: metriport/metriport#3814
File: packages/api/src/routes/internal/medical/patient-consolidated.ts:141-174
Timestamp: 2025-05-20T21:26:26.804Z
Learning: The functionality introduced in packages/api/src/routes/internal/medical/patient-consolidated.ts is planned to be refactored in downstream PR #3857, including improvements to error handling and validation.

Applied to files:

  • packages/commonwell-cert-runner/src/flows/link-management.ts
📚 Learning: 2025-03-11T20:42:46.516Z
Learnt from: thomasyopes
PR: metriport/metriport#3427
File: packages/core/src/external/ehr/api/sync-patient.ts:16-55
Timestamp: 2025-03-11T20:42:46.516Z
Learning: In the patient synchronization architecture, the flow follows this pattern: (1) `ehr-sync-patient-cloud.ts` sends messages to an SQS queue, (2) the `ehr-sync-patient` Lambda consumes these messages, and (3) the Lambda uses the `syncPatient` function to make the API calls to process the patient data.

Applied to files:

  • packages/commonwell-cert-runner/src/flows/link-management.ts
🧬 Code Graph Analysis (9)
packages/api/src/external/commonwell-v2/api.ts (1)
packages/shared/src/index.ts (1)
  • MetriportError (44-44)
packages/commonwell-cert-runner/src/index.ts (1)
packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts (1)
  • orgManagementInitiatorOnly (22-97)
packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts (1)
packages/commonwell-cert-runner/src/env.ts (1)
  • existingOrgOid (22-22)
packages/commonwell-cert-runner/src/payloads.ts (1)
packages/commonwell-cert-runner/src/env.ts (1)
  • rootOID (3-3)
packages/commonwell-cert-runner/src/flows/org-management.ts (3)
packages/commonwell-cert-runner/src/env.ts (1)
  • existingOrgOid (22-22)
packages/commonwell-sdk/src/client/commonwell-member.ts (1)
  • getOneOrg (199-215)
packages/commonwell-cert-runner/src/payloads.ts (1)
  • makeOrganization (121-186)
packages/commonwell-cert-runner/src/flows/org-management-initiator-only.ts (4)
packages/commonwell-cert-runner/src/env.ts (4)
  • memberCertificateString (6-6)
  • memberPrivateKeyString (7-7)
  • memberName (5-5)
  • existingInitiatorOnlyOrgOid (23-23)
packages/commonwell-sdk/src/index.ts (1)
  • APIMode (1-1)
packages/commonwell-cert-runner/src/payloads.ts (1)
  • makeOrganization (121-186)
packages/shared/src/index.ts (1)
  • errorToString (46-46)
packages/commonwell-cert-runner/src/env.ts (1)
packages/commonwell-cert-runner/src/util.ts (2)
  • getEnvOrFail (12-16)
  • getEnv (9-11)
packages/commonwell-cert-runner/src/flows/document-contribution.ts (4)
packages/commonwell-cert-runner/src/env.ts (1)
  • contribExistingOrgOid (25-25)
packages/commonwell-cert-runner/src/payloads.ts (1)
  • makePatient (91-117)
packages/commonwell-cert-runner/src/util.ts (1)
  • getMetriportPatientIdOrFail (45-58)
packages/commonwell-sdk/src/common/util.ts (1)
  • encodeToCwPatientId (57-67)
packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts (1)
packages/commonwell-cert-runner/src/flows/contribution/token.ts (1)
  • verifySignature (45-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: check-pr / lint-build-test
🔇 Additional comments (16)
packages/commonwell-cert-runner/src/flows/link-management.ts (1)

8-8: Import additions look good

Importing getMetriportPatientIdOrFail and logError improves safety and centralizes error logging.

packages/api/src/shared/config.ts (1)

240-243: Deprecation annotation added — verified usage locations
I ran the search and located all call sites of Config.getCWMemberOID():

  • packages/api/src/external/commonwell-v2/api.ts: lines 31, 60
  • packages/api/src/external/commonwell-v1/organization.ts: lines 98, 124, 160
  • packages/api/src/external/commonwell-v1/api.ts: line 56

Please plan removal of these calls under ENG-554.

packages/commonwell-cert-runner/src/env.ts (3)

3-3: Confirm expected ROOT_OID format (numeric vs URN) to avoid downstream inconsistencies

makeOrgId now concatenates ROOT_OID directly. If ROOT_OID includes "urn:oid:", org IDs will include the URN; if it doesn’t, they won’t. Different call sites may expect one form or the other. Please confirm which format CommonWell SDK methods expect for:

  • org.organizationId
  • homeCommunityId
  • patient assignAuthority

If mixed inputs are possible, consider normalizing in one place (either always numeric OID or always with "urn:oid:") to prevent subtle bugs.


22-25: LGTM: Optional envs for existing org OIDs look consistent

existingOrgOid, existingInitiatorOnlyOrgOid, and contribExistingOrgOid as optional envs match the described flows and keep creation logic flexible.


27-27: Validate and parse CONTRIB_SERVER_PORT robustly (avoid NaN, set radix)

parseInt without validation can yield NaN at runtime and cause app.listen to fail unclearly. Suggest parsing with radix and validating.

Apply this diff:

-export const contribServerPort = parseInt(getEnvOrFail("CONTRIB_SERVER_PORT"));
+const contribServerPortStr = getEnvOrFail("CONTRIB_SERVER_PORT");
+export const contribServerPort = Number.parseInt(contribServerPortStr, 10);
+if (Number.isNaN(contribServerPort)) {
+  throw new Error(`Invalid CONTRIB_SERVER_PORT: "${contribServerPortStr}" is not a number`);
+}
⛔ Skipped due to learnings
Learnt from: thomasyopes
PR: metriport/metriport#3608
File: packages/lambdas/src/ehr-refresh-resource-diff.ts:0-0
Timestamp: 2025-04-17T21:32:36.505Z
Learning: In this codebase, validating for NaN after parseInt is not necessary due to well-established patterns for handling environment variables.
packages/commonwell-cert-runner/src/payloads.ts (1)

24-25: LGTM: Switching to rootOID import is aligned with env changes

Using rootOID here aligns with the broader migration away from memberOID. Import list looks correct.

packages/commonwell-cert-runner/src/single-commands/init-contrib-server.ts (3)

6-6: LGTM: env import now aligned with OID changes

Switching to existingOrgOid and removing memberOID usage is consistent with the env.ts refactor.


13-19: Fail-fast on missing organizationId is good; verify format matches CommonWell expectations

Throwing when organizationId is absent is correct. Since homeCommunityId (Line 26) is now set to org.organizationId, please verify whether CommonWell expects URN (“urn:oid:...”) or numeric OID here. If the value is numeric and CW expects URN (or vice versa), token flows can fail subtly.


26-27: homeCommunityId switched from member OID to org.organizationId — confirm API contract

This is a behavioral change. Ensure CommonWell.init expects homeCommunityId for the org itself (not the member/root OID). If that’s intended per CW v2, this looks correct.

packages/commonwell-cert-runner/src/flows/contribution/contribution-server.ts (1)

156-161: LGTM: Startup log and server init

Server bootstrap looks fine; consistent “[server]” prefix improves log filtering.

packages/commonwell-cert-runner/src/index.ts (1)

9-9: Initiator-only flow and environment variable verified

Call site and env var usage have been confirmed in the codebase:

  • orgManagementInitiatorOnly is imported and invoked in packages/commonwell-cert-runner/src/index.ts (line 51).
  • CW_INITIATOR_ONLY_ORG_OID is exposed as existingInitiatorOnlyOrgOid in packages/commonwell-cert-runner/src/env.ts (line 23).

Please update the PR description and release notes to reflect that:

  • The initiator-only flow is now invoked by this PR.
  • Consumers must set CW_INITIATOR_ONLY_ORG_OID in their environments for this behavior.
packages/commonwell-cert-runner/src/flows/org-management.ts (4)

41-47: Early return for existing org and explicit post-create orgId check: LGTM.

This short-circuits unnecessary work and adds a defensive guard after org creation.

Also applies to: 57-57


77-85: Silent certificate retrieval failure is acceptable here (test tool context).

Catching and defaulting to [] preserves flow execution. This aligns with prior intentional behavior for this runner.


185-187: Init for existing org switched to OID: LGTM.

Consistent with the env rename and usage elsewhere.


11-18: Approve OID migration: no existingOrgId references remain

No matches for existingOrgId were found—migration to existingOrgOid is consistent across the codebase. Changes are approved. 🚀

packages/commonwell-cert-runner/src/flows/document-contribution.ts (1)

149-166: New explicit CHA 2.4–2.5 steps are clear and consistent.

Good addition of linking and document querying phases with straightforward logging.

Copy link
Member

@leite08 leite08 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to update these on the downstream PR

Part of ENG-200

Signed-off-by: RamilGaripov <ramil@metriport.com>
@RamilGaripov RamilGaripov enabled auto-merge August 21, 2025 16:13
@RamilGaripov RamilGaripov added this pull request to the merge queue Aug 21, 2025
Merged via the queue into develop with commit 72d68f9 Aug 21, 2025
16 checks passed
@RamilGaripov RamilGaripov deleted the eng-200-cert-runner-updated branch August 21, 2025 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants