Skip to content

Domain Entities

The Core layer defines 18 entities that model the email domain. This page documents each entity, its fields, relationships, and enumerations.

Screenshot

[Screenshot placeholder: Entity Relationship Diagram]

TODO: Add screenshot of entity relationship diagram showing all entities and their connections

User

The central identity entity representing a user account.

FieldTypeDescription
IdGuidPrimary key
OidcSubjectstringOIDC subject claim (unique with issuer)
OidcIssuerstringOIDC issuer URL
EmailstringPrimary email address
DisplayNamestring?Human-readable display name
CreatedAtDateTimeOffsetAccount creation timestamp
LastLoginAtDateTimeOffset?Most recent login timestamp

Relationships:

  • AdditionalAddresses -- ICollection<UserEmailAddress> -- Additional email addresses
  • ReceivedEmails -- ICollection<EmailRecipient> -- Emails received by this user
  • SmtpApiKeys -- ICollection<SmtpApiKey> -- API keys for protocol authentication
  • Labels -- ICollection<Label> -- Custom labels for organizing email
  • EmailLabels -- ICollection<EmailLabel> -- Label assignments on emails
  • EmailFilters -- ICollection<EmailFilter> -- Automated filter rules
  • Preference -- UserPreference? -- User settings (one-to-one)

Email

Represents an inbound email message stored in the system.

FieldTypeDescription
IdGuidPrimary key
MessageIdstringRFC 5322 Message-ID header (globally unique identifier)
FromAddressstringSender's email address
FromDisplayNamestring?Sender's display name
SubjectstringEmail subject line
TextBodystring?Plain text body
HtmlBodystring?HTML body
ReceivedAtDateTimeOffsetWhen the server received the message
SizeByteslongTotal message size in bytes
InReplyTostring?Message-ID of the message being replied to
Referencesstring?Space-separated list of ancestor Message-IDs for threading
ThreadIdGuid?Thread identifier for conversation grouping
SentByUserIdGuid?User who authenticated to send this email (if sent via SMTP)

Relationships:

  • Recipients -- ICollection<EmailRecipient> -- Delivery records per recipient
  • Attachments -- ICollection<EmailAttachment> -- File attachments
  • EmailLabels -- ICollection<EmailLabel> -- Labels applied to this email

Computed property:

  • HasAttachments -- bool -- Returns true if the email has any attachments

EmailRecipient

Tracks per-recipient delivery and read status. Each email has one EmailRecipient record for each person it was addressed to.

FieldTypeDescription
IdGuidPrimary key
EmailIdGuidForeign key to Email
AddressstringRecipient's email address
DisplayNamestring?Recipient's display name
TypeRecipientTypeWhether recipient was To, Cc, or Bcc
UserIdGuid?Foreign key to User (null if recipient is not a local user)
IsReadboolPer-user read status (allows different users to track read state independently)

Relationships:

  • Email -- Navigation to the parent Email
  • User -- Navigation to the User (if the recipient is a local account)

EmailAttachment

Stores file attachments as binary data alongside the email.

FieldTypeDescription
IdGuidPrimary key
EmailIdGuidForeign key to Email
FileNamestringOriginal filename
ContentTypestringMIME content type (e.g., application/pdf)
SizeByteslongAttachment size in bytes
Contentbyte[]Binary attachment data

EmailLabel

Junction table that links emails to labels, scoped per user. A single email can have different labels for different users.

FieldTypeDescription
IdGuidPrimary key
EmailIdGuidForeign key to Email
UserIdGuidForeign key to User
LabelIdGuidForeign key to Label
AssignedAtDateTimeOffsetWhen the label was applied

Label

User-defined labels for organizing emails, similar to Gmail labels or folder tags.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to the owning User
NamestringLabel display name
ColorstringHex color code (default: #3b82f6, blue)
SortOrderintDisplay order for UI rendering
CreatedAtDateTimeOffsetCreation timestamp

Relationships:

  • User -- Navigation to the owning User
  • EmailLabels -- Emails with this label applied

EmailFilter

Automated rules for organizing incoming email. Filters are evaluated in priority order when new mail arrives.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to User
NamestringHuman-readable filter name
IsEnabledboolWhether the filter is active (default: true)
PriorityintEvaluation order (lower number = higher priority)

Conditions (all nullable -- null means "don't filter on this field"):

FieldTypeDescription
FromAddressContainsstring?Match if sender address contains this substring
SubjectContainsstring?Match if subject contains this substring
BodyContainsstring?Match if body contains this substring
HasAttachmentsbool?Match if email has (or lacks) attachments

Actions (applied when conditions match):

FieldTypeDescription
MarkAsReadboolAutomatically mark the email as read
AssignLabelIdGuid?Apply this label to the email
DeleteboolDelete the email automatically

Metadata:

FieldTypeDescription
CreatedAtDateTimeOffsetWhen the filter was created
LastAppliedAtDateTimeOffset?Last time this filter matched an email
TimesAppliedintTotal number of times this filter has been applied

SmtpApiKey

API keys used for protocol authentication (SMTP, POP3, IMAP) and API access. Keys are stored as BCrypt hashes with a prefix for efficient lookup.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to the owning User
NamestringHuman-readable key name (e.g., "Thunderbird", "iPhone")
KeyHashstringBCrypt hash of the raw API key
KeyPrefixstring?First 12 characters of the raw key for O(1) database lookup
ScopesstringJSON array of permission scopes (e.g., ["smtp","pop3"])
CreatedAtDateTimeOffsetKey creation timestamp
LastUsedAtDateTimeOffset?Most recent usage timestamp
RevokedAtDateTimeOffset?Revocation timestamp (null if active)

The KeyPrefix field enables a two-phase lookup: first find candidate keys by prefix (database index scan), then verify the full key against the BCrypt hash. This avoids iterating through all keys for a user.

UserEmailAddress

Additional email addresses associated with a user account, beyond their primary address. These addresses must be verified before they become active.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to User
AddressstringThe email address
IsVerifiedboolWhether the address has been verified
VerificationTokenstring?Token sent for email verification
VerificationTokenExpiresAtDateTimeOffset?Token expiration time
AddedAtDateTimeOffsetWhen the address was added

OutboundEmail

Represents an email being composed and sent by a user.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to the sending User
FromAddressstringSender's email address
FromDisplayNamestring?Sender's display name
SubjectstringEmail subject
TextBodystring?Plain text body
HtmlBodystring?HTML body
StatusOutboundEmailStatusCurrent delivery status
InReplyTostring?Message-ID being replied to
Referencesstring?Threading references
OriginalEmailIdGuid?Email being replied to or forwarded
MessageIdstring?Generated RFC 5322 Message-ID (set on send)
CreatedAtDateTimeOffsetDraft creation timestamp
QueuedAtDateTimeOffset?When the email entered the delivery queue
SentAtDateTimeOffset?Successful delivery timestamp
RetryCountintNumber of delivery attempts
NextRetryAtDateTimeOffset?Scheduled time for next retry
LastErrorstring?Most recent error message

Relationships:

  • User -- Navigation to the sending User
  • Recipients -- ICollection<OutboundRecipient> -- Per-recipient delivery status
  • Attachments -- ICollection<OutboundAttachment> -- File attachments
  • DeliveryLogs -- ICollection<DeliveryLog> -- Delivery attempt records

OutboundRecipient

Tracks per-recipient delivery status for outbound emails.

FieldTypeDescription
IdGuidPrimary key
OutboundEmailIdGuidForeign key to OutboundEmail
AddressstringRecipient's email address
DisplayNamestring?Recipient's display name
TypeRecipientTypeTo, Cc, or Bcc
StatusOutboundRecipientStatusDelivery status for this recipient
StatusMessagestring?SMTP response or error detail
DeliveredAtDateTimeOffset?Successful delivery timestamp

OutboundAttachment

File attachments for outbound emails.

FieldTypeDescription
IdGuidPrimary key
OutboundEmailIdGuidForeign key to OutboundEmail
FileNamestringOriginal filename
ContentTypestringMIME content type
SizeByteslongAttachment size in bytes
Contentbyte[]Binary attachment data

UserPreference

Per-user settings for display and notification preferences.

FieldTypeDefaultDescription
IdGuidPrimary key
UserIdGuidForeign key to User
Themestring"system"UI theme (light, dark, system)
DisplayDensitystring"comfortable"Layout density (compact, comfortable, spacious)
EmailsPerPageint20Pagination size
DefaultSortstring"receivedAt-desc"Default sort order
ShowPreviewbooltrueShow email preview in list
GroupByDateboolfalseGroup emails by date
DesktopNotificationsboolfalseEnable desktop push notifications
EmailDigestboolfalseEnable periodic email digest
DigestFrequencystring"daily"Digest frequency (daily, weekly)
DigestTimeTimeOnly09:00Time of day to send digest
UpdatedAtDateTimeOffsetLast modification timestamp

PushSubscription

Web push notification subscriptions using the VAPID protocol.

FieldTypeDescription
IdGuidPrimary key
UserIdGuidForeign key to User
EndpointstringPush service endpoint URL
P256dhKeystringClient public key (P-256 Diffie-Hellman)
AuthKeystringAuthentication secret
UserAgentstringBrowser/client user agent string
CreatedAtDateTimeOffsetSubscription creation timestamp
LastUsedAtDateTimeOffset?Last notification sent timestamp

DeliveryLog

Records each delivery attempt for outbound emails, providing an audit trail for troubleshooting.

FieldTypeDescription
IdGuidPrimary key
OutboundEmailIdGuidForeign key to OutboundEmail
RecipientIdGuid?Foreign key to OutboundRecipient
RecipientAddressstringRecipient email address
MxHoststring?MX host that was contacted
SmtpStatusCodeint?SMTP response code (e.g., 250, 550)
SmtpResponsestring?Full SMTP response text
SuccessboolWhether the attempt succeeded
ErrorMessagestring?Error description on failure
AttemptNumberintWhich retry attempt this was
AttemptedAtDateTimeOffsetWhen the attempt was made
DurationTimeSpan?How long the attempt took

Enumerations

RecipientType

csharp
public enum RecipientType { To, Cc, Bcc }

OutboundEmailStatus

csharp
public enum OutboundEmailStatus
{
    Draft,           // Being composed
    Queued,          // Ready for delivery
    Sending,         // Delivery in progress
    Sent,            // All recipients delivered
    PartialFailure,  // Some recipients failed
    Failed           // All recipients failed, max retries exceeded
}

OutboundRecipientStatus

csharp
public enum OutboundRecipientStatus
{
    Pending,   // Not yet attempted
    Sending,   // Delivery in progress
    Sent,      // Successfully delivered
    Failed,    // Permanently failed
    Deferred   // Temporarily failed, will retry
}

Released under the MIT License.