Skip to content

[SABRA-2456] Add V2 Facets and Searchabilities API Support#237

Open
aandrukhovich wants to merge 13 commits intomasterfrom
SABRA-2456/cio-node
Open

[SABRA-2456] Add V2 Facets and Searchabilities API Support#237
aandrukhovich wants to merge 13 commits intomasterfrom
SABRA-2456/cio-node

Conversation

@aandrukhovich
Copy link

Add V2 Facets and Searchabilities API Support

Summary

This PR adds support for the V2 versions of the /v2/facets and /v2/searchabilities endpoints, running in parallel with the existing V1 implementations.

Changes

New Facets V2 Methods

  • addFacetConfigurationV2 - Create a single facet configuration
  • getFacetConfigurationsV2 - Retrieve all facet configurations with pagination
  • getFacetConfigurationV2 - Get a specific facet by name
  • modifyFacetConfigurationsV2 - Batch partial update facets (PATCH)
  • modifyFacetConfigurationV2 - Partially update a single facet
  • replaceFacetConfigurationV2 - Replace a single facet configuration (PUT)
  • createOrReplaceFacetConfigurationsV2 - Batch create or replace facets (PUT)
  • removeFacetConfigurationV2 - Delete a facet configuration

New Searchabilities V2 Methods

  • retrieveSearchabilitiesV2 - Retrieve searchabilities with filtering/pagination/sorting
  • getSearchabilityV2 - Get a specific searchability by name
  • patchSearchabilitiesV2 - Batch create or update searchabilities
  • patchSearchabilityV2 - Update a single searchability
  • deleteSearchabilitiesV2 - Batch delete searchabilities
  • deleteSearchabilityV2 - Delete a single searchability

New Types (TypeScript)

  • FacetConfigurationV2 - V2 facet model with pathInMetadata field
  • SearchabilityConfigurationV2 - V2 searchability model with new fields (displayable, hidden, createdAt, updatedAt)
  • Request/response types for all V2 operations

V2 API Differences from V1

Facets:

  • Requires pathInMetadata field which specifies where in item metadata the facet data is located
  • Uses /v2/facets endpoint instead of /v1/facets

Searchabilities:

  • Adds displayable and hidden fields
  • Adds createdAt/updatedAt timestamps
  • Simplified query parameter filtering (direct boolean params)
  • Uses /v2/searchabilities endpoint instead of /v1/searchabilities

Test Plan

  • Added catalog-facet-configurations-v2.js with comprehensive test coverage for all facet V2 operations
  • Added catalog-searchabilities-v2.js with comprehensive test coverage for all searchability V2 operations
  • All tests include proper cleanup in after hooks
  • Tests cover success cases, error cases, and network timeout scenarios

Breaking Changes

None. V2 methods are additive and V1 methods remain unchanged.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

Copilot AI review requested due to automatic review settings February 25, 2026 23:41
@constructor-claude-bedrock

This comment has been minimized.

Copy link

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 adds V2 API support for facets and searchabilities endpoints, running in parallel with existing V1 implementations. The changes introduce 14 new methods (8 for facets, 6 for searchabilities) along with corresponding TypeScript type definitions and comprehensive test coverage.

Changes:

  • Added V2 facet configuration methods with support for the new required pathInMetadata field
  • Added V2 searchability methods with new displayable and hidden fields plus timestamp tracking
  • Added comprehensive TypeScript type definitions for V2 request/response models
  • Added full test coverage for all new V2 methods with proper cleanup logic
  • Updated CI/CD workflow to include new test API key environment variable

Reviewed changes

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

Show a summary per file
File Description
src/types/index.d.ts Defines V2 types for facet and searchability configurations and responses
src/types/catalog.d.ts Defines parameter interfaces and method signatures for all V2 catalog operations
src/modules/catalog.js Implements 14 new V2 methods with proper validation, error handling, and 'v2' endpoint routing
spec/src/modules/catalog/catalog-facet-configurations-v2.js Comprehensive test suite for all facet V2 operations including edge cases and timeouts
spec/src/modules/catalog/catalog-searchabilities-v2.js Comprehensive test suite for all searchability V2 operations including edge cases and timeouts
.github/workflows/run-tests.yml Adds TEST_CATALOG_FACETS_V2_API_KEY secret for V2 API testing

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

Comment on lines 4353 to 4355
// Support both camelCase and snake_case for backwards compatibility
const { skip_rebuild, skipRebuild = skip_rebuild } = parameters;
const { name, skip_rebuild: _sr, skipRebuild: _srCamel, section = 'Products', ...rest } = parameters;
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The parameter destructuring here is overly complex and could be simplified for better readability. The dual destructuring (extracting skipRebuild on line 4354, then re-extracting both skip_rebuild and skipRebuild to exclude them on line 4355) is confusing.

Consider simplifying this pattern by explicitly extracting only what's needed for the body:

const { skip_rebuild, skipRebuild = skip_rebuild, name, section = 'Products' } = parameters;
const bodyParams = { 
  fuzzySearchable: parameters.fuzzySearchable,
  exactSearchable: parameters.exactSearchable, 
  displayable: parameters.displayable,
  hidden: parameters.hidden 
};
// Then use toSnakeCaseKeys(bodyParams) in the request body

Or alternatively, filter out the non-body parameters after conversion:

const { skip_rebuild, skipRebuild = skip_rebuild, name, section = 'Products', ...bodyParams } = parameters;

This would make the intent clearer - separating query parameters (skip_rebuild, name, section) from body parameters.

Copilot uses AI. Check for mistakes.
@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock

This comment has been minimized.

@constructor-claude-bedrock
Copy link

Code Review Results

Strengths

The implementation consistently applies camelCase-to-snake_case backwards compatibility across all new V2 methods, and includes comprehensive test coverage with proper cleanup hooks for all new endpoints.

Critical Issues

[File: spec/src/modules/catalog/catalog-searchabilities-v2.js Line: 16] The searchabilities V2 test file uses TEST_CATALOG_FACETS_V2_API_KEY instead of a dedicated key for searchabilities (or the shared TEST_CATALOG_API_KEY). If the V2 facets and V2 searchabilities APIs require separate keys or run on different index setups, this would silently cause test failures. At minimum, use a clearly named env var or document why facets and searchabilities share the same key.

[File: src/modules/catalog.js ~line 3617] In addFacetConfigurationV2, section is destructured out of parameters but rest (spread into the request body via toSnakeCaseKeys(rest)) may still contain both pathInMetadata and path_in_metadata if the caller provides both. The code reads pathInMetadata = parameters.pathInMetadata || parameters.path_in_metadata for validation but sends the raw rest object to the API. If both are provided, both keys end up serialized in the body. This edge case deserves a test and explicit normalization, consistent with how other methods handle it.

Important Issues

[File: src/modules/catalog.js ~line 3770] In replaceFacetConfigurationV2, the request body is built as toSnakeCaseKeys({ name, ...rest }), which includes name in the body even though name is already sent as a URL path parameter. Verify whether the V2 API expects name in the request body for a PUT -- if not, name should be excluded from the body for consistency with how single-resource methods in the codebase typically work.

[File: spec/src/modules/catalog/catalog-facet-configurations-v2.js ~line 100] The test for adding a duplicate facet configuration depends on test execution order -- it assumes facetConfigurations[0] was populated by a prior test in the same suite. If test ordering changes or a prior test is skipped, this will fail with a confusing error. Use a before hook to guarantee the configuration exists, independent of other tests.

[File: spec/src/modules/catalog/catalog-searchabilities-v2.js ~line 247] The getSearchabilityV2 happy-path test hard-codes the name 'keywords' as a known-existing searchability, creating an implicit dependency on the external test environment state. Consider creating the searchability in a before hook (similar to other describe blocks) to make the test self-contained and environment-agnostic.

[File: src/types/index.d.ts ~line 380] SearchabilityConfigurationV2Response marks updated_at as optional but created_at as required. Confirm whether the API always returns created_at for all searchabilities (including pre-existing ones migrated from V1). If created_at can ever be absent, making it required will cause TypeScript errors for callers.

[File: src/types/catalog.d.ts ~line 304] AddFacetConfigurationV2Parameters and ReplaceFacetConfigurationV2Parameters are both aliased directly to FacetConfigurationV2, which requires pathInMetadata: string. However, the runtime implementation also accepts path_in_metadata (snake_case) as a backwards-compatible alias. Callers using the snake_case form will get a TypeScript type error even though the code handles it at runtime. Either update the type to include the snake_case variant or document that only camelCase is type-safe.

Suggestions

[File: src/modules/catalog.js lines ~3590-4540] All 14 new methods follow identical boilerplate: AbortController setup, URL construction, timeout application, fetch call, and response.ok check. Consider whether a private helper (e.g., _makeRequest) could reduce duplication, especially as more V2 endpoints are added.

[File: spec/src/modules/catalog/catalog-facet-configurations-v2.js ~line 22] The createMockFacetConfigurationV2 factory could be moved to a shared test helpers/factories file so it can be reused across test files rather than duplicated, consistent with the project's testing guidelines.

[File: src/types/catalog.d.ts ~line 353] ModifyFacetConfigurationV2Parameters is typed inline as a union type in the class declaration but could be extracted as a named interface for consistency with the other parameter interfaces defined in this file.

[File: spec/src/modules/catalog/catalog-facet-configurations-v2.js ~line 157] There is a backwards-compatibility test for display_name but no equivalent test for path_in_metadata (snake_case), even though the implementation explicitly supports it via parameters.pathInMetadata || parameters.path_in_metadata. A parallel test would improve confidence in the aliasing logic.

Overall Assessment: Needs Work

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