Add network and data layer for category leaderboards#15580
Add network and data layer for category leaderboards#15580JorgeMucientes wants to merge 5 commits intotrunkfrom
Conversation
Add support for fetching top performer categories from the WC leaderboards API. This includes: - LeaderboardCategoryItem parser for category API responses - WCCategoryLeaderboardsMapper for mapping API data to entities - TopPerformerCategoryEntity Room entity and DAO - Database migration to v80 for new entity table - WCLeaderboardsStore methods for category leaderboard operations - ReportsRestClient method for fetching products by category
Add the app data layer for the top categories dashboard card: - StatsRepository methods for fetching/caching top performer categories - GetTopPerformerCategories use case with cache-first data loading - GetProductsByCategory use case for drill-down into category products - TopPerformerCategoryUiModel for the presentation layer - TopCategoriesCustomDateRangeDataStore for custom date range persistence
Add DataStoreType and DataStoreModule entries for top categories custom date range persistence, AnalyticsUpdateDataStore entry for cache tracking, and AppPrefs/AppPrefsWrapper methods for date range selection preference.
Generated by 🚫 Danger |
|
|
Add tests for the GetTopPerformerCategories use case covering: - Fetch success with and without cached data - Fetch failure with cached data - Returning cached data when up-to-date (skip fetch) - Empty cache with no refresh needed - Sorting by quantity desc then total desc Add tests for StatsRepository category methods covering: - fetchTopPerformerCategories success and failure scenarios - Cache freshness check (skip fetch when cache is fresh) - fetchTopPerformerProductsByCategory success and failure scenarios
Update the test to pass the new categoryMapper and topPerformerCategoriesDao parameters added to WCLeaderboardsStore.
There was a problem hiding this comment.
Pull request overview
Adds FluxC + app-layer infrastructure to fetch, persist, and expose “Top Categories” leaderboard data (and product drill-down by category) to support a forthcoming dashboard card.
Changes:
- Introduces Room persistence for top performer categories (entity/DAO + DB v80 migration + DI wiring).
- Adds category leaderboard parsing/mapping and new
WCLeaderboardsStore/ReportsRestClientAPIs for categories and products-by-category. - Adds app-layer repository + use cases + DataStore/AppPrefs wiring and unit tests for cache-first loading.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| libs/fluxc-plugin/src/test/java/org/wordpress/android/fluxc/wc/leaderboards/WCLeaderboardsStoreTest.kt | Updates store construction to include category mapper + DAO dependencies. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCLeaderboardsStore.kt | Adds observe/cache/fetch/invalidate APIs for category leaderboards and fetch products-by-category. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/entity/TopPerformerCategoryEntity.kt | Adds Room entity for cached top performer categories. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/TopPerformerCategoriesDao.kt | Adds DAO queries and update helpers for category leaderboard persistence. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/WCAndroidDatabase.kt | Bumps DB to v80 and registers new entity/DAO + auto-migration. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/reports/ReportsRestClient.kt | Adds report endpoint call to fetch top products filtered by category. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/leaderboards/LeaderboardsApiResponse.kt | Adds categories accessor mapping leaderboard rows to category items. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/leaderboards/LeaderboardCategoryItem.kt | Adds parser/model for “category” leaderboard row arrays. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/model/leaderboards/WCCategoryLeaderboardsMapper.kt | Maps category leaderboard API models into Room entities. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/di/WCDatabaseModule.kt | Provides TopPerformerCategoriesDao from the database. |
| libs/fluxc-plugin/schemas/org.wordpress.android.fluxc.persistence.WCAndroidDatabase/80.json | Adds generated Room schema for DB version 80. |
| WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/domain/GetTopPerformerCategoriesTest.kt | Adds unit tests for cache-first + refresh behavior and sorting. |
| WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/data/StatsRepositoryTests.kt | Adds repository tests for categories fetch/cache behavior and products-by-category fetching. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/domain/GetTopPerformerCategories.kt | Adds use case to load top categories with caching/outdated tracking. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/domain/GetProductsByCategory.kt | Adds use case to fetch products for a selected category (drill-down). |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/data/TopCategoriesCustomDateRangeDataStore.kt | Adds DataStore wrapper for persisting custom date range selection for top categories. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/data/StatsRepository.kt | Adds repository APIs for category leaderboards and products-by-category + expiry logic. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/TopPerformerCategoryUiModel.kt | Adds UI model for rendering top categories items. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/sync/AnalyticsUpdateDataStore.kt | Adds new analytic data key for category leaderboard cache tracking. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/datastore/DataStoreType.kt | Adds new DataStoreType for top performer categories. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/datastore/DataStoreModule.kt | Wires DataStore instance for the top categories custom date range configuration. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/AppPrefsWrapper.kt | Exposes AppPrefs get/set for active top categories tab selection. |
| WooCommerce/src/main/kotlin/com/woocommerce/android/AppPrefs.kt | Adds preference key + accessors for active top categories tab selection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fetchAllLeaderboards( | ||
| site = site, | ||
| startDate = startDate, | ||
| endDate = endDate, | ||
| quantity = quantity, | ||
| addProductsPath = false, | ||
| forceRefresh = true, | ||
| interval = "" | ||
| ) | ||
| .model | ||
| ?.firstOrNull { it.type == CATEGORIES } | ||
| ?.run { |
There was a problem hiding this comment.
fetchAllLeaderboards(...) can return a WooResult with error set and model == null. In that case this implementation falls through to WooResult(WooError(GENERIC_ERROR, UNKNOWN)), discarding the original error details. Consider checking the result from fetchAllLeaderboards first and returning WooResult(it.error) (or equivalent) when it’s an error, so callers get the real failure reason.
| Html.fromHtml(priceAmountHtmlTag, Html.FROM_HTML_MODE_LEGACY) | ||
| .toString() | ||
| .replace(Regex("[0-9.,]"), "") |
There was a problem hiding this comment.
plainTextCurrency calls Html.fromHtml(priceAmountHtmlTag, ...) where priceAmountHtmlTag is nullable. If the API omits the third row or its display, this will crash at runtime. Make this parsing null-safe (e.g., return an empty string when priceAmountHtmlTag is null) to avoid NPEs on unexpected responses.
| Html.fromHtml(priceAmountHtmlTag, Html.FROM_HTML_MODE_LEGACY) | |
| .toString() | |
| .replace(Regex("[0-9.,]"), "") | |
| priceAmountHtmlTag | |
| ?.let { Html.fromHtml(it, Html.FROM_HTML_MODE_LEGACY).toString() } | |
| ?.replace(Regex("[0-9.,]"), "") | |
| ?: "" |
| private val link by lazy { | ||
| Html.fromHtml(itemHtmlTag, Html.FROM_HTML_MODE_LEGACY) | ||
| .run { this as? SpannableStringBuilder } | ||
| ?.spansAsList() | ||
| ?.firstOrNull() | ||
| ?.url | ||
| } |
There was a problem hiding this comment.
link uses Html.fromHtml(itemHtmlTag, ...) with itemHtmlTag being nullable. If the API returns a row with a null display, this will throw at runtime. Consider guarding with itemHtmlTag?.let { Html.fromHtml(it, ...) } (or similar) and returning null when missing.

Description
Adds FluxC and app-layer data infrastructure for fetching top performer categories from the WooCommerce Analytics leaderboards API (
wc-analytics/leaderboards/categories). This lays the groundwork for a new "Top Categories" dashboard card (UI in follow-up PR).FluxC Data Layer
LeaderboardCategoryItemparser for category API responsesWCCategoryLeaderboardsMapperfor mapping API data to Room entitiesTopPerformerCategoryEntityandTopPerformerCategoriesDaofor local persistenceWCLeaderboardsStoremethods for category leaderboard operationsReportsRestClientmethod for fetching products by categoryApp Data Layer
StatsRepositorymethods for fetching and caching top performer categoriesGetTopPerformerCategoriesuse case with cache-first data loading (1-hour expiry)GetProductsByCategoryuse case for drill-down into category productsTopCategoriesCustomDateRangeDataStorefor custom date range persistenceTopPerformerCategoryUiModelfor the presentation layerInfrastructure Wiring
DataStoreTypeandDataStoreModuleentries for custom date range persistenceAnalyticsUpdateDataStoreentry for cache trackingAppPrefs/AppPrefsWrappermethods for date range selection preferenceTest Steps
RELEASE-NOTES.txt
RELEASE-NOTES.txtif so.