Skip to content

[ALFMOB-339] Implement Search via BFF#23

Merged
hoangnhatdrk merged 4 commits into
mainfrom
feature/ALFMOB-339-implement-search-bff
Jun 19, 2026
Merged

[ALFMOB-339] Implement Search via BFF#23
hoangnhatdrk merged 4 commits into
mainfrom
feature/ALFMOB-339-implement-search-bff

Conversation

@hoangnhatdrk

Copy link
Copy Markdown
Contributor

ALFMOB-339 — Implement Search via BFF

Migrates Android Search off the legacy autocomplete (SearchSuggestionsQuery) and onto the BFF's searchProducts query, reusing the rewired PLP from ALFMOB-337/338 for results.

What changed

  • Search overlay gutted to a local-only shell. Removed the suggestion autocomplete (keyword/brand chips, product previews), its use case / service / mapper / domain & UI models, the SearchSuggestionsQuery GraphQL op, and the overlay's Loading/Loaded/Error states. Kept the search bar, recent searches (Room), empty state, and submit→PLP.
  • Search results now go through the PLP. Introduced a ProductListQuerySource sealed type (Collection | Search) threaded through the repository → service → paging source → use cases. The repo calls searchProducts(searchTerm, …) in search mode and productList(collectionHandle, …) otherwise — both share the new ProductListResponseFragment, so pagination/sort/cursor plumbing is identical.
  • PLP states implemented. Added a reusable StateMessage design-system component, now driving the search no-results state, a generic empty state, and an error state with a Try again (retry) button.
  • Blank-search guard. Search deeplinks with an empty/blank q now show an error snackbar (DeeplinkResult.ShowError) instead of navigating to an empty PLP; the search term is trimmed before it reaches the BFF/title/recent-searches.

Figma ↔ Jira conflicts (Jira wins — see Docs/ALFMOB-339-search-via-bff-plan.md)

  • Keyword autocomplete (Figma frames 2–3) and "Popular Items" dropped — no BFF suggestion query exists yet (tracked as a follow-up).
  • Filter facets remain BFF-blocked → out of scope (parity with category PLP: sort + pagination only).

Out of scope / follow-ups

  • plp_empty_* and plp_search_empty_query_error copy is placeholder — needs design/content sign-off.
  • Category/brand collection-handle resolution is still the hardcoded "women" placeholder (BFF gap, shared with the PLP work) — search is unaffected since it threads the query string directly.

Testing

  • Unit tests updated/added across data, domain, domain:repository, feature:search, feature:plp (search-source branching, searchProducts mapper/service, no-results gating, deeplink blank-query guard).
  • compileDebugKotlin (incl. app), affected testDebugUnitTest suites, and detekt all green.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 11, 2026 08:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Migrates Search from the legacy autocomplete/suggestions flow to the BFF-backed searchProducts query by routing search results through the existing PLP (paging/sort/cursor), removing the old suggestions stack, and adding shared empty/error UI states plus a blank-search deeplink guard.

Changes:

  • Removed legacy Search suggestions GraphQL op, domain/data plumbing, and Search overlay suggestion states; Search overlay now focuses on recent searches + submit → PLP.
  • Added BFF SearchProductsQuery and a shared ProductListResponseFragment, introducing ProductListQuerySource to switch between collection and search queries while reusing PLP paging.
  • Implemented reusable StateMessage UI for PLP empty/no-results/error states and added deeplink handling for blank search queries via DeeplinkResult.ShowError surfaced as an error snackbar.

Reviewed changes

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

Show a summary per file
File Description
network/src/main/graphql/legacy/search-queries.graphql Removes legacy SearchSuggestionsQuery operation.
network/src/main/graphql/bff/product-listing-queries.graphql Adds SearchProductsQuery and reuses a shared response fragment for PLP/search.
network/src/main/graphql/bff/fragments/ProductListResponseFragment.graphql Introduces a fragment capturing shared paging response shape.
feature/src/main/java/com/mindera/alfie/feature/webview/delegate/WebViewHandlerDelegate.kt Handles/logs new DeeplinkResult.ShowError in webview deeplink flow.
feature/src/main/java/com/mindera/alfie/feature/webview/component/WebViewNavigator.kt Treats ShowError as non-navigable from webview.
feature/search/src/test/java/com/mindera/alfie/feature/search/SearchViewModelTest.kt Updates SearchViewModel tests to match submit-only behavior and blank guard.
feature/search/src/test/java/com/mindera/alfie/feature/search/SearchMockData.kt Removes mock data for deleted suggestions UI/models.
feature/search/src/test/java/com/mindera/alfie/feature/search/factory/SearchUIFactoryTest.kt Removes tests for deleted Search suggestions UI factory.
feature/search/src/main/res/values/strings.xml Removes strings used by the deleted suggestions UI.
feature/search/src/main/java/com/mindera/alfie/feature/search/SearchViewModel.kt Removes suggestion fetching/state; trims term before navigation/saving.
feature/search/src/main/java/com/mindera/alfie/feature/search/SearchOverlay.kt Removes suggestions UI and related state wiring; keeps recent searches + submit.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/SearchUIState.kt Deletes now-unused Search overlay state model.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/SearchUI.kt Deletes now-unused Search suggestions UI model.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/SearchEvent.kt Removes events related to suggestions/autocomplete.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/ProductSuggestionUI.kt Deletes now-unused product suggestion UI model.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/KeywordSuggestionUI.kt Deletes now-unused keyword suggestion UI model.
feature/search/src/main/java/com/mindera/alfie/feature/search/model/BrandSuggestionUI.kt Deletes now-unused brand suggestion UI model.
feature/search/src/main/java/com/mindera/alfie/feature/search/factory/SearchUIFactory.kt Deletes now-unused suggestions UI factory.
feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListViewModelTest.kt Updates PLP tests to validate query-source branching and searchQuery exposure.
feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListPreviewCountTest.kt Updates preview-count tests for new query-source parameter.
feature/plp/src/main/res/values/strings.xml Adds placeholder copy for search blank/no-results/empty/error states.
feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListViewModel.kt Switches to ProductListQuerySource and exposes searchQuery.
feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListTypeMapper.kt Adds mapping from nav type → query source + display title.
feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListScreen.kt Uses StateMessage to render error/empty/no-results states and enables retry.
feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListDeeplinks.kt Trims/validates search deeplink query and emits ShowError when blank.
feature/plp/src/androidTest/java/com/mindera/alfie/feature/plp/ProductListDeeplinksTest.kt Adds instrumentation tests for blank-query error vs navigation.
domain/src/test/java/com/mindera/alfie/domain/usecase/search/GetSearchSuggestionsUseCaseTest.kt Removes tests for deleted suggestions use case.
domain/src/test/java/com/mindera/alfie/domain/usecase/productlist/GetProductListUseCaseTest.kt Updates tests for new query-source parameter.
domain/src/test/java/com/mindera/alfie/domain/usecase/productlist/GetPaginatedProductListUseCaseTest.kt Updates tests for new query-source parameter.
domain/src/main/java/com/mindera/alfie/domain/usecase/search/GetSearchSuggestionsUseCase.kt Deletes suggestions use case.
domain/src/main/java/com/mindera/alfie/domain/usecase/productlist/GetProductListUseCase.kt Replaces collection handle param with query source param.
domain/src/main/java/com/mindera/alfie/domain/usecase/productlist/GetPaginatedProductListUseCase.kt Replaces collection handle param with query source param in paging setup.
domain/repository/src/test/java/com/mindera/alfie/repository/search/model/SearchSuggestionsTest.kt Removes tests for deleted suggestions model.
domain/repository/src/test/java/com/mindera/alfie/repository/productlist/paging/ProductListPagingSourceTest.kt Updates paging source tests for new query-source parameter.
domain/repository/src/main/java/com/mindera/alfie/repository/search/SearchRepository.kt Removes suggestions API from repository interface.
domain/repository/src/main/java/com/mindera/alfie/repository/search/model/SearchSuggestions.kt Deletes suggestions model.
domain/repository/src/main/java/com/mindera/alfie/repository/search/model/SearchSuggestion.kt Deletes suggestions model types.
domain/repository/src/main/java/com/mindera/alfie/repository/productlist/ProductListRepository.kt Replaces collection handle with query source in repository API.
domain/repository/src/main/java/com/mindera/alfie/repository/productlist/paging/ProductListPagingSource.kt Threads query source through paging source.
domain/repository/src/main/java/com/mindera/alfie/repository/productlist/model/ProductListQuerySource.kt Adds sealed type to identify BFF list query source (collection vs search).
designsystem/src/main/java/com/mindera/alfie/designsystem/component/state/StateMessageAction.kt Adds CTA model for state-message action button.
designsystem/src/main/java/com/mindera/alfie/designsystem/component/state/StateMessage.kt Adds reusable centered empty/error/no-results component.
designsystem/src/main/java/com/mindera/alfie/designsystem/component/searchbar/SearchState.kt Removes custom on-term-change listener support.
debug/operational/src/main/java/com/mindera/alfie/debug/operational/view/catalog/screen/SearchPullDownScreen.kt Updates Search overlay usage to new signature.
data/src/test/java/com/mindera/alfie/data/search/service/SearchServiceImplTest.kt Removes tests for deleted legacy suggestions service.
data/src/test/java/com/mindera/alfie/data/search/SearchMockData.kt Removes legacy suggestions mock data.
data/src/test/java/com/mindera/alfie/data/search/repository/SearchRepositoryImplTest.kt Removes suggestions repository tests and dependencies.
data/src/test/java/com/mindera/alfie/data/search/mapper/SearchSuggestionsMapperTest.kt Removes tests for deleted suggestions mapper.
data/src/test/java/com/mindera/alfie/data/productlist/service/ProductListServiceImplTest.kt Adds tests for new BFF searchProducts service call.
data/src/test/java/com/mindera/alfie/data/productlist/repository/ProductListRepositoryImplTest.kt Adds tests for search-vs-collection branching and fragment mapping.
data/src/test/java/com/mindera/alfie/data/productlist/mapper/ProductListMapperTest.kt Updates mapper tests to target shared response fragment.
data/src/main/java/com/mindera/alfie/data/search/service/SearchServiceImpl.kt Deletes legacy search suggestions service implementation.
data/src/main/java/com/mindera/alfie/data/search/service/SearchService.kt Deletes legacy search suggestions service interface.
data/src/main/java/com/mindera/alfie/data/search/repository/SearchRepositoryImpl.kt Removes suggestions dependency/implementation, keeps recent searches persistence.
data/src/main/java/com/mindera/alfie/data/search/mapper/SearchSuggestionMapper.kt Deletes legacy suggestions mapper.
data/src/main/java/com/mindera/alfie/data/search/di/SearchModule.kt Removes binding for deleted search suggestions service.
data/src/main/java/com/mindera/alfie/data/productlist/service/ProductListServiceImpl.kt Adds searchProducts query call via new BFF GraphQL operation.
data/src/main/java/com/mindera/alfie/data/productlist/service/ProductListService.kt Adds searchProducts API to product list service.
data/src/main/java/com/mindera/alfie/data/productlist/repository/ProductListRepositoryImpl.kt Branches between productList and searchProducts based on query source; maps via response fragment.
data/src/main/java/com/mindera/alfie/data/productlist/mapper/ProductListMapper.kt Maps from shared ProductListResponseFragment to domain ProductList.
core/ui/src/main/java/com/mindera/alfie/core/ui/test/TestTagConstants.kt Removes now-unused Search no-results test tag.
core/deeplink/src/main/java/com/mindera/alfie/core/deeplink/DeeplinkResult.kt Adds ShowError(@StringRes messageRes) deeplink result type.
app/src/main/java/com/mindera/alfie/navigation/AppNavigation.kt Surfaces DeeplinkResult.ShowError via error snackbar without navigation.

Copilot AI left a comment

Copy link
Copy Markdown

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 63 out of 63 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

feature/search/src/main/java/com/mindera/alfie/feature/search/SearchViewModel.kt:84

  • navigateToQuery assumes the passed term is already trimmed/non-blank. That’s true for OnSearchAction, but not for other call sites like OnRecentSearchClick (which can surface older persisted recent searches that include whitespace). This can lead to navigating to a search PLP with a blank/space-only query and re-saving that invalid query. Centralize trimming/blank-guard inside navigateToQuery so all entry points behave consistently.

@amccall-mindera amccall-mindera 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.

Approving — all ALFMOB-339 acceptance criteria verified. The suggestion/autocomplete stack is fully removed (SearchSuggestionsQuery, Suggestion domain/UI types, GetSearchSuggestionsUseCase, SearchUIFactory) with zero leftover references, and search is rewired through PLP: SearchViewModel navigates ProductListType.Search(query) into ProductListQuerySource.Search, backed by searchProducts sharing the ProductListResponseFragment so pagination/sort/filters are source-agnostic. Recent searches and the search bar are retained, no-results is search-aware via the new StateMessage, and the search deeplink guards empty queries. Test coverage is solid (repository, service, PLP ViewModel, deeplink) and the prior Copilot KDoc comment is addressed.

@hoangnhatdrk hoangnhatdrk added this pull request to the merge queue Jun 19, 2026
Merged via the queue into main with commit ed0a9b9 Jun 19, 2026
4 checks passed
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