Skip to content

Migrate the channel members and member events to the generated model - #6698

Merged
gpunto merged 3 commits into
developfrom
migrate/member-events
Sep 15, 2026
Merged

gpunto merged 3 commits into
developfrom
migrate/member-events

Conversation

@gpunto

@gpunto gpunto commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Goal

Parse channel members and the member events with the generated ChannelMemberResponse, retiring
DownstreamMemberDto.

Part of AND-1291

Implementation

  • Point the member field on the eight member events, and members / membership on both
    DownstreamChannelDto and the hand-written ChannelResponse, at the generated model. queryMembers and
    partialUpdateMember already returned it through MembersResponse and UpdateMemberPartialResponse;
    this adds the channel payloads and the events.
  • Delete DownstreamMemberDto with its adapter, its registration and its mapper. MemberDtos.kt and
    MemberDtoAdapters.kt become DownstreamMemberInfoDto.kt and DownstreamMemberInfoDtoAdapter.kt, since
    that is all they still hold.
  • Seed every field in randomChannelMemberResponse with a value that differs from its domain default. Six
    of them were previously left unset, which made their assertions in the mapper test vacuous.
  • Give the members in the stream-chat-android-ui-uitests channel fixtures the notifications_muted and
    user.language keys the generated models require. The snapshot workflow is dispatch-only, so nothing ran
    them.
  • Derive NON_CUSTOM_MEMBER_KEYS from the adapter's compatibility set rather than repeating it, since most
    of those keys are now declared on ChannelMemberResponse and only stay in extraData because that set
    holds them there.

Notes

This swap makes a member without a user parseable. The wire declares user,omitempty and falls back to
user_id, but DownstreamMemberDto.user was non-null, so such a payload would have thrown and taken the
whole response or event with it. The generated model is nullable there and the mapper already falls back to
User(id = userId).

Six fields go the other way, from optional to required: created_at, updated_at, banned,
shadow_banned, channel_role and notifications_muted. All six are plain non-omitempty tags on
payload.ChannelMemberResponse, the struct the events and channel responses actually serialize, so the
wire always sends them. Every lean member fixture had to gain them.

membership is populated only by get_channel and get_or_create_channel; update_channel leaves it
out, so an addMembers response carries members without a membership. The field was already nullable and
still is.

The E2E mock server needs GetStream/stream-chat-test-mock-server#68 before this merges. Its member.added
payload was seeded from a fixture that predates the sync script and omits notifications_muted and the
user's language, so once members parse through the generated model that event fails to decode and is
dropped. Nothing turns red either way, since the one test that adds a member asserts a delivery status that
is hidden whether or not the event arrives, but without it the test stops exercising its scenario.

Testing

  • Mutation sweep over ChannelMemberResponse.toDomain: zero survivors across all 15 fields, where six
    survived before the fixture was seeded.
  • Device-probed every shape that carries a member: members and membership from queryChannels, the
    addMembers response, partialUpdateMember, and the member.added, member.updated and
    member.removed events. The compatibility keys user_id and role still reach Member.extraData
    alongside real custom data, which round-tripped on both the response and the event.

@gpunto gpunto added the pr:internal Internal changes / housekeeping label Sep 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 6.09 MB 6.08 MB -0.00 MB 🚀
stream-chat-android-ui-components 11.39 MB 11.39 MB 0.00 MB 🟢
stream-chat-android-compose 13.07 MB 13.07 MB 0.00 MB 🟢

@gpunto
gpunto marked this pull request as ready for review September 14, 2026 09:42
@gpunto
gpunto requested a review from a team as a code owner September 14, 2026 09:42
@coderabbitai

coderabbitai Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 55b43110-cbec-481e-babf-831bed25204f

📥 Commits

Reviewing files that changed from the base of the PR and between 7c12807 and d5919dc.

📒 Files selected for processing (18)
  • 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/model/dto/ChannelDtos.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/DownstreamMemberInfoDto.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/EventDtos.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/ChannelResponse.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelMemberResponseAdapter.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/DownstreamMemberInfoDtoAdapter.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.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/MoshiChatApiTestArguments.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/EventMappingTestArguments.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/extensions/internal/MemberExtensionsTests.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser/EventArguments.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamMemberDtoAdapterTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/MemberDtoTestData.kt
💤 Files with no reviewable changes (7)
  • 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/model/dto/DownstreamMemberInfoDto.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamMemberDtoAdapterTest.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/DownstreamMemberInfoDtoAdapter.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/parser2/testdata/MemberDtoTestData.kt

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


Walkthrough

The change replaces DownstreamMemberDto with ChannelMemberResponse across channel responses, events, mappings, parser registration, and test fixtures. The obsolete DTO, adapter, mapping function, and related test data are removed.

Changes

Channel member model migration

Layer / File(s) Summary
Channel and event member contracts
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt, stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/EventDtos.kt, stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/ChannelResponse.kt, stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/DownstreamMemberInfoDto.kt
Channel responses and member-related events now use ChannelMemberResponse. The obsolete DownstreamMemberDto declaration is removed.
Member mapping and parser cleanup
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/parser2/MoshiChatParser.kt, stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/*
The DownstreamMemberDto.toDomain() mapping and custom adapter registration are removed. The remaining adapter documentation is updated.
Fixtures and parser test migration
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/*, stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser/*, stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/*, stream-chat-android-client/src/test/java/io/getstream/chat/android/client/extensions/internal/MemberExtensionsTests.kt, stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.kt
Test arguments and JSON fixtures now use ChannelMemberResponse. Obsolete DownstreamMemberDto factories, mapping coverage, adapter tests, and test data are removed.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: velikovpetar

Merge Risk: ⚪ Minimal · up to d5919

The member-model migration retains parsing, custom data, and user fallback behavior across the migrated paths. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 11 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly and concisely describes the main change: migrating channel members and member events to the generated model.
Description check ✅ Passed The description explains the goal, implementation, compatibility behavior, testing, fixture updates, and known E2E mock-server dependency. It omits template sections for UI changes, checklists, and GI…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch migrate/member-events

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

A rabbit hops through member fields,
Old DTO leaves the parsing yields.
New channels carry shapes more bright,
Tests follow paths from day to night,
And adapters rest beneath moonlight.

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

@gpunto
gpunto force-pushed the migrate/member-events branch from d5919dc to 1d9311a Compare September 14, 2026 10:58

@andremion andremion left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nothing blocking. Two fixtures outside the diff stop parsing with this change, and CI does not catch either.

The mock server's http_member.json has no notifications_muted and its user has no language, and helpers/members.rb sends that object as the member.added payload. The event throws and gets dropped, so test_deliveryStatusHidden_whenNewParticipantAddedAndReadEventsIsDisabled is passing without it now. Would you mind a small PR on stream-chat-test-mock-server for that?

Same two keys are missing in stream-chat-android-ui-uitests/src/androidTest/resources/http_channel.json and http_channels.json. The snapshot workflow is dispatch-only so CI is unaffected, but run_snapshot_test will fail on the next run.

Not blocking, just on the description: MembersResponse.members and UpdateMemberPartialResponse.channelMember already declare ChannelMemberResponse on develop, so queryMembers and partialUpdateMember were already on that path.

@sonarqubecloud

Copy link
Copy Markdown

@gpunto
gpunto enabled auto-merge September 15, 2026 08:05
@gpunto

gpunto commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, all three were real.

The uitests fixtures are fixed in c57923d: all four members in each file gained notifications_muted and user.language. I swept the repo for others and these two were the only ones.

The mock server turned out to be a bit more involved: http_member.json predates sync.rb and is not one of the fixtures it records, so it could never be brought up to date by re-recording. GetStream/stream-chat-test-mock-server#68 seeds the added member from http_add_member.json instead, which sync does record from exactly that endpoint, and deletes the stale file. Cron runs are green on Android; iOS and Flutter are red on failures that also occur without the change, details in that PR.

Fixed the description too, you are right that queryMembers and partialUpdateMember were already on that path. I also added a note there that the mock server PR should land first, since nothing turns red if it does not.

@gpunto
gpunto added this pull request to the merge queue Sep 15, 2026
Merged via the queue into develop with commit 80dd6d7 Sep 15, 2026
31 checks passed
@gpunto
gpunto deleted the migrate/member-events branch September 15, 2026 09:24
@stream-public-bot stream-public-bot added the released Included in a release label Sep 24, 2026
@stream-public-bot

Copy link
Copy Markdown
Contributor

🚀 Available in v7.12.0

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

Labels

pr:internal Internal changes / housekeeping released Included in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants