Skip to content

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

Merged
codebestia merged 3 commits into
codebestia:mainfrom
Tijesunimi004:feat/delivery-pipeline
Jun 29, 2026
Merged

feat: delivery pipeline — validate, persist, resolve devices, push envelopes (#194)#272
codebestia merged 3 commits into
codebestia:mainfrom
Tijesunimi004:feat/delivery-pipeline

Conversation

@Tijesunimi004

@Tijesunimi004 Tijesunimi004 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

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

@codebestia

Copy link
Copy Markdown
Owner

@Tijesunimi004
Please fix the CI.
Ensure to pull from the remote branch first before proceeding.

@codebestia codebestia left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

LGTM!
Thank you for your contribution.

@codebestia codebestia merged commit b7a4b43 into codebestia:main Jun 29, 2026
2 checks passed
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

3 participants