Table of Contents

Class SpamActionRecorder

Namespace
MailFathom.Application.Spam.Actions
Assembly
MailFathom.Application.dll

Writes down the changes an operator asked a spam verdict to produce, as ordinary mutation records.

public sealed class SpamActionRecorder
Inheritance
SpamActionRecorder
Inherited Members

Remarks

This is the whole join between a classification and a mailbox. Nothing here issues an IMAP command, opens a write session, or touches the local row: it opens a durable record per change, and the account's own convergence pass carries each one exactly as it carries a change somebody authored by hand. The local folder and flags change later, because synchronization observed the server — never because this decided they should.

Two rules keep filing from turning into an argument with the mailbox's owner, and they are the reason this type is more than a translation of two switches into two requests. A message already in the destination is not moved into it, and a message this feature has already asked to have filed, which is not in the destination, is left alone entirely: somebody moved it back, which is exactly the correction a false positive is supposed to have, and repeating the filing would undo their decision on every pass. The second rule is read from the durable record rather than from the message, because the record is what survives the message moving — and it holds equally for a filing still in flight, which the same reading makes idempotent.

The caller's posture decides whether the last step happens at all. A dry run takes every decision above and opens no record, which is what lets a run over a whole mailbox report what it would do to somebody's mail before any of it reaches their server. Nothing else about the work differs, so the two postures cannot disagree about one message.

Both changes are written down in one commit, and the \Seen change is written first so it is issued first. On a server without MOVE a relocation gives the message a new UID, and a flag stored afterwards would be aimed at an occurrence the source folder no longer holds.

Where the junk folder is is not decided here. A verdict is one author of a filing mutation among others, so the destination is turned into a folder by MailboxDestinationResolver, which is the single place any author reaches one — including the on-demand resolution a junk folder nothing mirrors needs, that being the destination this feature recommends. Resolving happens before the commit is opened, because it can reach the mail server.

Nothing it reads or reports is mail content. The occurrence, the folder alias, the outcome, and the record identifiers are safe to report; there is no path from here to a subject, an address, or a body.

Constructors

SpamActionRecorder(ISpamActionSettingsReader, ISpamActionOccurrenceReader, IMailboxMutationRecordStore, MailboxDestinationResolver, IAuthoredDeleteEmailDispositionReader, OptimisticConcurrencyRetryPolicy)

Initializes the use case from the decisions it has to read and the record it writes.

Methods

RecordAsync(SpamClassification, SpamActionPosture, CancellationToken)

Asks for whatever the switches say should happen to one classified message.