feat(backend): edit/repost as new ciphertext version#277
Open
Olorunfemi20 wants to merge 1 commit into
Open
Conversation
|
@Olorunfemi20 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! 🚀 |
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.
Summary
Implements message editing as an append-only operation. An edit never mutates the original row's ciphertext in place; instead it creates a brand-new message carrying fresh ciphertext and per-device envelopes, linked back to the message it replaces through a new nullable self-referential
editsMessageIdFK onmessages. The gateway broadcastsmessage_edited { originalMessageId, newMessageId }so clients can resolve a thread to its newest version and render an "edited" marker.closes #190
Changes
db/schema.ts): addeditsMessageId uuidtomessages, a self-referential FK tomessages.idwithON DELETE SET NULL(deleting an original does not cascade away its edits). Added theeditsMessage/editsself-relation (sharedrelationName) so Drizzle can resolve the self-join. The inferredMessagetype now carries the field automatically.0009_message_edits.sql(+ journal entry):ADD COLUMN edits_message_idand the FK constraint. Standard additive DDL that applies cleanly on top of the existing messages table.socket/messaging.ts): newedit_messagehandler thatoriginalMessageIdand the client-generated newmessageId,senderId === caller),original.editsMessageId ?? original.id) so a chain of edits always collapses to one logical message,messageIdre-acks without inserting again,message_envelopes, then broadcastsnew_message(so recipient devices receive the new ciphertext to decrypt) andmessage_edited.The handler mirrors the existing
send_messageflow (idempotency check, envelope fan-out,message_ack, cache invalidation) to stay consistent with the established patterns.Acceptance criteria
messagesrow is inserted witheditsMessageIdset and newmessage_envelopesrows are written;new_messageis broadcast.message_edited { originalMessageId, newMessageId }is broadcast for clients to supersede the previous version.Testing
src/__tests__/messageEdit.test.tscovers: missing ids, empty content, non-sender rejection, linked-new-message creation withnew_message+message_editedbroadcast, edit-of-an-edit collapsing to the root, and idempotent replay.tsc --noEmitclean, ESLint clean (no new warnings), Prettier clean.