Skip to content

feat(chat): canonical DM chat-id derivation, DmChatResolver, concurrent feed sync - #1123

Merged
bmc08gt merged 3 commits into
code/cashfrom
feat/chat-dm-id-resolver
Jul 23, 2026
Merged

feat(chat): canonical DM chat-id derivation, DmChatResolver, concurrent feed sync#1123
bmc08gt merged 3 commits into
code/cashfrom
feat/chat-dm-id-resolver

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Foundational chat-layer changes split out of the in-progress tip-DM / notifications work so they can land independently. Three focused commits:

1. feat(chat) — canonical DM chat-id derivation

Adds ChatIdGenerator, deriving a DM's ChatId from the two participants' user IDs: SHA-256 over a per-type domain (flipcash:chat:dm for CONTACT_DM, flipcash:chat:dm:2 for TIP_DM) and the unsigned-sorted, self-pair-collapsed member set. Mirrors the server's MustDeriveDmChatID byte-for-byte, so either side reaches the same id without a prior lookup. Unit tests pin the wire-contract vectors (matching the iOS TipDmChatIDTests).

2. refactor(chat) — extract DmChatResolver, add member accessors

Splits DM-identity resolution out of MessagingOperations into a dedicated DmChatResolver interface (generateChatId / getChatId), implemented by a new DmChatResolverDelegate and composed into RealChatCoordinator. MessagingOperations is left focused on operating on an existing ChatId.

Adds MessagingOperations.getOtherMember(chatId) returning the full ChatMember (profile incl. avatar) with a local-cache-then-network fallback; getOtherMemberE164 now delegates to it. Backs tip DM chat-id lookup with ChatMemberDao.getChatIdForMember / ChatMemberDataSource.getChatIdForUser.

3. perf(chat) — concurrent feed sync

Runs the contact and tip getDmChatFeed calls in parallel via coroutineScope/async, so combined-feed latency is max(contact, tip) instead of the sum. Failure semantics unchanged (contact fatal, tip tolerated).

Testing

  • :apps:flipcash:shared:chat:testDebugUnitTest passes (incl. new ChatIdGeneratorTest cross-platform vectors).
  • :apps:flipcash:shared:notifications:compileDebugKotlin passes — existing callers of getOtherMemberE164 are unaffected by the refactor.

Notes

  • Non-breaking: the ChatCoordinator facade surface is unchanged; existing getChatId callers still resolve through it.
  • Follow-ups (separate PRs): notification rendering for TIP_DM + avatar loading, and the tip-DM send flow.

bmc08gt and others added 3 commits July 23, 2026 10:58
Add ChatIdGenerator, which deterministically derives a DM's ChatId from
the two participants' user IDs: SHA-256 over a per-type domain
("flipcash:chat:dm" for CONTACT_DM, "flipcash:chat:dm:2" for TIP_DM) and
the unsigned-sorted, self-pair-collapsed member set. Mirrors the server's
MustDeriveDmChatID byte-for-byte so either side reaches the same id
without a prior lookup. Tests pin the wire-contract vectors (matching the
iOS TipDmChatIDTests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Split DM-identity resolution out of MessagingOperations into a dedicated
DmChatResolver interface (generateChatId / getChatId), implemented by a
new DmChatResolverDelegate and composed into RealChatCoordinator via `by`
delegation. MessagingOperations is left focused on operating on an
existing ChatId.

Add MessagingOperations.getOtherMember(chatId), returning the full
ChatMember (profile incl. avatar) with a local-cache-then-network
fallback; getOtherMemberE164 now delegates to it. Back tip DM chat-id
resolution with ChatMemberDao.getChatIdForMember /
ChatMemberDataSource.getChatIdForUser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Run the two getDmChatFeed calls in parallel via coroutineScope/async so
combined-feed latency is max(contact, tip) instead of their sum. Failure
semantics are unchanged: a contact-feed failure is fatal, a tip-feed
failure is tolerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the type: feature New functionality label Jul 23, 2026
@bmc08gt
bmc08gt merged commit a156985 into code/cash Jul 23, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the feat/chat-dm-id-resolver branch July 23, 2026 15:07
bmc08gt added a commit that referenced this pull request Jul 24, 2026
…nt feed sync (#1123)

* feat(chat): derive canonical DM chat IDs matching server

Add ChatIdGenerator, which deterministically derives a DM's ChatId from
the two participants' user IDs: SHA-256 over a per-type domain
("flipcash:chat:dm" for CONTACT_DM, "flipcash:chat:dm:2" for TIP_DM) and
the unsigned-sorted, self-pair-collapsed member set. Mirrors the server's
MustDeriveDmChatID byte-for-byte so either side reaches the same id
without a prior lookup. Tests pin the wire-contract vectors (matching the
iOS TipDmChatIDTests).


* refactor(chat): extract DmChatResolver and add member accessors

Split DM-identity resolution out of MessagingOperations into a dedicated
DmChatResolver interface (generateChatId / getChatId), implemented by a
new DmChatResolverDelegate and composed into RealChatCoordinator via `by`
delegation. MessagingOperations is left focused on operating on an
existing ChatId.

Add MessagingOperations.getOtherMember(chatId), returning the full
ChatMember (profile incl. avatar) with a local-cache-then-network
fallback; getOtherMemberE164 now delegates to it. Back tip DM chat-id
resolution with ChatMemberDao.getChatIdForMember /
ChatMemberDataSource.getChatIdForUser.


* perf(chat): fetch contact and tip DM feeds concurrently

Run the two getDmChatFeed calls in parallel via coroutineScope/async so
combined-feed latency is max(contact, tip) instead of their sum. Failure
semantics are unchanged: a contact-feed failure is fatal, a tip-feed
failure is tolerated.


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

Labels

type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant