Parse the draft message with the generated model and restore the draft command round trip - #6718
Conversation
…t command round trip
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (13)
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review. WalkthroughDraft payloads now use a shared response model with custom-data parsing. Draft command and argument values map between custom data, domain models, and request models. Tests cover parsing, mapping, serialization, and missing command data. ChangesDraft payload mapping
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant DraftJSON
participant MoshiChatParser
participant DraftPayloadResponseAdapter
participant DomainMapping
participant DtoMapping
DraftJSON->>MoshiChatParser: parse draft payload
MoshiChatParser->>DraftPayloadResponseAdapter: read flattened custom fields
DraftPayloadResponseAdapter-->>DomainMapping: return DraftPayloadResponse
DomainMapping-->>DomainMapping: map command, args, and extraData
DtoMapping->>DtoMapping: add non-null command data to custom
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The SDK now preserves draft custom data and restores command round trips; the change is mergeable with normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 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. I hop through fields where draft keys gleam Comment |
SDK Size Comparison 📏
|
|
|
🚀 Available in v7.12.0 |



Goal
Parse the draft message with the generated
DraftPayloadResponse, retiringDownstreamDraftMessageDto,and fix the two things the swap exposed: draft custom data was never read, and the active slash command
stopped being sent.
Closes AND-1473
Closes AND-1558
Part of AND-1291
Implementation
DownstreamDraftDto.messageat the generated model and delete the hand-written one. VendorsDraftPayloadResponse, the only new model in the closure.custom.commandandargsincustomin both directions: into the request body when mappingDraftMessage, and back out to the typed domain fields when reading, filtered out ofextraDataso theydo not show up twice.
Notes
Drafts have no dedicated command fields on the backend. Neither
DraftPayloadResponsenorMessageRequestdeclares them, and both carry
Custom jsonextra.ExtraFields, which sweeps unknown root keys in andflattens them back out. That is what the round trip has always relied on:
UpstreamMessageDtodeclaredcommandandargs, so they serialized at the root, the backend stored them as custom data, and theresponse flattened them back where the typed DTO field read them.
Building the outgoing body with
MessageRequestremoved the two declarations and left the values nowhereto go, so they have not been sent since v7.11.0. iOS carries the same mechanism explicitly, putting both
into custom data in
asDraftMessageRequest()and reading them back inDraftPayload+Extensions, so thismatches it rather than inventing a shape.
Custom data on drafts is a separate, older bug:
DownstreamDraftMessageDtodeclared a field literally namedextraDatawith no collecting adapter registered, and the wire has no key by that name, so every draft readback with an empty map. The generated model declares
custom, and registering the adapter is what makes itarrive.
Drafts written by this SDK since v7.11.0 have no command or args in their stored custom data and cannot be
recovered. Drafts written by iOS, or by Android before that, resolve again once this lands.
Testing
Mutation sweep over
DownstreamDraftDto.toDomain: zero survivors across all twelve fields.Added a parsing test feeding root-level custom keys as JSON, a serialization test asserting both keys reach
the root of the request body, and mapper tests for the promotion and for a draft with no active command. The
draft.updatedfixture now carries custom data too, so the event path is covered as well as the HTTP one.Device-probed
createDraftMessageandqueryDrafts, with and without an active command. The request bodycarried
probe_flair,commandandargsflattened to the root, and both reads returnedcommand=giphy,args=catandextraData={probe_flair=gold}with no command keys left in the map. The no-command passreturned nulls and a clean map.
Summary by CodeRabbit
New Features
Bug Fixes