Skip to content

Stratconn 6646/other trait groups support#3668

Draft
monutwilio wants to merge 6 commits intomainfrom
STRATCONN-6646/other-trait-groups-support
Draft

Stratconn 6646/other trait groups support#3668
monutwilio wants to merge 6 commits intomainfrom
STRATCONN-6646/other-trait-groups-support

Conversation

@monutwilio
Copy link
Contributor

A summary of your pull request, including the what change you're making and why.

Testing

Include any additional information about the testing you have completed to
ensure your changes behave as expected. For a speedy review, please check
any of the tasks you completed below during your testing.

  • Added unit tests for new functionality
  • Tested end-to-end using the local server
  • [If destination is already live] Tested for backward compatibility of destination. Note: New required fields are a breaking change.
  • [Segmenters] Tested in the staging environment
  • [Segmenters] [If applicable for this change] Tested for regression with Hadron.

Security Review

Please ensure sensitive data is properly protected in your integration.

  • Reviewed all field definitions for sensitive data (API keys, tokens, passwords, client secrets) and confirmed they use type: 'password'

New Destination Checklist

  • Extracted all action API versions to verioning-info.ts file. example

@github-actions
Copy link
Contributor

New required fields detected

Warning

Your PR adds new required fields to an existing destination. Adding new required settings/mappings for a destination already in production requires updating existing customer destination configuration. Ignore this warning if this PR is for a new destination with no active customers in production.

The following required fields were added in this PR:

  • Destination: Memora Internal, Action Field(s):profile_traits
  • Destination: Memora, Action Field(s):profile_traits

Add these new fields as optional instead and assume default values in perform or performBatch block.

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 79.31034% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.75%. Comparing base (b8ed678) to head (797000f).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
...ons/src/destinations/memora/upsertProfile/index.ts 79.31% 2 Missing and 4 partials ⚠️

❌ Your patch check has failed because the patch coverage (79.31%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3668      +/-   ##
==========================================
+ Coverage   80.59%   80.75%   +0.15%     
==========================================
  Files        1320     1321       +1     
  Lines       24439    24535      +96     
  Branches     4995     5054      +59     
==========================================
+ Hits        19697    19813     +116     
+ Misses       3834     3797      -37     
- Partials      908      925      +17     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Memora upsertProfile action to support traits from multiple Memora trait groups (not just the Contact trait group) by switching the mapped trait key format to TraitGroupName.$.traitName and updating dynamic trait loading accordingly.

Changes:

  • Renames the mapped trait field from contact_traits to profile_traits and updates trait parsing to build per-trait-group payloads.
  • Updates the dynamic field loader to fetch trait definitions across all trait groups and present them as selectable keys.
  • Adjusts tests/types and updates destination snapshots to reflect the new trait behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/memora/upsertProfile/index.ts Renames traits field, parses TraitGroupName.$.traitName, and updates dynamic trait fetching to list all trait groups.
packages/destination-actions/src/destinations/memora/upsertProfile/generated-types.ts Updates generated payload typings/docstrings to profile_traits and new key format guidance.
packages/destination-actions/src/destinations/memora/upsertProfile/tests/index.test.ts Migrates tests to profile_traits keys and adds coverage for non-Contact trait groups.
packages/destination-actions/src/destinations/memora/tests/snapshots/snapshot.test.ts.snap Updates request-body snapshots to match the new trait-building behavior.
packages/destination-actions/src/destinations/memora-internal/upsertProfile.types.ts Updates internal payload type to profile_traits and new key format guidance.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Memora upsertProfile action to support traits from all Memora trait groups (not just Contact) by introducing a TraitGroupName.$.traitName key format and fetching dynamic trait keys across groups from the Control Plane API.

Changes:

  • Renamed contact_traitsprofile_traits and updated trait payload construction to split traits into multiple trait groups.
  • Updated dynamic field loading to fetch trait definitions for all trait groups and present them as TraitGroupName.$.traitName choices.
  • Updated unit tests, generated payload types, and destination snapshots to reflect the new profile_traits structure.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/memora/upsertProfile/index.ts Implements profile_traits, parses trait-group-qualified keys, and fetches dynamic trait keys across all trait groups.
packages/destination-actions/src/destinations/memora/upsertProfile/generated-types.ts Updates generated payload typing/docs to profile_traits.
packages/destination-actions/src/destinations/memora/upsertProfile/tests/index.test.ts Updates mappings and adds coverage for multiple trait groups.
packages/destination-actions/src/destinations/memora/tests/snapshots/snapshot.test.ts.snap Updates snapshot output for the revised payload structure.
packages/destination-actions/src/destinations/memora-internal/upsertProfile.types.ts Updates internal generated payload typing/docs to profile_traits.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support in the Memora upsertProfile action for sending traits across multiple Memora trait groups (instead of only the Contact trait group) by adopting a TraitGroupName.$.traitName key format and updating dynamic field loading accordingly.

Changes:

  • Renames contact_traitsprofile_traits and updates the action to parse TraitGroupName.$.traitName keys into grouped traits for the Memora API payload.
  • Updates dynamic field loading to fetch traits from all trait groups (Control Plane list endpoint) rather than only the Contact trait group.
  • Updates unit tests and destination snapshots to use the new key format and validate multi–trait group behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/memora/upsertProfile/index.ts Renames the field and builds trait groups from profile_traits; updates dynamic field fetch to list all trait groups.
packages/destination-actions/src/destinations/memora/upsertProfile/generated-types.ts Regenerates payload type to reflect profile_traits and updated description.
packages/destination-actions/src/destinations/memora/upsertProfile/tests/index.test.ts Updates mappings to profile_traits and adds test coverage for non-Contact trait groups.
packages/destination-actions/src/destinations/memora/tests/snapshot.test.ts Updates snapshots/mappings to the new profile_traits key format.
packages/destination-actions/src/destinations/memora-internal/upsertProfile.types.ts Regenerates internal payload type to reflect profile_traits.
Comments suppressed due to low confidence (1)

packages/destination-actions/src/destinations/memora/upsertProfile/index.ts:132

  • upsertProfiles validates hasTraits by checking for any non-null entry in payload.profile_traits, but buildTraitGroups later ignores entries that don’t match the required TraitGroupName.$.traitName key format. This can accept payloads that “have traits” yet send an empty traits object (or only identifiers), causing silent data loss and/or downstream API errors—especially since the dynamic-field error path explicitly says users can “manually enter field names.” Consider validating that at least one profile_traits key matches the expected pattern (or coercing unqualified keys into the Contact trait group) and throwing a clear PayloadValidationError when none do.
  payloads.forEach((payload, index) => {
    // Validate that profile has at least one identifier AND at least one trait
    const identifiers = payload.contact_identifiers || {}
    const hasIdentifier = !!(identifiers.email || identifiers.phone)

    const traits = (
      payload.profile_traits && typeof payload.profile_traits === 'object' ? payload.profile_traits : {}
    ) as Record<string, unknown>
    const hasTraits = Object.keys(traits).some((key) => traits[key] !== undefined && traits[key] !== null)

    if (!hasIdentifier || !hasTraits) {
      invalidIndices.push(index)
      return
    }

    // Build trait groups for valid profile
    const traitGroups = buildTraitGroups(payload)
    validProfiles.push({ traits: traitGroups })
    validIndices.push(index)
  })

You can also share your feedback on Copilot code review. Take the survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants