Skip to content

Data Access

The Infrastructure layer uses Entity Framework Core with the Npgsql PostgreSQL provider for all database operations. This page covers the AppDbContext, entity configurations, indexes, and migration management.

AppDbContext

AppDbContext is the central EF Core database context, exposing 16 DbSet properties:

DbSetEntityDescription
EmailsEmailInbound email messages
EmailRecipientsEmailRecipientPer-recipient delivery records
EmailAttachmentsEmailAttachmentFile attachments
UsersUserUser accounts
UserEmailAddressesUserEmailAddressAdditional email addresses
SmtpApiKeysSmtpApiKeyAPI keys
LabelsLabelUser labels
EmailLabelsEmailLabelEmail-to-label assignments
EmailFiltersEmailFilterAutomated filter rules
UserPreferencesUserPreferenceUser settings
PushSubscriptionsPushSubscriptionWeb push subscriptions
OutboundEmailsOutboundEmailOutgoing emails
OutboundRecipientsOutboundRecipientPer-recipient outbound status
OutboundAttachmentsOutboundAttachmentOutbound attachments
DeliveryLogsDeliveryLogDelivery attempt records

Configuration Loading

Entity configurations are loaded automatically from the assembly:

csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
}

This scans the Configurations/ directory for all classes implementing IEntityTypeConfiguration<T>.

Entity Configurations

The Data/Configurations/ directory contains 15 Fluent API configuration files that define primary keys, foreign key relationships, indexes, and column constraints for each entity:

Configuration FileEntity
EmailConfiguration.csEmail
EmailRecipientConfiguration.csEmailRecipient
EmailAttachmentConfiguration.csEmailAttachment
UserConfiguration.csUser
UserEmailAddressConfiguration.csUserEmailAddress
SmtpApiKeyConfiguration.csSmtpApiKey
LabelConfiguration.csLabel
EmailLabelConfiguration.csEmailLabel
EmailFilterConfiguration.csEmailFilter
UserPreferenceConfiguration.csUserPreference
PushSubscriptionConfiguration.csPushSubscription
OutboundEmailConfiguration.csOutboundEmail
OutboundRecipientConfiguration.csOutboundRecipient
OutboundAttachmentConfiguration.csOutboundAttachment
DeliveryLogConfiguration.csDeliveryLog

Key Indexes

The following database indexes are critical for query performance:

IndexColumn(s)TypePurpose
User OIDC lookupOidcSubject + OidcIssuerUniqueFast OIDC authentication lookup
API key prefixKeyPrefixNon-uniqueO(1) key lookup by prefix
Email Message-IDMessageIdNon-uniqueDeduplication and threading
EmailRecipient userUserIdNon-uniqueInbox query (all emails for a user)
OutboundEmail queueUserId + StatusNon-uniqueOutbox/sent mail queries and delivery queue

Foreign Key Relationships

Key relationships configured in the Fluent API:

  • Email has many EmailRecipient (cascade delete)
  • Email has many EmailAttachment (cascade delete)
  • User has many SmtpApiKey (cascade delete)
  • User has many Label (cascade delete)
  • User has one UserPreference (cascade delete)
  • OutboundEmail has many OutboundRecipient (cascade delete)
  • OutboundEmail has many OutboundAttachment (cascade delete)
  • OutboundEmail has many DeliveryLog (cascade delete)

Migrations

Four migrations track the database schema evolution:

MigrationDateDescription
InitialCreate2026-01-31Base schema with Users, Emails, Recipients, Attachments, API Keys, Labels, Filters, Preferences, Push Subscriptions
AddApiKeyPrefix2026-02-06Adds KeyPrefix column to SmtpApiKey for efficient prefix-based lookup
AddEmailVerificationToken2026-02-09Adds verification token fields to UserEmailAddress
AddOutboundEmailTables2026-02-09Adds OutboundEmail, OutboundRecipient, OutboundAttachment, and DeliveryLog tables

Creating a New Migration

From the api/ directory:

bash
dotnet ef migrations add MigrationName \
    --project src/Relate.Smtp.Infrastructure \
    --startup-project src/Relate.Smtp.Api

The --startup-project flag is required because the Infrastructure project does not have a Program.cs -- it needs the API project to provide the host and configuration.

Applying Migrations

Manually:

bash
dotnet ef database update \
    --project src/Relate.Smtp.Infrastructure \
    --startup-project src/Relate.Smtp.Api

Auto-Migration in Development

When the API starts in development mode (the ASPNETCORE_ENVIRONMENT is Development), it automatically applies pending migrations on startup. This means you do not need to manually run database update during local development -- just start the API and it will create or update the schema.

In production, migrations should be applied as part of the deployment process, either manually or through a CI/CD pipeline.

Released under the MIT License.