Repository navigation
refactor(llc)!: route message reminders through the generated client - #3053
Draft
VelikovPetar wants to merge 35 commits into
Draft
VelikovPetar wants to merge 35 commits into
VelikovPetar wants to merge 35 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # packages/stream_chat/lib/src/client/client.dart
…/flu-882_polls_openapi_migration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ient_test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mappers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-openapi-migration # Conflicts: # migrations/v11-migration.md # packages/stream_chat/CHANGELOG.md
…igration' into claude/polls-openapi-migration-0dc838 # Conflicts: # migrations/v11-migration.md # openapi-migration/12-uploads-cdn.md # packages/stream_chat/CHANGELOG.md # packages/stream_chat/lib/src/core/api/responses.g.dart
…esponse Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…igration' into claude/polls-openapi-migration-0dc838 # Conflicts: # packages/stream_chat/CHANGELOG.md
…igration-0dc838 # Conflicts: # migrations/v11-migration.md # openapi-migration/04-roles-guest-and-app.md # openapi-migration/09-users.md # openapi-migration/README.md # openapi-migration/tool/generate_plan.py # packages/stream_chat/CHANGELOG.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # packages/stream_chat/lib/src/ws/events/event.g.dart
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…penapi_migration' into claude/message-mappers-openapi-591b98 # Conflicts: # migrations/v11-migration.md # openapi-migration/10-messages.md # openapi-migration/tool/generate_plan.py # packages/stream_chat/CHANGELOG.md
…igration' into claude/message-mappers-openapi-591b98 # Conflicts: # openapi-migration/README.md # openapi-migration/tool/generate_plan.py # packages/stream_chat/lib/src/client/client.dart # packages/stream_chat/lib/src/core/api/responses.dart # packages/stream_chat/lib/src/core/api/responses.g.dart # packages/stream_chat/lib/src/core/models/converters/v1_json_converters.dart # packages/stream_chat/lib/src/core/models/message.g.dart # packages/stream_chat/lib/src/ws/events/event.g.dart # packages/stream_chat/test/src/client/client_test.dart
…enapi_migration' into claude/message-mappers-openapi-591b98 # Conflicts: # migrations/v11-migration.md # openapi-migration/README.md # openapi-migration/tool/generate_plan.py # packages/stream_chat/CHANGELOG.md # packages/stream_chat/lib/src/core/api/responses.g.dart # packages/stream_chat/test/src/client/client_test.dart
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # packages/stream_chat_flutter_core/CHANGELOG.md
…efactor/flu-955_reminders_openapi_migration # Conflicts: # packages/stream_chat_flutter_core/CHANGELOG.md
…oll requests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efactor/flu-955_reminders_openapi_migration
…/flu-955_reminders_openapi_migration
…e custom data revisit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Submit a pull request
Linear: FLU-955
Github Issue: -
CLA
Description of the pull request
Moves message reminders onto the OpenAPI-generated client, as plan group 06 (Reminders). It also adds the mapper from the generated
MessageResponseto today'sMessage; reminders are its first user. Stacked on #3052.Note
The branch carries more than this change. Besides the final commit, it contains a merge of #3037 (polls, still open against
v11) and five not-yet-reviewed commits that make leaf models plain:Moderation(e1ec831),ReactionGroup(ae62a1b),Action(d4e87e1),Reaction(b072b06) andLocation(03c00a8). The message mapper depends on both. This PR lands after #3037; the leaf-model commits can be split into their own PR if preferred. Review this change through the last commit, d2c4277.Reminders (group 06): fully migrated
StreamChatClientandChannel:createReminder,updateReminder,deleteReminderandqueryRemindersreturn aResultinstead of throwing.queryReminderstakeslimit(default 10),nextandprevinstead ofPaginationParams, andQueryRemindersResponsegainsprev.deleteReminderreturns a newDeleteReminderResponse.CreateReminderResponse,UpdateReminderResponseandQueryRemindersResponsebecome immutable freezed envelopes with a non-nullduration. Their shared base class,MessageReminderResponse, is removed.MessageReminderbecomes a plain freezed model. It losesfromJson,toJsonandEquatable; equality is unchanged, and the hand-writtencopyWithandmergeare kept.Message.reminder,Event.reminder) decodes through the internalMessageReminderV1JsonConverter, which writes the keys v10 did.RemindersRepositoryoverDefaultApi;reminders_api.dartandStreamChatApi.remindersare removed.StreamMessageReminderListControlleris adapted; its API and behaviour are unchanged.DefaultApi.createReminder(POST /api/v2/chat/messages/{id}/reminders)StreamChatClient.createReminder,Channel.createReminderDefaultApi.updateReminder(PATCH /api/v2/chat/messages/{id}/reminders)StreamChatClient.updateReminder,Channel.updateReminderDefaultApi.deleteReminder(DELETE /api/v2/chat/messages/{id}/reminders)StreamChatClient.deleteReminder,Channel.deleteReminderDefaultApi.queryReminders(POST /api/v2/chat/reminders/query)StreamChatClient.queryRemindersCreateReminderResponse,UpdateReminderResponse,QueryRemindersResponseDeleteReminderResponseDeleteReminderResponse(new, ours)ReminderResponseDataMessageReminderMessage mapping: added, used only by reminders for now
The generated message and everything nested in it map onto today's json_serializable models. Each mapper sits in its own file under
repository/mapper/:message_mapper.dartMessageResponse→Messageattachment_mapper.dartAttachment→Attachment,Action→Actionreaction_mapper.dartReactionResponse→Reaction,ReactionGroupResponse→ReactionGrouplocation_mapper.dartSharedLocationResponseData→Locationdrafts_mapper.dartDraftResponse→Draft,DraftPayloadResponse→DraftMessagemoderation_mapper.dart(existing)ModerationV2Response→Moderationreminders_mapper.dartReminderResponseData→MessageReminder, plus the four envelopesMessagegainshtml,mml,imageLabelsanddeletedReplyCountas constructor arguments stored inextraDataand read back through typed getters. This is the partial promotionUserandMemberuse.core/util/message_decoding.dart(internal) is shared byMessage.fromJsonand the mapper:withDerivedState(): the type/state derivation, moved verbatim fromfromJson;reactionGroupsFromCounts(): reaction groups built from counts and scores, rewritten to work on typed maps with the same results.Decisions
PaginationParams→limit/next/prev(the backend reads only those, so the other fields never worked), and removingMessageReminderResponse.deleteReminderreturns an envelope, notResult<void>: the spec answers a namedDeleteReminderResponse.!, no throwing constructors on response data. Repositories keepresult.map(...)and there is no catching helper.extraData. This matches v1, where the server drops a colliding custom key. The entries forcid,htmlanddeleted_reply_countare redundant, because those are always written after the custom data, but they are kept for consistency until the full promotion.cidstays raw inextraData, as in v10.mentioned_channel_membersis dropped by the v2 mapper: the SDK has no feature built on it.Message.fromJson(WebSocket events, offline cache) still puts it inextraData.DraftMessagekeepshtmlandmmlas plainextraDataentries, without getters.Eventkeeps decoding v1 JSON after group 10, so they are labelled "WebSocket v2 (no group)", like the poll converters.remindAtonupdateReminderclears the due date, as in v10: the backend treats the generated request's explicitnulllike v10's omitted key.Temporary until a later step
Message.fromJsonMessage,Attachment,Draft,DraftMessage,LocationMessageReminderV1JsonConverter,ReactionV1JsonConverterEvent/Messagestill decode v1 JSONhtml/mml/imageLabels/deletedReplyCountstored inextraDataextraDatakeeps what v10 put in itextraData-backed values safe from custom datacidraw inextraData;mentioned_channel_memberson the v1 path onlyuser_mapper.dart, unchanged; nested users carryblocked_user_ids: []where v10 had noneFollow-ups
User's custom-key filter lacksnameandimage, so a custom key with those names can stand in for a missing real value. It is left as is, consistent with the message filters, until the full promotion.blocked_user_ids: []on nested users.Channel's reminder methods throwStateErrorsynchronously on an uninitialized channel, as in v10.Backend checks
queryReminderscarry their channel, message and user. Create and update carry the message and user. Event payloads carry them only on some paths. Test stubs follow this.type: "deleted". v2 moderation carries the current action names (remove,bounce,flag,shadow).reaction_countsandreaction_scoresalways share keys with the groups and are integers;reaction_groupsis absent on messages without reactions and on some legacy ones.customcan contain keys named like built-in fields; v1 drops them.Testing
melos run analyzeanddart formatare clean. Suites pass:stream_chat(1,997),stream_chat_flutter_core(384),stream_chat_persistence(314).generate_plan.py --checkreports 0 problems.New client tests (
client_{create,update,delete}_reminder_test.dart,client_query_reminders_test.dart):message_fixtures.dart, with distinct values across three messages) and compares the whole envelope;Extended tests:
message_test(type/state derivation, reaction-group precedence, the new constructor arguments and getters),v1_json_converters_test(reminder decode, epoch dates,toJsonkeys, bookmark round trip),message_reminder_test(mergekeeps the channel, message and user the update lacks),channel_test(with and without a due date), and the controller test (page order and cursors).Coverage and mutation testing: line coverage is 100% for every new or changed file. Mutation testing (317 mutants) left only survivors with a recorded reason. Three adversarial reviews (v10 parity, tests, API/docs/plan) and two further test passes were applied.
Live v1 vs v2 parity on the demo app (throwaway channel): 34 of 34 domain-model comparisons equal, covering create for 16 message types and query for the 15 still listed after a soft delete:
Also equal: update (set and clear the due date), cursors, and the second page. The only difference is the deferred
blocked_user_ids.Screenshots / Videos
Not applicable: no visible UI change.
🤖 Generated with Claude Code