Skip to content

Comments

Migrate SitePluginModel to Room#15098

Merged
wzieba merged 11 commits intotrunkfrom
migrate_site_plugin_model
Dec 23, 2025
Merged

Migrate SitePluginModel to Room#15098
wzieba merged 11 commits intotrunkfrom
migrate_site_plugin_model

Conversation

@wzieba
Copy link
Contributor

@wzieba wzieba commented Dec 12, 2025

Closes: AINFRA-547: Migrate SitePluginModel

Description

This PR migrates SitePluginModel from WellSql to Room.

Test Steps

Plugins list

  1. Go to settings > Plugins > Installed Plugins - verify all plugins are listed like before

Plugin installation

  1. You'll likely need a new site: I've used Jurrasic
  2. Go to settings
  3. Tap on Install Jetpack
  4. Log in with a WordPress account ⚠️ BUT do not use A8c account - it won't work with it
  5. Make sure that Jetpack installation is smooth and Jetpack was installed

Images/gif

Screenshot 2025-12-19 at 15 51 22
  • I have considered if this change warrants release notes and have added them to RELEASE-NOTES.txt if necessary. Use the "[Internal]" label for non-user-facing changes.

@dangermattic
Copy link
Collaborator

dangermattic commented Dec 12, 2025

1 Warning
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 15, 2025

📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
App NameWooCommerce-Wear Android
Platform⌚️ Wear OS
FlavorJalapeno
Build TypeDebug
Commit6a9569d
Direct Downloadwoocommerce-wear-prototype-build-pr15098-6a9569d.apk

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 15, 2025

📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.

App NameWooCommerce Android
Platform📱 Mobile
FlavorJalapeno
Build TypeDebug
Commit6a9569d
Direct Downloadwoocommerce-prototype-build-pr15098-6a9569d.apk

@wzieba wzieba force-pushed the migrate_site_plugin_model branch 14 times, most recently from 03dd081 to 14e6630 Compare December 19, 2025 15:06
Comment on lines +182 to +189
return runBlocking {
val allPlugins = sitePluginDao.getActiveSitePlugins(site.localId())
val extractedRequestedPluginName = plugin.pluginName.substringAfterLast('/')
allPlugins.firstOrNull { sitePlugin ->
val extractedPluginName = sitePlugin.name.substringAfterLast('/')
extractedPluginName == extractedRequestedPluginName
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wzieba wzieba force-pushed the migrate_site_plugin_model branch 2 times, most recently from 2b12dd5 to 447ddb7 Compare December 19, 2025 15:30
@wzieba wzieba force-pushed the migrate_site_plugin_model branch from 447ddb7 to c39c421 Compare December 19, 2025 15:42
@wzieba wzieba added the type: technical debt Represents or solves tech debt of the project. label Dec 19, 2025
@wzieba wzieba added this to the 23.9 milestone Dec 19, 2025
@wzieba wzieba requested a review from samiuelson December 19, 2025 15:56
@wzieba wzieba marked this pull request as ready for review December 19, 2025 15:57
@wzieba wzieba removed the request for review from samiuelson December 19, 2025 16:01
Copy link
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

This PR migrates the SitePluginModel from WellSql to Room database, simplifying the data model and modernizing the persistence layer. The migration removes several fields that were not actively used (displayName, pluginUrl, description, authorUrl, settingsUrl, isAutoUpdateEnabled) and introduces a new Room entity with a streamlined schema.

Key Changes

  • Replaced WellSql-based PluginSqlUtils and PluginSqlUtilsWrapper with Room SitePluginDao
  • Converted SitePluginModel from a Java WellSql entity to a Kotlin Room entity with composite primary key (siteId, slug)
  • Updated all stores and clients to use the new DAO methods (suspend functions and blocking interop methods)

Reviewed changes

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

Show a summary per file
File Description
libs/fluxc/src/main/java/org/wordpress/android/fluxc/model/plugin/SitePluginModel.kt New Room entity replacing the Java WellSql model, with simplified schema containing only essential fields
libs/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/SitePluginDao.kt New DAO with suspend functions for plugin CRUD operations and deprecated blocking methods for Java interop
libs/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt Added migration to drop the old SitePluginModel table from WellSql
libs/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WPAndroidDatabase.kt Updated Room database version to 33 and registered SitePluginModel entity
libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/PluginStore.java Replaced SQL utils with DAO calls and added null checks for plugin upserts
libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/PluginCoroutineStore.kt Updated to use SitePluginDao with suspend functions
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WooCommerceStore.kt Replaced SQL utils with DAO and added runBlocking wrappers for non-suspend methods
libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/plugin/PluginRestClient.java Simplified response mapping to match new model structure
libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/plugin/PluginResponseModel.kt Updated domain model conversion to use new constructor-based approach
libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/network/rest/wpcom/wc/system/WCSystemPluginResponse.kt Updated system plugin mapping to new SitePluginModel structure
libs/fluxc/src/testFixtures/kotlin/org/wordpress/android/fluxc/wp/site/SitePluginFixtures.kt Added test fixture factory for creating test plugins
libs/fluxc-tests/src/test/java/org/wordpress/android/fluxc/plugin/SitePluginDaoTest.kt New comprehensive DAO tests replacing old SQL utils tests
libs/fluxc-tests/src/test/java/org/wordpress/android/fluxc/store/PluginCoroutineStoreTest.kt Updated tests to use new model and DAO mocks
WooCommerce/src/test/kotlin/com/woocommerce/android/ui/subscriptions/IsEligibleForSubscriptionsTest.kt Updated to use test fixtures instead of creating plugins manually
WooCommerce/src/main/kotlin/com/woocommerce/android/ui/prefs/plugins/PluginsViewModel.kt Minor update to clarify filter lambda parameter type

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

import org.wordpress.android.fluxc.model.plugin.SitePluginModel

@Dao
abstract class SitePluginDao {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The DAO query is selecting from table "SitePluginEntity" but the entity annotation specifies tableName as "SitePluginEntity". While this is consistent, it might cause confusion since the old WellSql table was named "SitePluginModel". Consider adding a comment in the migration or documentation explaining the table name change from "SitePluginModel" to "SitePluginEntity" to help with debugging and future reference.

Suggested change
abstract class SitePluginDao {
abstract class SitePluginDao {
// NOTE: The Room table "SitePluginEntity" replaces the legacy WellSql table "SitePluginModel".
// This rename happened during the migration from WellSql to Room; keep this in mind when
// debugging older migrations, logs, or database contents that still reference "SitePluginModel".

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's by design and consistent with already more than 30 migrations 👍. I don't see that this comment will help to navigate.


@Entity(
tableName = "SitePluginEntity",
primaryKeys = ["siteId", "slug"]
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The entity uses a composite primary key of (siteId, slug), but the slug field can potentially be an empty string based on the API response (as seen in the Hello Dolly plugin example where textdomain is empty). This could cause issues if multiple plugins with empty slugs are inserted for the same site, resulting in primary key conflicts.

Consider adding validation or handling for empty slugs, or using a different primary key strategy (e.g., using name instead of slug, or generating a unique identifier).

Suggested change
primaryKeys = ["siteId", "slug"]
primaryKeys = ["siteId", "name"]

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added name to the key in 654bef2 - just in case, as it's true that we should be very cautious with API responses 👍

siteId: Int = 1,
name: String = "",
version: String = "1.0.0",
slug: String = name.lowercase().replace(" ", "-"),
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The default slug generation using name.lowercase().replace(" ", "-") could produce an empty string if the name parameter is empty (which it is by default). This would cause primary key issues since slug is part of the composite primary key. Consider either:

  1. Providing a non-empty default for name
  2. Adding validation to ensure slug is never empty
  3. Using a different default slug generation that guarantees a non-empty value (e.g., "test-plugin-${random()}")

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is testFixtures directory, not a production code. It's okay to make fake assumptions here.

Copy link
Contributor

@samiuelson samiuelson left a comment

Choose a reason for hiding this comment

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

The PR tests good 👍 I left a couple of unresolved comments from Copilot to verify.

It's probably possible that `slug` could be empty. For such cases, `name` should be also taken into account for primary key. If both `name` and `slug` would be empty - then we can assume something is really wrong and not a valid state
`SitePluginModel` is now a data class, so mocking it causes lint error
@wzieba
Copy link
Contributor Author

wzieba commented Dec 23, 2025

Thank you @samiuelson for review! I checked the opened comments, replied to them and added one fix in 654bef2 with explanation.

The primary key change was introduced in
654bef2. I assume here that both name and slug of plugin don't change
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 34.61538% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 38.65%. Comparing base (98fa016) to head (6a9569d).
⚠️ Report is 18 commits behind head on trunk.

Files with missing lines Patch % Lines
.../wordpress/android/fluxc/store/WooCommerceStore.kt 0.00% 13 Missing ⚠️
...ork/rest/wpcom/wc/system/WCSystemPluginResponse.kt 0.00% 7 Missing ⚠️
...rdpress/android/fluxc/persistence/SitePluginDao.kt 0.00% 4 Missing ⚠️
...rdpress/android/fluxc/persistence/WellSqlConfig.kt 0.00% 4 Missing ⚠️
...dpress/android/fluxc/store/PluginCoroutineStore.kt 40.00% 1 Missing and 2 partials ⚠️
...c/network/rest/wpapi/plugin/PluginResponseModel.kt 71.42% 0 Missing and 2 partials ⚠️
...merce/android/ui/prefs/plugins/PluginsViewModel.kt 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##              trunk   #15098      +/-   ##
============================================
+ Coverage     38.63%   38.65%   +0.01%     
  Complexity    10448    10448              
============================================
  Files          2178     2178              
  Lines        123901   123849      -52     
  Branches      17093    17097       +4     
============================================
  Hits          47875    47875              
+ Misses        71206    71151      -55     
- Partials       4820     4823       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wzieba wzieba merged commit 4cfbab7 into trunk Dec 23, 2025
19 checks passed
@wzieba wzieba deleted the migrate_site_plugin_model branch December 23, 2025 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: technical debt Represents or solves tech debt of the project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants