Skip to content

Conversation

@joshheald
Copy link
Contributor

@joshheald joshheald commented Sep 5, 2025

Part of: WOOMOB-1252
Closes: WOOMOB-1094
Merge after: #16097

Description

This PR adds a basic catalog sync coordinator. For now, it only supports full syncs.

I've removed the previous code for creating the database – this will happen automatically at the end of a successful sync.

Steps to reproduce

  1. Launch the app logged in to a POS-eligible site – observe that the full sync starts (check the console)
  2. Switch to an ineligible store – observe that sync does not start for that store
  3. Switch to a different eligible store – observe that the full sync starts for that store
  4. Switch back to the first store – observe that the full sync doesn't start.

Testing information

Note that if you switch during a sync, it will carry on, and start syncing the other site if needed.

This doesn't actually cause a problem, it's just a bit wasteful. Only the last one to save will be persisted in the end, because we currently only persist one site at a time. In future, we will change the primary keys to properly support multiple sites, and then they'll be saved as expected.


  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

@joshheald joshheald added this to the 23.3 milestone Sep 5, 2025
@joshheald joshheald added type: task An internally driven task. status: feature-flagged Behind a feature flag. Milestone is not strongly held. feature: POS labels Sep 5, 2025
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Sep 5, 2025

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

App NameWooCommerce iOS Prototype
Build Numberpr16098-ffe3aeb
Version23.2
Bundle IDcom.automattic.alpha.woocommerce
Commitffe3aeb
Installation URL0imi9nah6u9l0
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@joshheald joshheald marked this pull request as ready for review September 5, 2025 16:04
@joshheald joshheald requested a review from jaclync September 5, 2025 16:09
Copy link
Contributor

@jaclync jaclync left a comment

Choose a reason for hiding this comment

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

Works nicely! LGTM 🚀

self.settingsStore = settingsStore ?? SiteSpecificAppSettingsStoreMethods(fileStorage: PListFileStorage())
}

public func performFullSync(for siteID: Int64) async throws -> POSCatalog {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think we could remove the POSCatalog as the return value, and in the protocol. In POSCatalogFullSyncService.startFullSync, the returned catalog is based on the API response, not the final catalog in the database which is the source of truth for POS. As we discovered on the Large fun testing test site, the API response could include duplicate items.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, agreed. I wasn't sure whether it would break anything for you if I did that, but if you're happy I'll take it out.


// Trigger POS catalog sync if tab is visible and feature flag is enabled
if isPOSTabVisible, ServiceLocator.featureFlagService.isFeatureFlagEnabled(.pointOfSaleLocalCatalogi1) {
await triggerPOSCatalogSyncIfNeeded(for: siteID)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: WDYT about moving posCatalogSyncCoordinator initialization here before this line to consolidate the catalog sync code? So that if the updateTabViewControllers call ever gets moved after this code by accident, it won't just silently skip the full sync.

Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Have we decided to trigger the initial full sync if the store is eligible for POS, or if the POS tab is shown (not necessarily eligible)? If the former, we might need to check for eligibility from posEligibilityChecker. Though, it might be simpler to perform a full sync for stores with POS tab visible so that once they fix the ineligibility issue it enters POS right away. I'm not sure if we made a decision cross-platform. In any case, we can make any eligibility updates separately.

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'm not aware of a decision at that level of detail. I can see arguments for either. How quickly after the tab being shown do we usually know if the store's actually eligible?

If those are generally very close together, we can leave the sync until we know for sure. If it takes some time, e.g. they need to open the tab, I think it's better to sync preemptively.

Copy link
Contributor

Choose a reason for hiding this comment

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

How quickly after the tab being shown do we usually know if the store's actually eligible?

If those are generally very close together, we can leave the sync until we know for sure. If it takes some time, e.g. they need to open the tab, I think it's better to sync preemptively.

Currently, we only check the country eligibility & POS remote feature flag on site launch for the POS tab visibility. The rest of the POS eligibility (iOS version, currency, WC plugin version, feature switch in core) are checked when the user taps on the POS tab.

I think we can include the POS tab visibility check in the Local Catalog feature check. Asked a question in p1757465589133769/1757414787.869759-slack-C070SJRA8DP to sync with Android.

Comment on lines 232 to 233


Copy link
Contributor

Choose a reason for hiding this comment

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

super nit: could remove extra empty lines

Comment on lines 147 to 148
var startFullSyncResult: POSCatalog = POSCatalog(products: [], variations: [])
var startFullSyncError: Error?
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: how about a Result<POSCatalog, Error> variable for mocking either success or failure?

}

public final class POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
private let syncService: POSCatalogFullSyncServiceProtocol
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could be named fullSyncService to differentiate from incremental sync when both syncs are supported.

Base automatically changed from task/swift-testing-for-site-settings-method-tests to trunk September 8, 2025 16:28
@joshheald joshheald enabled auto-merge September 9, 2025 13:14
@joshheald joshheald merged commit 5182fcd into trunk Sep 9, 2025
14 checks passed
@joshheald joshheald deleted the woomob-1252-top-level-catalog-sync-coordinator branch September 9, 2025 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: POS status: feature-flagged Behind a feature flag. Milestone is not strongly held. type: task An internally driven task.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants