Skip to content

STRATCONN-6824 [Braze] cart_updated ecommerce events + batch index fix - #3931

Open
joe-ayoub-segment wants to merge 8 commits into
mainfrom
STRATCONN-6824-braze-ecommerce-cart-updated
Open

STRATCONN-6824 [Braze] cart_updated ecommerce events + batch index fix#3931
joe-ayoub-segment wants to merge 8 commits into
mainfrom
STRATCONN-6824-braze-ecommerce-cart-updated

Conversation

@joe-ayoub-segment

Copy link
Copy Markdown
Contributor

Combines two pieces of Braze ecommerce work into a single PR (supersedes #3804 and #3929):

STRATCONN-6824 — add/remove from cart ecommerce events

  • Adds support for Braze's ecommerce.cart_updated event, with an action field (add / remove / replace).
  • Adds subtotal_value, tax, shipping to cart_updated, checkout_started, order_placed and order_cancelled.
  • Adds catalog_type (price_drop / back_in_stock) to the single-product Product Viewed event.
  • cart_id is conditionally required for cart_updated.
  • New presets Product Added (beta) and Product Removed (beta) map Segment's Product Added / Product Removed events to cart_updated with action: 'add' / 'remove', and are excluded from the Track Calls preset.

STRATCONN-6937 — batch multistatus index fix + sent/body population

  • send() now attributes Braze per-item errors on the sent-array index (payload.index) rather than the original batch index, skips payloads filtered out by validate(), and reads response.data?.errors null-safely.
  • Per-item MultiStatusResponse sent/body are populated per the repo convention: sent = the transformed event actually sent (omitted when nothing was sent), body = { success: true } on 2xx and the Braze error.type on a per-item error.

Testing

  • Reconciled the multistatus unit tests and added regression tests for filtered-index error attribution and a fully-successful batch.
  • All Braze ecommerce unit tests pass (yarn cloud test --testPathPattern="braze/(ecommerce|ecommerceSingleProduct)"), plus the destination-level preset test.
  • Verified end-to-end against a live Braze workspace using the e2e test runner (fixtures kept on the e2e branch, not included here).

🤖 Generated with Claude Code

joe-ayoub-segment and others added 7 commits May 21, 2026 10:36
Combines the add/remove-from-cart ecommerce work with the batch
multistatus index fix (STRATCONN-6937):
- Add "Product Added"/"Product Removed" presets mapping Segment's
  Product Added/Removed to ecommerce.cart_updated with action add/remove,
  and exclude them from the Track Calls preset
- send(): attribute Braze errors on the sent-array index (payload.index),
  skip payloads filtered by validate(), null-safe errors lookup
- per-item MultiStatus sent/body: sent = transformed event when actually
  sent, body = { success: true } on 2xx / error.type on Braze error,
  omit both when nothing was sent
- reconcile multistatus unit tests + add regression tests for
  filtered-index attribution and a fully-successful batch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@joe-ayoub-segment
joe-ayoub-segment requested a review from a team as a code owner August 8, 2026 09:15
Copilot AI lite review requested due to automatic review settings August 8, 2026 09:15
@github-actions
github-actions Bot requested review from arnav777dev and nk1107 August 8, 2026 09:15
@joe-ayoub-segment joe-ayoub-segment self-assigned this Aug 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR expands Braze ecommerce support by adding ecommerce.cart_updated (including add/remove presets) and enhancing batch MultiStatus handling to attribute per-item errors to the sent payload index while populating sent/body consistently.

Changes:

  • Add ecommerce.cart_updated support (including action) plus subtotal_value, tax, shipping across multiple ecommerce events.
  • Add catalog_type support for single-product Product Viewed events (mapped to Braze properties.type).
  • Fix batch MultiStatus indexing and standardize sent/body population for successes and per-item errors.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/braze/index.ts Updates presets and excludes Product Added/Removed from the generic Track Calls preset.
packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/index.ts Exposes catalog_type in the single-product action fields.
packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/generated-types.ts Adds typings/docs for catalog_type and new ecommerce fields in generated payload types.
packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/tests/index.test.ts Adds regression coverage for catalog_type and reformats existing assertions.
packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/tests/snapshots/snapshot.test.ts.snap Updates snapshots to reflect type/catalog trigger output.
packages/destination-actions/src/destinations/braze/ecommerce/types.ts Enables Cart Updated event typing and adds new numeric fields + Product Viewed type.
packages/destination-actions/src/destinations/braze/ecommerce/generated-types.ts Adds action, subtotal_value, tax, shipping to generated payload types.
packages/destination-actions/src/destinations/braze/ecommerce/functions.ts Implements cart_updated payload shaping and batch MultiStatus index attribution + sent/body conventions.
packages/destination-actions/src/destinations/braze/ecommerce/fields.ts Adds Cart Updated to choices, makes cart_id required for cart_updated, adds new fields and catalog_type.
packages/destination-actions/src/destinations/braze/ecommerce/constants.ts Enables the CART_UPDATED constant.
packages/destination-actions/src/destinations/braze/ecommerce/tests/index.test.ts Adds cart_updated tests and batch indexing regressions; updates MultiStatus expectations.
packages/destination-actions/src/destinations/braze/ecommerce/tests/snapshots/snapshot.test.ts.snap Updates snapshots to reflect new fields and generated event selection.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +55 to +58
/**
* The cart action that was performed (add, remove, or replace).
*/
action?: string

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This file is auto-generated from the action field definitions (// Generated file. DO NOT MODIFY IT BY HAND.). The type generator emits string for any field with choices — no generated-types.ts in this repo uses a string-literal union for a choice field. The runtime constraint is already enforced by the field's choices (validated by the framework), and the internal CartUpdatedEvent type in types.ts already narrows action to 'add' | 'remove' | 'replace'. Closing as not actionable.

Comment on lines +104 to +107
/**
* Required to use Braze catalog trigger features. Accepted values: price_drop, back_in_stock.
*/
catalog_type?: string[]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as the action field: this is an auto-generated file (// Generated file. DO NOT MODIFY IT BY HAND.). The type generator emits string[] for a multiple field with choices and cannot produce a literal-union array — no generated-types.ts in the repo does. The price_drop/back_in_stock contract is enforced at runtime by the field's choices. Closing as not actionable.

Comment on lines +95 to +97
subtotal_value?: number
tax?: number
shipping?: number

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

eslint/prettier pass clean on this file (the repo's config does not flag trailing whitespace here, and the same style is already present elsewhere in the file). No CI impact — closing as not actionable.

})

const errors = Array.isArray(response.data.errors) ? response.data.errors : []
const errors = Array.isArray(response.data?.errors) ? response.data.errors : []

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The access is guarded by the Array.isArray(response.data?.errors) check immediately above, so it is runtime-safe and TypeScript narrows correctly here. Leaving as-is for now — closing as not actionable.

…ecommerce-cart-updated

# Conflicts:
#	packages/destination-actions/src/destinations/braze/ecommerce/__tests__/index.test.ts
#	packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/__tests__/index.test.ts
Copilot AI review requested due to automatic review settings August 8, 2026 13:55
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
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: Braze Cloud Mode (Actions), Action Field(s):cart_id
  • Destination: Braze Cloud Mode (Actions), Action Field(s):cart_id

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Suppressed comments (3)

packages/destination-actions/src/destinations/braze/ecommerceSingleProduct/generated-types.ts:107

  • catalog_type is documented as having accepted values (price_drop, back_in_stock), but the generated type allows any string[]. If this file is meant to be authoritative for consumers, consider narrowing this to a string-literal union array (e.g., ('price_drop' | 'back_in_stock')[]) to prevent invalid values from compiling and to improve editor autocomplete.
  catalog_type?: string[]

packages/destination-actions/src/destinations/braze/ecommerce/generated-types.ts:58

  • action is constrained by the field choices (add / remove / replace) but is typed as a free-form string. Aligning the type with the actual allowed values (string-literal union) will prevent invalid payloads from type-checking and reduce the need for casts downstream.
  action?: string

packages/destination-actions/src/destinations/braze/ecommerce/fields.ts:661

  • The input is named catalog_type but defaults from $.properties.type, and later gets emitted to Braze as properties.type. This overloads a very generic Segment property name (type) and can easily collide with an existing properties.type meaning (e.g., product type/category). Consider changing the default path to something more explicit (e.g., $.properties.catalog_type) while still emitting type to Braze, so existing Segment events with properties.type don’t get unintentionally reinterpreted as a Braze catalog trigger.
const catalog_type: InputField = {
    label: 'Catalog Trigger Type',
    description: 'Required to use Braze catalog trigger features. Accepted values: price_drop, back_in_stock.',
    type: 'string',
    multiple: true,
    choices: [
        { label: 'Price Drop', value: 'price_drop' },
        { label: 'Back In Stock', value: 'back_in_stock' }
    ],
    default: { '@path': '$.properties.type' },

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.

2 participants