Add ChatClient endpoints for user groups, roles, and chat preferences#6493
Add ChatClient endpoints for user groups, roles, and chat preferences#6493gpunto wants to merge 5 commits into
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
SDK Size Comparison 📏
|
b09c5e0 to
47accb0
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (26)
🚧 Files skipped from review as they are similar to previous changes (17)
WalkthroughAdds per-category chat-preference models and APIs, user-group CRUD/member operations, role search, DTO/domain mappings, MoshiChatApi implementations and DI wiring, ChatClient public methods and plugin/listener hooks, and accompanying tests. ChangesUser Group Management, Role Search, and Chat Preferences APIs
Sequence Diagram(s)sequenceDiagram
participant Client as ChatClient
participant API as MoshiChatApi
participant Retrofit as UserGroupApi/RoleApi/PushPreferencesApi
participant Server as Stream API
Client->>API: createUserGroup(name, id, ...)
API->>Retrofit: call CreateUserGroupRequest
Retrofit->>Server: POST /user_groups
Server-->>Retrofit: UserGroupResponse
Retrofit-->>API: Return DTO
API->>API: map DTO -> UserGroup
API-->>Client: Call<UserGroup>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt (1)
1736-1954: ⚡ Quick winAdd thread/state notes to these new public KDocs.
The new public APIs document parameters, but they don’t consistently state execution/thread expectations or client-state side effects (for example,
setUserChatPreferencesupdates local user state on success). Please align this block with the module KDoc requirement.As per coding guidelines, "Document public APIs with KDoc, including thread expectations and state notes."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt` around lines 1736 - 1954, Update the public KDoc for the new APIs (e.g., setUserChatPreferences, setChannelChatPreferences, createUserGroup, queryUserGroups, searchUserGroups, getUserGroup, updateUserGroup, deleteUserGroup, addUserGroupMembers, removeUserGroupMembers, searchRoles) to include thread/execution expectations (e.g., whether the call executes off the main thread or is asynchronous) and explicit client-state side-effect notes (for example, state that setUserChatPreferences updates mutableClientState.user on success). For each function mention if callbacks/Results are delivered on a background or main thread and whether the function mutates local client state or requires additional synchronization; keep the descriptions short and consistent with module KDoc guidelines.Source: Coding guidelines
stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt (1)
2869-2914: ⚡ Quick winAssert mapped chat-preferences in result, not only success type.
These two tests validate request payloads, but they don’t assert the returned mapped preferences from
DownstreamChatPreferencesDto. Add value assertions onresult.getOrThrow()so DTO→domain mapping regressions are caught.Also applies to: 2916-2952
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt` around lines 2869 - 2914, The test testSetUserChatPreferences currently only asserts a Result.Success type; extend it to assert the mapped domain preferences returned by sut.setUserChatPreferences by calling result.getOrThrow() and verifying that the chat preferences match the values from the DownstreamChatPreferencesDto (direct_mentions="all", channel_mentions="none", default_preference="none")—do the same change in the sibling test (the one covering the other response case). Locate the mapping flow through setUserChatPreferences, PushPreferencesResponse -> DownstreamPushPreferenceDto -> DownstreamChatPreferencesDto and assert the resulting domain ChatPreferences fields equal the expected domain values so DTO→domain regressions are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt`:
- Around line 1758-1760: The method setChannelChatPreferences currently calls
api.setChannelChatPreferences directly and therefore skips the plugin/offline
callback flow used by setChannelPushPreference and
snoozeChannelPushNotifications; to fix this, add a plugin/state propagation
similar to the push-preference path: introduce a new callback in the
plugin/state interface (e.g., onChannelChatPreferenceSet) and corresponding
handler in PushPreferencesListenerState (or a new ChatPreferencesListenerState)
with an updateChannelChatPreference(...) method, then update
ChatClient.setChannelChatPreferences to invoke that plugin callback (and update
offline state) after a successful api.setChannelChatPreferences call so channel
chat preference updates stay synchronized with plugins/offline logic
(alternatively, if synchronization is intentionally handled elsewhere, add
documentation in setChannelChatPreferences describing that behavior).
---
Nitpick comments:
In
`@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt`:
- Around line 1736-1954: Update the public KDoc for the new APIs (e.g.,
setUserChatPreferences, setChannelChatPreferences, createUserGroup,
queryUserGroups, searchUserGroups, getUserGroup, updateUserGroup,
deleteUserGroup, addUserGroupMembers, removeUserGroupMembers, searchRoles) to
include thread/execution expectations (e.g., whether the call executes off the
main thread or is asynchronous) and explicit client-state side-effect notes (for
example, state that setUserChatPreferences updates mutableClientState.user on
success). For each function mention if callbacks/Results are delivered on a
background or main thread and whether the function mutates local client state or
requires additional synchronization; keep the descriptions short and consistent
with module KDoc guidelines.
In
`@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt`:
- Around line 2869-2914: The test testSetUserChatPreferences currently only
asserts a Result.Success type; extend it to assert the mapped domain preferences
returned by sut.setUserChatPreferences by calling result.getOrThrow() and
verifying that the chat preferences match the values from the
DownstreamChatPreferencesDto (direct_mentions="all", channel_mentions="none",
default_preference="none")—do the same change in the sibling test (the one
covering the other response case). Locate the mapping flow through
setUserChatPreferences, PushPreferencesResponse -> DownstreamPushPreferenceDto
-> DownstreamChatPreferencesDto and assert the resulting domain ChatPreferences
fields equal the expected domain values so DTO→domain regressions are caught.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 71ffc174-dba0-4ffa-a9bb-154028ce6f35
📒 Files selected for processing (21)
stream-chat-android-client/api/stream-chat-android-client.apistream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatApi.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/RoleApi.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/UserGroupApi.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/DownstreamRoleDto.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/PushPreferenceDtos.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UserGroupRequests.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/SearchRolesResponse.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/UserGroupResponses.ktstream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/ChatModule.ktstream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.ktstream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.ktstream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.ktstream-chat-android-core/api/stream-chat-android-core.apistream-chat-android-core/src/main/java/io/getstream/chat/android/models/ChatPreferences.ktstream-chat-android-core/src/main/java/io/getstream/chat/android/models/PushPreference.ktstream-chat-android-core/src/main/java/io/getstream/chat/android/models/Role.kt
Exposes the full /usergroups API surface: create, list (query), get, update, delete, search by name prefix, and add/remove members. Adds the matching DTOs and wires them through ChatApi/MoshiChatApi.
Exposes a new public ChatClient function backed by the `/roles/search` endpoint. Adds the `Role` domain model and wires the response path through the Moshi API layer.
Adds ChatPreferences with per-category toggles (direct, role, group, here, channel mentions, thread replies, default fallback) alongside the existing coarse PushPreferenceLevel. New ChatClient methods setUserChatPreferences and setChannelChatPreferences hit the existing /push_preferences endpoint with the chat_preferences payload, and the response now hydrates PushPreference.chatPreferences so callers can read back the active toggles.
5980c58 to
306aa68
Compare
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
| public fun searchRoles( | ||
| query: String, | ||
| limit: Int? = null, | ||
| roleType: String? = null, |
There was a problem hiding this comment.
Small thing: roleType is only ever "user" or "channel", but it's a plain String here. You wrap the other closed sets in this PR (ChatPreferenceToggle), and PushPreferenceLevel does the same, so this one is inconsistent. Since it's a public API, changing to a typed value later would be a breaking change. Want to wrap it now, or keep it as a String on purpose?
| * Per-category push toggles. A null field means "use the server default". When set on a | ||
| * [PushPreference], takes precedence over [PushPreference.level]. | ||
| */ | ||
| public data class ChatPreferences( |
There was a problem hiding this comment.
Role and UserGroup from PR 1 both have @Immutable, but ChatPreferences and ChatPreferenceToggle don't. They are immutable value types that end up in Compose state via PushPreference.chatPreferences, so they would benefit from it too. Is it on purpose?
|
|
||
| @ParameterizedTest | ||
| @MethodSource("io.getstream.chat.android.client.api2.MoshiChatApiTestArguments#searchRolesInput") | ||
| fun testSearchRoles(call: RetrofitCall<SearchRolesResponse>, expected: KClass<*>) = runTest { |
There was a problem hiding this comment.
These check the request shape and Success/Failure, but nothing asserts the actual mapped Role / UserGroup fields, so a mistake in DownstreamRoleDto.toDomain() would not be caught. The mappings are trivial 1:1, so the risk is low. Maybe add one assertion on a mapped field to cover it?


Goal
Add the
ChatClientendpoints the enhanced-mentions UI needs: user-group CRUD/search, role search, and granular chat-preference toggles. No UI yet.This is PR 2 in the enhanced-mentions series.
Part of AND-1175
Implementation
createUserGroup,updateUserGroup,deleteUserGroup,getUserGroup,queryUserGroups,searchUserGroups,addUserGroupMembers,removeUserGroupMembers. New Retrofit interfaceUserGroupApiwith matching request/response DTOs.searchRoles+ newRolemodel andDownstreamRoleDto. New Retrofit interfaceRoleApi.setUserChatPreferences(prefs)andsetChannelChatPreferences(cid, prefs). NewChatPreferencesmodel with aChatPreferenceToggleper mention type.PushPreferencegains achatPreferencesfield so existing push-preference reads surface the new toggles.ChatApi/MoshiChatApiwire the new endpoints;ChatModuleregistersRoleApiandUserGroupApi.Testing
MoshiChatApiTestcovers every new endpoint: request shape, response mapping, and error paths.stream-chat-android-clientandstream-chat-android-core.Summary by CodeRabbit