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.
| Adapter | Port | What is behind it |
|---|---|---|
| Database | IXxxRepository, IXxxApiQueryRepository, IUnitOfWork | EF Core and PostgreSQL: BlouppyDbContext, the repositories, the migrations, the seeding |
| Caching | IResponseCache | Redis through HybridCache |
| FileStorage | IFileStorage | Local disk, or any S3-compatible bucket, chosen by FileStorage:Provider |
| FileExport | ICsvExporter, IArchiveBuilder | CSV and ZIP generation |
IEmailSender | SMTP and templating; MailPit in development | |
| RealTime | IServerEventPublisher | The SSE stream (see Real time) |
| Messaging | IIntegrationEventPublisher<T> | Wolverine and RabbitMQ (see Events and messaging) |
| Webhooks | IWebhookSender | Signed HTTP requests, refused for addresses inside the network |
| Scheduling | — | Quartz.NET and its jobs |
| Llm | ILlmClient | Anthropic, or NotConfiguredLlmClient until a key is set |
| Security | ISecretProtector | ASP.NET Core Data Protection, for secrets stored encrypted |
| Dns | IDnsTxtResolver | TXT 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.