feat(chat): scaffold roster summary, participation rules, and chat-profile blobs - #1464
Merged
Merged
Conversation
…ofile blobs flipcash2-client-protocol synced to 35f99814 (six commits, #93-#98). Two of its changes are wire-compatible renames that still break the build: EmojiReaction and ReactionUpdate's `sequence` field became `version`, and blob.v1.AccessContext's `profile` oneof arm became `user_profile` — an exhaustive `when` over that oneof stops compiling on the rename alone, before it even reaches the new `chat_profile` arm the same sync adds. The rest is additive. chat.v1.Metadata gains `picture` (a group chat's profile picture), `roster_summary` (member count plus a staleness version, so a client can tell its cached roster went stale without holding the roster itself), and `rules` (participation gates on listening and speaking). Both proto-to-domain mapping paths — ProtobufToLocal's toChatMetadata() and ChatMetadataMapper, which exist in parallel for historical reasons — now populate all three the same way. ListenerRules and SpeakerRules are two proto messages with an identical `kind` oneof (minimum balance or staff), so they collapse into one domain type, ChatRuleRequirement, used by both ChatRules.listener and ChatRules.speaker. A `kind`-unset entry is dropped rather than defaulted: inventing a requirement the server never sent would wrongly gate the chat, and inventing "no requirement" would wrongly open it. Nothing in the app reads picture, rosterSummary, or rules yet, so this is scaffolding, not a feature: the new ChatMetadata fields default to null/zero so the existing test constructors keep compiling, and no screen shows a roster count or a rules gate. That UI work is a separate, open product decision. BlobAccessContext.ChatProfile is wired the same way — mapped to and from the proto, validated, and otherwise unconsumed.
0.6.0 is unpublished until flipcash2-client-protocol's sync PR merges and publish.yml runs, so Gradle resolution fails here until then. The scaffold commit ahead of this builds against the local checkout through protoLocalRoot, which CI never sees.
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.
Blocked on code-payments/flipcash2-client-protocol#12. Draft until
0.6.0is published, because this pins a version that does not exist yet — Gradle resolution reportscom.flipcash:flipcash2-client-protocol:0.6.0 FAILEDuntil then. CI never sees the local override, sinceprotoLocalRootlives in untrackedlocal.properties.Why
flipcash2-protobuf-apirenamed three fields in place and added group-chat metadata across #93–#98. Nothing was renumbered, so the wire format is unchanged, but two of the renames are on fields this app reads and the third is on a oneof it builds, so the module does not compile against the new package without moving.What changed
All under
services/flipcash/src/main/kotlin/com/flipcash/services/:internal/network/extensions/ProtobufToLocal.ktgetSequence()→getVersion()onEmojiReactionandReactionUpdate;toChatMetadata()populates the three new fields; newtoRosterSummary(),toChatRules(),toRuleRequirement()mappersinternal/domain/ChatMetadataMapper.ktinternal/network/api/BlobStorageApi.kt.setProfile(→.setUserProfile(, plus the newChatProfilearmmodels/chat/BlobAccessContext.ktChatProfile(chatId)variantmodels/chat/ChatMetadata.ktpicture,rosterSummary,rules, all trailing with defaultsmodels/chat/RosterSummary.kt,models/chat/ChatRules.ktnetwork/api/BlobAccessContextValidationTest.ktThe proto rename is absorbed at the accessor: the domain field stays
sequence, so the reaction ordering code above the mapper is untouched. Renaming it through the domain layer is a larger, separate change.Worth a reviewer's attention
ListenerRulesandSpeakerRulesare separate proto messages with identicalkindoneofs. This collapses them into oneChatRuleRequirementsealed interface, withChatRulesholding two lists of it, rather than mirroring the proto's two parallel types — the distinction the proto encodes is which list a requirement sits in, and that survives. iOS made the opposite call and kept two parallel enums (code-payments/code-ios-app#769), so the two platforms read differently here. Worth settling before anything consumes it.An entry whose
kindoneof is unset is dropped rather than defaulted, so a rule this client does not understand denies nothing instead of silently becoming a requirement it can evaluate.Nothing in the app reads
picture,rosterSummary,rules, or builds aChatProfileaccess context yet. This is scaffolding to keep the module compiling against the new contract, not a behaviour change.