Other adapters

Every technical concern is a Blouppy.Infrastructure.<Concern> project implementing a port declared in its .Abstractions twin. A domain references the port; only the composition root (Blouppy.Web) references the adapter.

AdapterPortWhat is behind it
DatabaseIXxxRepository, IXxxApiQueryRepository, IUnitOfWorkEF Core and PostgreSQL: BlouppyDbContext, the repositories, the migrations, the seeding
CachingIResponseCacheRedis through HybridCache
FileStorageIFileStorageLocal disk, or any S3-compatible bucket, chosen by FileStorage:Provider
FileExportICsvExporter, IArchiveBuilderCSV and ZIP generation
EmailIEmailSenderSMTP and templating; MailPit in development
RealTimeIServerEventPublisherThe SSE stream (see Real time)
MessagingIIntegrationEventPublisher<T>Wolverine and RabbitMQ (see Events and messaging)
WebhooksIWebhookSenderSigned HTTP requests, refused for addresses inside the network
Scheduling—Quartz.NET and its jobs
LlmILlmClientAnthropic, or NotConfiguredLlmClient until a key is set
SecurityISecretProtectorASP.NET Core Data Protection, for secrets stored encrypted
DnsIDnsTxtResolverTXT lookups, for the identity host's verified domains

The response cache

IResponseCache sits in front of the read side, backed by Redis so that every replica agrees. It is invalidated by moving a version stamp forward rather than by deleting keys: one write is immediately true everywhere, and a cold cache means a slow first request, never a wrong answer. The plumbing ships with no authenticated route using it yet — your product's first reference list is the natural candidate.

Scheduled jobs

Every recurring job is a Quartz.NET IJob in Blouppy.Infrastructure.Scheduling/Jobs/, registered with its trigger in AddScheduling. The store is clustered, in the quartz schema, so a job runs once across replicas. The Starter's jobs sweep webhook deliveries due for a retry and purge what has outlived its retention: webhook deliveries, audit entries, AI usage records, expired data exports and old notifications.

Entity configuration stays out of the model

EF Core configurations are IEntityTypeConfiguration<T> classes in Blouppy.Infrastructure.Database/<Feature>/, discovered automatically. Domain classes carry no EF attribute: that is what keeps .Models free of any dependency.

Adding an adapter

A new external system — a search engine, a payment provider, an SMS gateway — is a new pair of projects: the port in Blouppy.Infrastructure.<Concern>.Abstractions, the adapter in Blouppy.Infrastructure.<Concern>, and a row in InfrastructureBoundaryTests saying which projects it may reference. The build fails until that row exists.