#24: make draft autosave replace the previous draft

The autosave I had just added appended a new message on every debounce, so a
few minutes of typing would have left the Drafts folder holding a dozen copies
of the same unfinished mail. Caught before deploying.

The composer now returns the stored UID and sends it back as replace_uid on
the next save; the use case expunges the superseded draft, but only after the
replacement has committed, so a failure leaves the older draft in place rather
than losing both. Expunge is a soft delete matching the expunged_at column the
schema already uses, and it locates the message by mailbox as well as UID so a
caller cannot delete someone else's mail by guessing a number.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5 committed 2026-08-02 20:01:12 -03:00
1 parent 707e6ae80e
commit 0fcdd15b58
6 files changed
+218 -6

No files matched your search

@@ -61,4 +61,6 @@ type WebmailRepository interface {
GetMessageBlob(ctx context.Context, mailboxID, folderName string, uid uint32) (uuid.UUID, error)
// MarkSeen records that the user opened the message.
MarkSeen(ctx context.Context, mailboxID, folderName string, uid uint32, seen bool) error
// Expunge soft-deletes one message, keeping the folder counters in step.
Expunge(ctx context.Context, mailboxID, folderName string, uid uint32) error
}