feat(llc, core, persistence): Add support for PredefinedFilters on QueryChannels#2709
feat(llc, core, persistence): Add support for PredefinedFilters on QueryChannels#2709VelikovPetar wants to merge 10 commits into
PredefinedFilters on QueryChannels#2709Conversation
… dynamic> to Filter.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| /// Yields the offline-cached result first (when available), followed by | ||
| /// the online result. Concurrent identical online queries are coalesced | ||
| /// via [_queryChannelsCache]. | ||
| Stream<QueryChannelsResult> queryChannelsWithResult({ |
There was a problem hiding this comment.
I wasn't sure about the naming here, I tried to make it as explicit as possible. (it wasn't really possible to use the existing queryChannels without a breaking change, as we must change the return type).
| /// Carries the live [Channel] instances matching the query alongside the | ||
| /// server-resolved [PredefinedFilter] spec (when one is associated with the | ||
| /// query). | ||
| class QueryChannelsResult { |
There was a problem hiding this comment.
I introduced this new model to serve as a container for the result of the StreamChatClient.queryChannelsWithResult.
| Future<List<Channel>> queryChannelsOnline({ | ||
| Filter? filter, | ||
| SortOrder<ChannelState>? sort, | ||
| String? predefinedFilter, |
There was a problem hiding this comment.
Note: At the moment I didn't expose public queryChannelsWithResultOnline/queryChannelsWithResultOffline -> only the new queryChannelsWithResults is public. I didn't want to pollute the public API, with methods which most likely will not be used. Let me know if you think we should expose them as well.
| // passed options | ||
| if (sort != null) 'sort': sort, | ||
| if (filter != null) 'filter_conditions': filter, | ||
| if (predefinedFilter != null) 'predefined_filter': predefinedFilter, |
There was a problem hiding this comment.
I didn't add any guards preventing the users to send both predefined_filter and filter/sort. The BE will prioritise the predefined filter if available.
Another option would be to:
- Fail early (throw error when building the
StreamChannelListController, or when callingclient.queryChannels) - Override
filter/sortwithnullwhenpredefinedFilterexists
But overall, I a think that letting the server handle this scenario would be the best, I don't want to introduce front-end guards which might become invalid if the server changes the default behaviour.
Let me know if you think we should introduce some front-end checks anyway.
| /// falling back to `last_updated` otherwise — this mirrors the server's | ||
| /// default sort for channel queries. | ||
| SortOrder<ChannelState> get predefinedFilterFallbackSort { | ||
| if (_touchesField('last_message_at')) { |
There was a problem hiding this comment.
Note: This follows the BE default sort, if no sort is defined in the predefined filter. See this discussion.
| /// Default implementation returns an empty response; persistence | ||
| /// implementations that support predefined-filter caching should override | ||
| /// this. | ||
| Future<QueryChannelsResponse> getChannelStatesByPredefinedFilter({ |
There was a problem hiding this comment.
Do you think it is OK to return QueryChannelsResponse here - or should we introduce a new specific model for this?
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v10.0.0 #2709 +/- ##
==========================================
Coverage ? 67.94%
==========================================
Files ? 413
Lines ? 24641
Branches ? 0
==========================================
Hits ? 16742
Misses ? 7899
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Submit a pull request
Linear: FLU-357
CLA
Description of the pull request
Adds support for server-defined predefined filters on
queryChannelsacross the LLC, persistence, and core layers.A predefined filter is a named filter/sort preset that lives on the server. The client sends
predefined_filter(plus optionalfilter_values/sort_valuesto interpolate placeholders) instead of an inline filter, and the server echoes back the materializedfilterandsortit applied.stream_chat(LLC)ChannelApi.queryChannelsandStreamChatClient.queryChannelsacceptpredefinedFilter,filterValues,sortValues.StreamChatClient.queryChannelsWithResultreturns aQueryChannelsResultexposing both the live channels and the server-resolvedPredefinedFilter(name + materialized filter + sort).PredefinedFiltermodel andpredefined_filterfield onQueryChannelsResponse.SortOption<T>.fromJsonadded so sort specs can round-trip through persistence.ChatPersistenceClienthooks:getChannelStatesByPredefinedFilterandupdateChannelQueriesByPredefinedFilter(default no-op so existing implementations keep compiling).stream_chat_persistencechannel_query_metadatatable that stores the server-resolvedfilter+sortkeyed by the predefined-filter query hash, so offline reads reconstruct the exact resolved spec the server applied.FilterConverterandChannelStateSortOrderConverterDrift converters.StreamChatPersistenceClientimplements the new hooks;ChannelQueryDaogainsupdateChannelQueriesByPredefinedFilterandgetChannelsAndSpecByPredefinedFilter.stream_chat_flutter_coreStreamChannelListControlleracceptspredefinedFilter,filterValues,sortValues. When set, they take precedence overfilter/channelStateSort._resolvedChannelStateSortthat is overwritten with the server-resolved sort on every successful query, so event-driven inserts keep matching the server's ordering even when the caller only specifies apredefinedFilter.Sample app
ChannelListnow uses thestream_chat_flutter_sample_apppredefined filter (interpolated with the currentuser_id) to demonstrate the flow end-to-end.How to test
Test coverage
predefined_filter_test.dart— model.predefined_filter_defaults_test.dart— fallback-sort selection.client_test.dart— online/offlinequeryChannelspaths andqueryChannelsWithResult.channel_api_test.dart— request payload assertions.filter_converter_test.dart/sort_order_converter_test.dart— Drift converters.channel_query_dao_test.dart— DAO read/write of cids + metadata.stream_chat_persistence_client_test.dart— persistence client integration.stream_channel_list_controller_test.dart— controller path including resolved-sort tracking.