Skip to content

sassy-solutions/compendium

Compendium

A pragmatic .NET framework for building event-sourced, multi-tenant SaaS applications.

CI NuGet License: MIT .NET 9

Compendium is the framework that powers Nexus, Sassy Solutions' multi-tenant platform engineering product. It distills years of building event-sourced SaaS into a small set of focused packages: DDD primitives, CQRS handlers, an event store, multi-tenancy, and ready-to-use adapters for PostgreSQL, Redis, Zitadel, and more.

Why Compendium?

  • Zero-dependency Core — Pure DDD primitives (AggregateRoot<TId>, ValueObject, Result<T>, Error) with no external dependencies beyond the .NET BCL.
  • CQRS + Event Sourcing built-in — Command/query dispatchers, event store interfaces, and a PostgreSQL adapter wired out of the box.
  • Sagas, two flavorsProcessManager<TState> for DDD-style orchestration sagas and IHandle<TEvent> for event-driven choreography sagas, each clearly named so you don't have to guess which pattern you're using. See docs/sagas.md.
  • Multi-tenancy native — Tenant context, resolution, and scoping baked into the primitives — not bolted on.
  • Result pattern everywhere — No control-flow exceptions. Every fallible operation returns Result<T> with structured Error values.
  • Modular adapters — Pick only what you need: eighteen production adapters across persistence (Postgres, Redis, pgvector, Qdrant, Pinecone, S3-compatible), identity (Zitadel), billing (Stripe, LemonSqueezy), email (Listmonk), and AI (OpenRouter, OpenAI, Anthropic, Gemini, Azure OpenAI, AWS Bedrock, LiteLLM, Ollama). See Adapters. Each ships its own repo, NuGet package, and release cadence per ADR-0006.
  • Battle-tested in production — Powers Nexus, a multi-tenant platform engineering product.

Adapters

Each public adapter lives in its own repository under sassy-solutions/compendium-adapter-* and is released independently per ADR-0006. The framework defines the ports (IEventStore, IAIProvider, IVectorStore, IBillingProvider, …); adapters provide concrete implementations.

Official adapters

Domain Adapter Repo NuGet
Persistence — event store PostgreSQL compendium-adapter-postgresql NuGet
Persistence — cache & idempotency Redis compendium-adapter-redis NuGet
Persistence — vector store pgvector compendium-adapter-pgvector NuGet
Persistence — vector store Qdrant compendium-adapter-qdrant NuGet
Persistence — vector store Pinecone (managed) compendium-adapter-pinecone NuGet
Persistence — object storage S3-compatible (AWS / R2 / MinIO / B2 / Wasabi) compendium-adapter-s3 NuGet
Identity Zitadel compendium-adapter-zitadel NuGet
Billing Stripe compendium-adapter-stripe NuGet
Billing LemonSqueezy compendium-adapter-lemonsqueezy NuGet
Email Listmonk compendium-adapter-listmonk NuGet
AI — gateway OpenRouter compendium-adapter-openrouter NuGet
AI — direct provider OpenAI compendium-adapter-openai NuGet
AI — direct provider Anthropic compendium-adapter-anthropic NuGet
AI — direct provider Gemini (Google) compendium-adapter-gemini NuGet
AI — Azure-hosted Azure OpenAI (Entra ID) compendium-adapter-azure-openai NuGet
AI — AWS gateway Bedrock (Claude / Llama / Mistral / Nova) compendium-adapter-bedrock NuGet
AI — gateway LiteLLM (self-hostable) compendium-adapter-litellm NuGet
AI — local Ollama compendium-adapter-ollama NuGet

The thin ASP.NET Core glue (Compendium.Adapters.AspNetCore — middleware, ProblemDetails, multi-tenancy HTTP resolution) stays in the framework monorepo since it has no external SDK and evolves lock-step with Compendium.Application.

Verified third-party adapters

None yet. Maintainers of community adapters that pass a security & convention review (namespacing, tenancy, Result-pattern, test coverage) can open a PR adding a row here.

Writing your own adapter

Use the template-compendium-adapter-dotnet GitHub template — it ships with the test stack, CI gate, MinVer versioning, and NuGet publishing wired in. See docs/adapters/external.md for the writing guide.

Quick start

Install the packages you need:

dotnet add package Compendium.Core
dotnet add package Compendium.Application
dotnet add package Compendium.Adapters.PostgreSQL

Define an event-sourced aggregate:

using Compendium.Core.Domain.Primitives;
using Compendium.Core.Results;

public sealed class OrderAggregate : AggregateRoot<OrderId>
{
    private OrderStatus _status;
    private decimal _amount;

    private OrderAggregate(OrderId id) : base(id) { }

    public static Result<OrderAggregate> Create(CustomerId customerId, decimal amount)
    {
        if (amount <= 0)
            return Result.Failure<OrderAggregate>(
                Error.Validation("Order.Amount.Invalid", "Amount must be positive"));

        var order = new OrderAggregate(OrderId.New());
        order.AddDomainEvent(new OrderCreated(order.Id, customerId, amount));
        return Result.Success(order);
    }

    public void Apply(OrderCreated @event)
    {
        _status = OrderStatus.Pending;
        _amount = @event.Amount;
    }
}

Wire it up in Program.cs:

using Compendium.Application.CQRS;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Register Compendium CQRS dispatchers (command/query handlers are resolved via IServiceProvider).
builder.Services.AddScoped<ICommandDispatcher, CommandDispatcher>();
builder.Services.AddScoped<IQueryDispatcher, QueryDispatcher>();

// Register your command/query handlers, then wire the PostgreSQL event store adapter
// using the options published by Compendium.Adapters.PostgreSQL.

var app = builder.Build();

Architecture

Core (zero deps) → Abstractions → Application → Infrastructure → Adapters
                                       ↓
                              Multitenancy (cross-cutting)
  • Core — Domain primitives with no external dependencies.
  • Abstractions — Ports (interfaces) for infrastructure concerns: identity, billing, email, AI.
  • Application — CQRS orchestration: command/query handlers, dispatchers.
  • Infrastructure — Generic infrastructure concerns: projections, outbox, caching.
  • Adapters — Concrete integrations with external systems.
  • Multitenancy — Tenant resolution and scoping, usable across all layers.

Packages

These are the framework packages that ship from this repository. Adapter packages live in their own repositories — see Adapters above.

Package Purpose NuGet
Compendium.Core DDD primitives, Result pattern, domain events NuGet
Compendium.Abstractions Shared infrastructure port interfaces NuGet
Compendium.Abstractions.AI AI provider contracts (incl. IAIProvider, IEmbeddingProvider, IReranker, agent loop) NuGet
Compendium.Abstractions.Billing Billing provider contracts NuGet
Compendium.Abstractions.Email Email provider contracts NuGet
Compendium.Abstractions.Identity Identity provider contracts NuGet
Compendium.Abstractions.VectorStore Vector store port (IVectorStore) NuGet
Compendium.Abstractions.Search Search port (ISearchIndex) NuGet
Compendium.Application CQRS dispatchers, handlers, pipelines NuGet
Compendium.Infrastructure Projections, outbox, infrastructure building blocks NuGet
Compendium.Multitenancy Tenant context, resolution, and scoping NuGet
Compendium.Adapters.AspNetCore ASP.NET Core glue (middleware, ProblemDetails, multi-tenancy HTTP resolution) NuGet
Compendium.Testing Test helpers, fakes, TestContainers fixtures NuGet

Documentation

The full documentation site is being built at sassy-solutions.github.io/compendium (DocFX-powered). In the meantime:

  • ROADMAP.md — themes, what's next, and what's out of scope
  • CONTRIBUTING.md — build, test, conventions
  • docs/adr/ — architecture decision records
  • Source under src/ and the Nexus consumer code for end-to-end examples

Who's using Compendium?

  • Nexus — Multi-tenant platform engineering by Sassy Solutions.

Using Compendium in your project? Open a PR to add yourself to this list.

Contributing

Contributions, issues, and feedback are welcome. See CONTRIBUTING.md for guidelines on code style, commit conventions, and the development loop.

License

MIT © 2026 Sassy Solutions. See LICENSE for details.

Packages

 
 
 

Contributors