Skip to content

feat: delivery pipeline — validate, persist, resolve devices, push envelopes (#194)#272

Open
Tijesunimi004 wants to merge 1 commit into
codebestia:mainfrom
Tijesunimi004:feat/delivery-pipeline
Open

feat: delivery pipeline — validate, persist, resolve devices, push envelopes (#194)#272
Tijesunimi004 wants to merge 1 commit into
codebestia:mainfrom
Tijesunimi004:feat/delivery-pipeline

Conversation

@Tijesunimi004

@Tijesunimi004 Tijesunimi004 commented Jun 28, 2026

Copy link
Copy Markdown

Closes #194


What

Implements the delivery pipeline described in #194 as the single path all messages take after being stored.

Changes

src/services/deliveryPipeline.ts (new)

Encapsulates the full post-persist delivery flow:

  1. Re-fetches members from conversation_members — membership is re-validated against the DB, not inferred from Socket.IO room occupancy.
  2. Resolves active devices for those members (revokedAt IS NULL).
  3. Loads the persisted envelopes for this message, filtered to those active devices.
  4. Emits message_envelope to device:{deviceId} for each device that has an envelope — each device receives exactly its own ciphertext.
  5. Emits new_message to the conversation room as a stripped notification (no ciphertext) so clients update unread counts and UI.

src/index.ts

Sockets now join device:{deviceId} on connect, enabling per-device targeting via io.to('device:...'). This works across horizontally-scaled instances because the Redis adapter routes room emissions through pub/sub.

src/socket/messaging.ts

Replaces the single io.to(conversationId).emit('new_message', message) call with await deliverMessage(io, message, conversationId). The message and all envelopes are committed to the database before this call — persist-before-deliver is guaranteed by control flow.

src/__tests__/deliveryPipeline.test.ts (new)

Unit tests covering:

  • Per-device envelope emission
  • new_message room notification without ciphertext
  • Devices with no envelope are skipped
  • Fallback to room notification when no active devices exist
  • Early return when conversation has no members
  • Independent delivery to multiple devices

Acceptance criteria

  • Storage always precedes delivery: deliverMessage is called only after db.insert for both messages and messageEnvelopes completes.
  • Each active recipient device receives exactly its envelope: the pipeline iterates active devices and emits only to device:{deviceId}, not to the conversation room.
  • Membership re-validated against conversation_members even when rooms are used: step 1 of deliverMessage queries the table directly.

Adds a single code path all messages take after persist:
1. Re-validates members against conversation_members (not room state).
2. Resolves active (non-revoked) devices for every member.
3. Loads persisted envelopes from the database.
4. Emits message_envelope to device:{id} room with each device's ciphertext.
5. Emits new_message to the conversation room as a UI notification.

Each socket joins its device:{deviceId} room on connect, so the Redis
adapter routes per-device emissions correctly across instances.

Persist-before-deliver is enforced: deliverMessage is called only after
the message row and all envelope rows have been committed.
Copilot AI review requested due to automatic review settings June 28, 2026 19:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@Tijesunimi004 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Delivery pipeline: validate → persist → resolve devices → push

2 participants