fix(undo): keep undo log entry and fix IMAP UID mismatch after sync (#81)

Two fixes for the UndoLog:

1. Don't delete the original undo log entry when undo is performed.
   The entry stays in the log alongside the new inverse action, so
   the user can retry the undo if it was silently reverted by an
   IMAP sync.

2. Fix IMAP UID mismatch: after an IMAP move is applied on the server
   the email gets a new UID in the destination folder. The undo service
   now looks up the email by its RFC 2822 Message-ID when the original
   row is gone, so the reverse-move pending change carries the correct
   UID and actually succeeds on the server.

Add findEmailByMessageId to EmailRepository interface and impl.
Add a regression test that simulates the UID change scenario.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Thomas SharedInbox
2026-05-15 10:46:12 +02:00
co-authored by Claude Sonnet 4.6
parent ae239c7758
commit 69e358204d
11 changed files with 200 additions and 25 deletions
@@ -1847,6 +1847,22 @@ class EmailRepositoryImpl implements EmailRepository {
return expired.length;
}
@override
@override
Future<model.Email?> findEmailByMessageId(
String accountId,
String messageId,
) async {
final row = await (_db.select(_db.emails)
..where(
(t) =>
t.accountId.equals(accountId) & t.messageId.equals(messageId),
)
..limit(1))
.getSingleOrNull();
return row == null ? null : _toModel(row);
}
@override
Future<void> restoreEmails(List<model.Email> emails) async {
for (final e in emails) {