Skip to content

[CDX-387] Support passing seed item ids to recommendations events#163

Merged
HHHindawy merged 8 commits intomasterfrom
cdx-387-android-sdk-add-support-to-pass-seed-item-ids-to-rex-events
Mar 31, 2026
Merged

[CDX-387] Support passing seed item ids to recommendations events#163
HHHindawy merged 8 commits intomasterfrom
cdx-387-android-sdk-add-support-to-pass-seed-item-ids-to-rex-events

Conversation

@HHHindawy
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings March 26, 2026 04:16
constructor-claude-bedrock[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
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 for including seed item IDs in recommendation tracking events so downstream analytics can associate a click/view event with the items that generated the recommendation set.

Changes:

  • Extend recommendation click/view request bodies to include seed_item_ids.
  • Add seedItemIds (list) and convenience seedItemId (single) overloads to recommendation tracking APIs.
  • Add tests validating that seed_item_ids is serialized into recommendation click/view tracking requests.

Reviewed changes

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

File Description
library/src/main/java/io/constructor/core/ConstructorIo.kt Adds new parameters/overloads for recommendation click/view tracking and passes seed IDs into request bodies.
library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultClickRequestBody.kt Adds seed_item_ids field to click tracking request model.
library/src/main/java/io/constructor/data/model/recommendations/RecommendationResultViewRequestBody.kt Adds seed_item_ids field to view tracking request model.
library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt Adds test coverage asserting seed_item_ids is included for single and multiple seeds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2233 to +2234
fun trackRecommendationResultsView(podId: String, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map<String, String>? = null, seedItemIds: List<String>? = null) {
var completable = trackRecommendationResultsViewInternal(podId, null, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags, seedItemIds)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

trackRecommendationResultsView(podId, numResultsViewed, ...) gained a new trailing seedItemIds parameter, which changes the JVM method signature and will break binary compatibility for clients compiled against the prior version. To keep this non-breaking, reintroduce the previous signature as an overload delegating to the new one (with seedItemIds = null), and optionally deprecate it.

Copilot uses AI. Check for mistakes.
Comment on lines +2142 to +2148
/**
* Tracks recommendation result click events with a single seed item ID.
*
* @see trackRecommendationResultClick
*/
fun trackRecommendationResultClick(podId: String, strategyId: String, customerId: String, variationId: String? = null, sectionName: String? = null, resultId: String? = null, numResultsPerPage: Int? = null, resultPage: Int? = null, resultCount: Int? = null, resultPositionOnPage: Int? = null, analyticsTags: Map<String, String>? = null, seedItemId: String) {
trackRecommendationResultClick(podId, strategyId, customerId, variationId, sectionName, resultId, numResultsPerPage, resultPage, resultCount, resultPositionOnPage, analyticsTags, listOf(seedItemId))
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The new single-seed overload trackRecommendationResultClick(..., seedItemId: String) adds KDoc but omits an @param seedItemId tag (most public APIs in this file document parameters explicitly). Add the missing param documentation so generated docs clearly describe how this overload differs from the list-based one.

Copilot uses AI. Check for mistakes.
Comment on lines +2208 to +2215
/**
* Tracks recommendation result view events with a single seed item ID.
*
* @see trackRecommendationResultsView
*/
fun trackRecommendationResultsView(podId: String, itemIds: Array<String>, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map<String, String>? = null, seedItemId: String) {
trackRecommendationResultsView(podId, itemIds, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags, listOf(seedItemId))
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The new single-seed overload trackRecommendationResultsView(..., seedItemId: String) has KDoc but does not document the seedItemId parameter. Add an @param seedItemId entry (and any other notable behavior differences) to keep public API docs consistent and clear.

Copilot uses AI. Check for mistakes.
Comment on lines +2239 to +2246
/**
* Tracks recommendation result view events with a single seed item ID.
*
* @see trackRecommendationResultsView
*/
fun trackRecommendationResultsView(podId: String, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map<String, String>? = null, seedItemId: String) {
trackRecommendationResultsView(podId, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags, listOf(seedItemId))
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The added single-seed overload trackRecommendationResultsView(podId, numResultsViewed, ..., seedItemId: String) is public API but its KDoc omits an @param seedItemId tag. Add the param documentation for consistency with the rest of the tracking APIs and to improve generated docs.

Copilot uses AI. Check for mistakes.
Comment on lines +2136 to +2137
fun trackRecommendationResultClick(podId: String, strategyId: String, customerId: String, variationId: String? = null, sectionName: String? = null, resultId: String? = null, numResultsPerPage: Int? = null, resultPage: Int? = null, resultCount: Int? = null, resultPositionOnPage: Int? = null, analyticsTags: Map<String, String>? = null, seedItemIds: List<String>? = null) {
var completable = trackRecommendationResultClickInternal(podId, strategyId, customerId, variationId, sectionName, resultId, numResultsPerPage, resultPage, resultCount, resultPositionOnPage, analyticsTags, seedItemIds)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Adding seedItemIds as a new parameter to the existing trackRecommendationResultClick function changes the JVM method signature and will break binary compatibility for apps compiled against older versions of this library (NoSuchMethodError at runtime) and source compatibility for Java callers. To avoid a breaking change, keep the old signature as an overload (without seedItemIds) delegating to the new implementation (e.g., passing null), and optionally deprecate the old overload.

Copilot uses AI. Check for mistakes.
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.

I think Copilot has a point here. What do you think about leaving the original function as is and adding an overload?

Comment on lines +2202 to +2203
fun trackRecommendationResultsView(podId: String, itemIds: Array<String>, numResultsViewed: Int, resultPage: Int? = null, resultCount: Int? = null, resultId: String? = null, sectionName: String? = null, url: String = "Not Available", analyticsTags: Map<String, String>? = null, seedItemIds: List<String>? = null) {
var completable = trackRecommendationResultsViewInternal(podId, itemIds, numResultsViewed, resultPage, resultCount, resultId, sectionName, url, analyticsTags, seedItemIds)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

trackRecommendationResultsView(podId, itemIds, ...) gained a new trailing seedItemIds parameter, which changes the JVM method signature and is a binary-breaking change for existing consumers. Consider restoring the previous signature as an overload delegating to this new one (passing null), and optionally deprecate the old overload to guide migration.

Copilot uses AI. Check for mistakes.
constructor-claude-bedrock[bot]

This comment was marked as outdated.

constructor-claude-bedrock[bot]

This comment was marked as outdated.

Comment on lines +2136 to +2137
fun trackRecommendationResultClick(podId: String, strategyId: String, customerId: String, variationId: String? = null, sectionName: String? = null, resultId: String? = null, numResultsPerPage: Int? = null, resultPage: Int? = null, resultCount: Int? = null, resultPositionOnPage: Int? = null, analyticsTags: Map<String, String>? = null, seedItemIds: List<String>? = null) {
var completable = trackRecommendationResultClickInternal(podId, strategyId, customerId, variationId, sectionName, resultId, numResultsPerPage, resultPage, resultCount, resultPositionOnPage, analyticsTags, seedItemIds)
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.

I think Copilot has a point here. What do you think about leaving the original function as is and adding an overload?

constructor-claude-bedrock[bot]

This comment was marked as outdated.

constructor-claude-bedrock[bot]

This comment was marked as outdated.

@HHHindawy HHHindawy requested a review from esezen March 26, 2026 15:08
constructor-claude-bedrock[bot]

This comment was marked as outdated.

Copy link
Copy Markdown

@constructor-claude-bedrock constructor-claude-bedrock bot left a comment

Choose a reason for hiding this comment

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

Code Review

This PR adds seedItemIds support to trackRecommendationResultClick and trackRecommendationResultsView events, correctly propagating the parameter through public/internal API layers and request body models, with good test coverage.

Inline comments: 3 discussions added

Overall Assessment: ⚠️ Needs Work

fun trackRecommendationResultClick(podId: String, strategyId: String, customerId: String, variationId: String? = null, sectionName: String? = null, resultId: String? = null, numResultsPerPage: Int? = null, resultPage: Int? = null, resultCount: Int? = null, resultPositionOnPage: Int? = null, analyticsTags: Map<String, String>? = null) {
var completable = trackRecommendationResultClickInternal(podId, strategyId, customerId, variationId, sectionName, resultId, numResultsPerPage, resultPage, resultCount, resultPositionOnPage, analyticsTags)
fun trackRecommendationResultClick(podId: String, strategyId: String, customerId: String, variationId: String? = null, sectionName: String? = null, resultId: String? = null, numResultsPerPage: Int? = null, resultPage: Int? = null, resultCount: Int? = null, resultPositionOnPage: Int? = null, analyticsTags: Map<String, String>? = null, seedItemIds: List<String>? = null) {
var completable = trackRecommendationResultClickInternal(podId, strategyId, customerId, variationId, sectionName, resultId, numResultsPerPage, resultPage, resultCount, resultPositionOnPage, analyticsTags, seedItemIds)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The completable variable is declared with var but never reassigned — it should be val. This is a pre-existing pattern in the file, but since this PR is touching these lines, it would be a good opportunity to fix it here. Same applies to the two trackRecommendationResultsView overloads below.

// Change:
var completable = trackRecommendationResultClickInternal(...)
// To:
val completable = trackRecommendationResultClickInternal(...)

assertEquals("pdp5", requestBody["pod_id"])
assertEquals("User Featured", requestBody["strategy_id"])
assertEquals("TIT-REP-1997", requestBody["item_id"])
assertEquals("[seed-item-123]", requestBody["seed_item_ids"])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important Issue: The test asserts "[seed-item-123]" (with brackets) as the serialized value of seed_item_ids. This format is the JSON array representation from Moshi's serialization, stripped of quotes by the getRequestBody helper. While this likely works today due to the parser implementation, the assertion is coupling the test to a specific serialization artefact of getRequestBody.

It would be clearer and more robust to verify this field is present and non-null, and separately test the actual JSON body format. At minimum, a comment explaining why the expected value includes brackets would help future readers understand the intent:

// Moshi serializes List<String> as a JSON array; getRequestBody strips quotes
// so "[\"seed-item-123\"]" becomes "[seed-item-123]"
assertEquals("[seed-item-123]", requestBody["seed_item_ids"])

}

@Test
fun trackRecommendationResultClickWithSingleSeedItemId() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The new tests for seedItemIds only exercise the *Internal methods directly. There are no tests calling the public trackRecommendationResultClick or trackRecommendationResultsView overloads (with itemIds: Array<String> and without) with seedItemIds populated. Since the public methods simply delegate to the internal ones the risk is low, but adding at least one smoke-test for a public overload with seedItemIds would make the test suite consistent with how other parameters are tested in this file.

@HHHindawy HHHindawy merged commit b730936 into master Mar 31, 2026
1 check passed
@HHHindawy HHHindawy deleted the cdx-387-android-sdk-add-support-to-pass-seed-item-ids-to-rex-events branch March 31, 2026 20:21
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.

3 participants