Skip to content

Commit a3af88b

Browse files
joshhealdclaude
andcommitted
Wire local search strategy to factory and UI
Integrates the local search strategy with the existing fetch strategy factory pattern and wires it up to the POS UI. The factory automatically chooses between local and remote search based on GRDB manager availability. Changes: - Update PointOfSaleItemFetchStrategyFactory: - Add optional grdbManager parameter to initializer - Add localSearchStrategy() factory method - Update searchStrategy() to prefer local when GRDB manager available - Falls back to remote search when local unavailable - Update POSTabCoordinator: - Pass ServiceLocator.grdbManager to factory initialization - Enables local search when local catalog is available - Update analytics infrastructure: - Add trackSearchLocalResultsFetchComplete() to protocol - Update mock analytics tracker for testing Behavior: - When GRDB manager is available → uses local catalog search - When GRDB manager is nil → falls back to existing remote search - No changes to UI layer (transparent integration) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent ffb0fcc commit a3af88b

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

Modules/Sources/Yosemite/PointOfSale/Items/PointOfSaleItemFetchStrategyFactory.swift

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import class Networking.ProductVariationsRemote
44
import class Networking.AlamofireNetwork
55
import struct Combine.AnyPublisher
66
import struct NetworkingCore.JetpackSite
7+
import protocol Storage.GRDBManagerProtocol
78

89
public protocol PointOfSaleItemFetchStrategyFactoryProtocol {
910
func defaultStrategy(analytics: POSItemFetchAnalyticsTracking) -> PointOfSalePurchasableItemFetchStrategy
@@ -16,17 +17,20 @@ public final class PointOfSaleItemFetchStrategyFactory: PointOfSaleItemFetchStra
1617
private let siteID: Int64
1718
private let productsRemote: ProductsRemote
1819
private let variationsRemote: ProductVariationsRemote
20+
private let grdbManager: GRDBManagerProtocol?
1921

2022
public init(siteID: Int64,
2123
credentials: Credentials?,
2224
selectedSite: AnyPublisher<JetpackSite?, Never>? = nil,
23-
appPasswordSupportState: AnyPublisher<Bool, Never>? = nil) {
25+
appPasswordSupportState: AnyPublisher<Bool, Never>? = nil,
26+
grdbManager: GRDBManagerProtocol? = nil) {
2427
self.siteID = siteID
2528
let network = AlamofireNetwork(credentials: credentials,
2629
selectedSite: selectedSite,
2730
appPasswordSupportState: appPasswordSupportState)
2831
self.productsRemote = ProductsRemote(network: network)
2932
self.variationsRemote = ProductVariationsRemote(network: network)
33+
self.grdbManager = grdbManager
3034
}
3135

3236
public func defaultStrategy(analytics: POSItemFetchAnalyticsTracking) -> PointOfSalePurchasableItemFetchStrategy {
@@ -37,11 +41,15 @@ public final class PointOfSaleItemFetchStrategyFactory: PointOfSaleItemFetchStra
3741
}
3842
public func searchStrategy(searchTerm: String,
3943
analytics: POSItemFetchAnalyticsTracking) -> PointOfSalePurchasableItemFetchStrategy {
40-
PointOfSaleSearchPurchasableItemFetchStrategy(siteID: siteID,
41-
searchTerm: searchTerm,
42-
productsRemote: productsRemote,
43-
variationsRemote: variationsRemote,
44-
analytics: analytics)
44+
// Use local search if GRDB manager is available, otherwise fall back to remote search
45+
if let localStrategy = localSearchStrategy(searchTerm: searchTerm, analytics: analytics) {
46+
return localStrategy
47+
}
48+
return PointOfSaleSearchPurchasableItemFetchStrategy(siteID: siteID,
49+
searchTerm: searchTerm,
50+
productsRemote: productsRemote,
51+
variationsRemote: variationsRemote,
52+
analytics: analytics)
4553
}
4654

4755
public func popularStrategy(pageSize: Int = 10) -> PointOfSalePurchasableItemFetchStrategy {
@@ -50,6 +58,26 @@ public final class PointOfSaleItemFetchStrategyFactory: PointOfSaleItemFetchStra
5058
productsRemote: productsRemote,
5159
variationsRemote: variationsRemote)
5260
}
61+
62+
/// Creates a local search strategy using the GRDB catalog
63+
/// - Parameters:
64+
/// - searchTerm: The search term to query
65+
/// - analytics: Analytics tracker
66+
/// - pageSize: Number of items per page (default: 25)
67+
/// - Returns: A local search strategy if GRDB manager is available, otherwise nil
68+
public func localSearchStrategy(searchTerm: String,
69+
analytics: POSItemFetchAnalyticsTracking,
70+
pageSize: Int = 25) -> PointOfSalePurchasableItemFetchStrategy? {
71+
guard let grdbManager else {
72+
return nil
73+
}
74+
return PointOfSaleLocalSearchPurchasableItemFetchStrategy(siteID: siteID,
75+
searchTerm: searchTerm,
76+
grdbManager: grdbManager,
77+
variationsRemote: variationsRemote,
78+
analytics: analytics,
79+
pageSize: pageSize)
80+
}
5381
}
5482

5583
public final class PointOfSaleFixedItemFetchStrategyFactory: PointOfSaleItemFetchStrategyFactoryProtocol {

Modules/Sources/Yosemite/PointOfSale/POSItemFetchAnalyticsTracking.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,10 @@ public protocol POSItemFetchAnalyticsTracking {
1212
/// - millisecondsSinceRequestSent: The time taken to fetch results in milliseconds
1313
/// - totalItems: The total number of items found in the search
1414
func trackSearchRemoteResultsFetchComplete(millisecondsSinceRequestSent: Int, totalItems: Int)
15+
16+
/// Tracks when a local search results fetch completes
17+
/// - Parameters:
18+
/// - millisecondsSinceRequestSent: The time taken to fetch results in milliseconds
19+
/// - totalItems: The total number of items found in the search
20+
func trackSearchLocalResultsFetchComplete(millisecondsSinceRequestSent: Int, totalItems: Int)
1521
}

Modules/Tests/YosemiteTests/Mocks/MockPOSItemFetchAnalyticsTracking.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ final class MockPOSItemFetchAnalyticsTracking: POSItemFetchAnalyticsTracking {
55
private(set) var spyTotalItems: Int?
66
private(set) var spyMillisecondsSinceRequestSent: Int?
77
private(set) var spySearchTotalItems: Int?
8+
private(set) var spyLocalSearchMilliseconds: Int?
9+
private(set) var spyLocalSearchTotalItems: Int?
810

911
func trackItemsFetchComplete(totalItems: Int) {
1012
spyTotalItems = totalItems
@@ -14,4 +16,9 @@ final class MockPOSItemFetchAnalyticsTracking: POSItemFetchAnalyticsTracking {
1416
spyMillisecondsSinceRequestSent = millisecondsSinceRequestSent
1517
spySearchTotalItems = totalItems
1618
}
19+
20+
func trackSearchLocalResultsFetchComplete(millisecondsSinceRequestSent: Int, totalItems: Int) {
21+
spyLocalSearchMilliseconds = millisecondsSinceRequestSent
22+
spyLocalSearchTotalItems = totalItems
23+
}
1724
}

WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ final class POSTabCoordinator {
5151
PointOfSaleItemFetchStrategyFactory(siteID: siteID,
5252
credentials: credentials,
5353
selectedSite: defaultSitePublisher,
54-
appPasswordSupportState: isAppPasswordSupported)
54+
appPasswordSupportState: isAppPasswordSupported,
55+
grdbManager: ServiceLocator.grdbManager)
5556
}()
5657

5758
private lazy var posPopularItemFetchStrategyFactory: PointOfSaleFixedItemFetchStrategyFactory = {

0 commit comments

Comments
 (0)