Skip to content

Wire enhanced-mention fields through Message#6479

Draft
gpunto wants to merge 1 commit into
developfrom
pr1-enhanced-mentions-data
Draft

Wire enhanced-mention fields through Message#6479
gpunto wants to merge 1 commit into
developfrom
pr1-enhanced-mentions-data

Conversation

@gpunto
Copy link
Copy Markdown
Contributor

@gpunto gpunto commented May 29, 2026

Goal

Add the new enhanced-mention fields and Config.pushLevel to the SDK's data layer so apps can read and write them end-to-end. UI lands in later PRs.

This is PR 1 in the enhanced-mentions series.

Part of AND-1175

Implementation

  • Message gets mentionedHere, mentionedChannel, mentionedRoles: List<String>, mentionedGroups: List<UserGroup>.
  • New UserGroup / UserGroupMember models; Config.pushLevel: String?.
  • DTOs: upstream sends mentioned_group_ids (id list); downstream receives hydrated mentioned_groups. DomainMapping / DtoMapping round-trip the new fields.
  • Room: MessageEntity / ReplyMessageEntity get a column per field; mentionedGroups is persisted as JSON via a new UserGroupConverter. ChatDatabase bumps its schema version.

Testing

  • MessageMapperTest, DtoMappingTest, DomainMappingTest, DownstreamMessageDtoAdapterTest round-trip the new fields.
  • Manual: send a message with mentionedHere = true and confirm it round-trips through Room.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for mentioning user groups in messages alongside existing mention types.
    • Enhanced message mention tracking to include @here, @channel, user groups, and roles.
    • Added push level configuration option for channels.

Review Change Stack

@gpunto gpunto added the pr:new-feature New feature label May 29, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 29, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@github-actions
Copy link
Copy Markdown
Contributor

DB Entities have been updated. Do we need to upgrade DB Version?
Modified Entities :

stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/channelconfig/internal/ChannelConfigEntity.kt%0Astream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/MessageEntity.kt%0Astream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/ReplyMessageEntity.kt

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 29, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.83 MB 5.84 MB 0.01 MB 🟢
stream-chat-android-ui-components 11.07 MB 11.08 MB 0.01 MB 🟢
stream-chat-android-compose 12.46 MB 12.47 MB 0.01 MB 🟢

@gpunto gpunto force-pushed the pr1-enhanced-mentions-data branch from f4808c1 to 56e5d2b Compare May 29, 2026 15:35
@gpunto
Copy link
Copy Markdown
Contributor Author

gpunto commented May 29, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
57.6% Coverage on New Code (required ≥ 80%)
4.3% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Walkthrough

This PR adds comprehensive user group mention support throughout the Stream Chat Android SDK, enabling messages to track mentions of @here, @channel, specific user groups, and roles. It also introduces push-level configuration. Changes span API DTOs, domain models, offline storage, and test infrastructure with mapping and persistence throughout.

Changes

User Group Mentions and Configuration

Layer / File(s) Summary
User group and message DTO models with mention fields
stream-chat-android-client/.../dto/UserGroupDtos.kt, stream-chat-android-client/.../dto/MessageDtos.kt, stream-chat-android-client/.../mapping/DtoMapping.kt
DownstreamUserGroupDto and DownstreamUserGroupMemberDto provide Moshi-serializable structures for user group data. UpstreamMessageDto and DownstreamMessageDto add mentioned_here, mentioned_channel, mentioned_groups, and mentioned_roles fields with sensible defaults.
Public domain models for user groups and message mentions
stream-chat-android-core/.../models/UserGroup.kt, stream-chat-android-core/.../models/Message.kt
UserGroup and UserGroupMember immutable data classes model group identity and membership. Message gains four mention properties and builder methods for mentionedHere, mentionedChannel, mentionedGroups, and mentionedRoles.
Configuration domain and DTO models with push level
stream-chat-android-client/.../dto/ConfigDto.kt, stream-chat-android-core/.../models/Config.kt
ConfigDto and Config add nullable push_level field with documentation for supported notification levels.
API mapping between DTOs and domain models
stream-chat-android-client/.../mapping/DomainMapping.kt, stream-chat-android-client/.../mapping/DtoMapping.kt
DomainMapping converts downstream DTOs to domain: DownstreamMessageDto mention fields map to Message, ConfigDto.push_levelConfig.pushLevel, and new DownstreamUserGroupDto.toDomain() / DownstreamUserGroupMemberDto.toDomain() helpers bridge group data. DtoMapping converts domain to upstream: Message.mentionedGroupsUpstreamMessageDto.mentioned_group_ids.
Offline storage entities for mentions and user groups
stream-chat-android-client/.../repository/domain/message/internal/MessageEntity.kt, stream-chat-android-client/.../repository/domain/message/internal/ReplyMessageEntity.kt, stream-chat-android-client/.../database/converter/internal/UserGroupConverter.kt, stream-chat-android-client/.../database/internal/ChatDatabase.kt
MessageInnerEntity and ReplyMessageInnerEntity store mention fields. UserGroupConverter serializes List<UserGroup> to/from JSON via Moshi. Database schema version incremented from 200 to 201; UserGroupConverter registered in @TypeConverters.
Channel configuration entity and mapping for push level
stream-chat-android-client/.../domain/channelconfig/internal/ChannelConfigEntity.kt, stream-chat-android-client/.../domain/channelconfig/internal/ChannelConfigMapper.kt
ChannelConfigInnerEntity adds nullable pushLevel field. Bidirectional mapper includes pushLevel in both ChannelConfigChannelConfigEntity and reverse conversion.
Entity to domain mapping for message mentions
stream-chat-android-client/.../domain/message/internal/MessageMapper.kt
Mention fields (mentionedHere, mentionedChannel, mentionedGroups, mentionedRoles) are mapped in all four directions: MessageEntity.toModel, Message.toEntity, ReplyMessageEntity.toModel, and Message.toReplyEntity.
Test fixture factories for user groups and message mentions
stream-chat-android-client/src/test/.../Mother.kt, stream-chat-android-core/src/testFixtures/.../Mother.kt
Client Mother adds randomDownstreamUserGroupDto() and extends randomDownstreamMessageDto() with mention parameters. Core Mother introduces randomUserGroup() and randomUserGroupMember(), and extends randomMessage() to accept mention-related parameters.
Test coverage for API and entity mappings
stream-chat-android-client/src/test/.../DomainMappingTest.kt, stream-chat-android-client/src/test/.../DtoMappingTest.kt, stream-chat-android-client/src/test/.../MessageMapperTest.kt, stream-chat-android-client/src/test/.../MessageDtoTestData.kt
Tests verify mention field propagation: DomainMappingTest checks downstream DTO-to-domain mapping, DtoMappingTest validates domain-to-upstream, MessageMapperTest tests entity-to-domain round-trips, and MessageDtoTestData provides fixtures for parsing and serialization.
Public API signature updates
stream-chat-android-core/api/stream-chat-android-core.api
API file updated to reflect new Config.getPushLevel() accessor, Message constructor/copy signatures and getters for mention fields, Message.Builder setters, and new UserGroup/UserGroupMember classes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • VelikovPetar
  • andremion

Poem

🐰 Hops of joy, mentions take flight,
Groups and roles now shining bright,
DTOs map with grace so true,
From downstream flows to storage—who knew?
Push levels set, the chat's complete!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: wiring enhanced-mention fields through the Message model, which is the core objective of this PR.
Description check ✅ Passed The PR description includes Goal and Implementation sections addressing the main changes, but lacks Testing details beyond a manual test note, and the UI Changes and Contributor Checklist sections are incomplete.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr1-enhanced-mentions-data

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/database/converter/internal/UserGroupConverter.kt (1)

32-35: 💤 Low value

Consider defensive fallback for JSON parse failures.

If fromJson encounters malformed JSON, it returns null. While Room will use the entity field's default (emptyList()), explicitly handling parse failure would be more defensive and clearer.

♻️ Suggested improvement
     `@TypeConverter`
     fun stringToUserGroupList(data: String?): List<UserGroup>? {
         if (data.isNullOrEmpty() || data == "null") return emptyList()
-        return listAdapter.fromJson(data)
+        return listAdapter.fromJson(data) ?: emptyList()
     }
🤖 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/internal/offline/repository/database/converter/internal/UserGroupConverter.kt`
around lines 32 - 35, The stringToUserGroupList function should defensively
handle malformed JSON by guarding the call to listAdapter.fromJson; if data is
null/empty return emptyList() as already done, and if listAdapter.fromJson
throws or returns null, catch the exception or check for null and return
emptyList() instead of propagating null—update
UserGroupConverter.stringToUserGroupList to wrap the fromJson call in a
try/catch (or null-check) and ensure it always returns a non-null
List<UserGroup> fallback.
🤖 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.

Nitpick comments:
In
`@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/database/converter/internal/UserGroupConverter.kt`:
- Around line 32-35: The stringToUserGroupList function should defensively
handle malformed JSON by guarding the call to listAdapter.fromJson; if data is
null/empty return emptyList() as already done, and if listAdapter.fromJson
throws or returns null, catch the exception or check for null and return
emptyList() instead of propagating null—update
UserGroupConverter.stringToUserGroupList to wrap the fromJson call in a
try/catch (or null-check) and ensure it always returns a non-null
List<UserGroup> fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2d2004e5-7e7d-41ff-b6bf-6de0da8ce2a8

📥 Commits

Reviewing files that changed from the base of the PR and between 4560c3d and 56e5d2b.

📒 Files selected for processing (23)
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ConfigDto.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/MessageDtos.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/UserGroupDtos.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/database/converter/internal/UserGroupConverter.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/database/internal/ChatDatabase.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/channelconfig/internal/ChannelConfigEntity.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/channelconfig/internal/ChannelConfigMapper.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/MessageEntity.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/MessageMapper.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/ReplyMessageEntity.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DtoMappingTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/internal/offline/Mother.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/internal/offline/repository/domain/message/internal/MessageMapperTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/MessageDtoTestData.kt
  • stream-chat-android-core/api/stream-chat-android-core.api
  • stream-chat-android-core/src/main/java/io/getstream/chat/android/models/Config.kt
  • stream-chat-android-core/src/main/java/io/getstream/chat/android/models/Message.kt
  • stream-chat-android-core/src/main/java/io/getstream/chat/android/models/UserGroup.kt
  • stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:new-feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant