https://github.com/sassy-solutions/compendium
A pragmatic .NET framework for event-sourced multi-tenant SaaS applications
https://github.com/sassy-solutions/compendium
cqrs csharp dotnet event-sourcing hexagonal-architecture multi-tenancy oss saas
Last synced: about 2 months ago
JSON representation
A pragmatic .NET framework for event-sourced multi-tenant SaaS applications
- Host: GitHub
- URL: https://github.com/sassy-solutions/compendium
- Owner: sassy-solutions
- License: mit
- Created: 2026-04-24T10:12:22.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-02T05:54:07.000Z (about 2 months ago)
- Last Synced: 2026-05-02T07:28:44.376Z (about 2 months ago)
- Topics: cqrs, csharp, dotnet, event-sourcing, hexagonal-architecture, multi-tenancy, oss, saas
- Language: C#
- Homepage: https://github.com/sassy-solutions/compendium
- Size: 8.43 MB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Compendium
> A pragmatic .NET framework for building event-sourced, multi-tenant SaaS applications.
[](https://github.com/sassy-solutions/compendium/actions/workflows/ci.yml)
[](https://www.nuget.org/packages/Compendium.Core/)
[](LICENSE)
[](https://dotnet.microsoft.com/)
Compendium is the framework that powers [Nexus](https://sassy.solutions), 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`, `ValueObject`, `Result`, `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 flavors** — `ProcessManager` for DDD-style orchestration sagas and `IHandle` for event-driven choreography sagas, each clearly named so you don't have to guess which pattern you're using. See [docs/sagas.md](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` with structured `Error` values.
- **Modular adapters** — Pick only what you need: PostgreSQL, Redis, Zitadel, Listmonk, LemonSqueezy, OpenRouter, ASP.NET Core.
- **Battle-tested in production** — Powers Nexus, a multi-tenant platform engineering product.
## Quick start
Install the packages you need:
```bash
dotnet add package Compendium.Core
dotnet add package Compendium.Application
dotnet add package Compendium.Adapters.PostgreSQL
```
Define an event-sourced aggregate:
```csharp
using Compendium.Core.Domain.Primitives;
using Compendium.Core.Results;
public sealed class OrderAggregate : AggregateRoot
{
private OrderStatus _status;
private decimal _amount;
private OrderAggregate(OrderId id) : base(id) { }
public static Result Create(CustomerId customerId, decimal amount)
{
if (amount <= 0)
return Result.Failure(
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`:
```csharp
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();
builder.Services.AddScoped();
// 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
| Package | Purpose | NuGet |
|---------|---------|-------|
| `Compendium.Core` | DDD primitives, Result pattern, domain events | [](https://www.nuget.org/packages/Compendium.Core/) |
| `Compendium.Abstractions` | Shared infrastructure port interfaces | [](https://www.nuget.org/packages/Compendium.Abstractions/) |
| `Compendium.Abstractions.AI` | AI provider contracts | [](https://www.nuget.org/packages/Compendium.Abstractions.AI/) |
| `Compendium.Abstractions.Billing` | Billing provider contracts | [](https://www.nuget.org/packages/Compendium.Abstractions.Billing/) |
| `Compendium.Abstractions.Email` | Email provider contracts | [](https://www.nuget.org/packages/Compendium.Abstractions.Email/) |
| `Compendium.Abstractions.Identity` | Identity provider contracts | [](https://www.nuget.org/packages/Compendium.Abstractions.Identity/) |
| `Compendium.Application` | CQRS dispatchers, handlers, pipelines | [](https://www.nuget.org/packages/Compendium.Application/) |
| `Compendium.Infrastructure` | Projections, outbox, infrastructure building blocks | [](https://www.nuget.org/packages/Compendium.Infrastructure/) |
| `Compendium.Multitenancy` | Tenant context, resolution, and scoping | [](https://www.nuget.org/packages/Compendium.Multitenancy/) |
| `Compendium.Testing` | Test helpers, fakes, TestContainers fixtures | [](https://www.nuget.org/packages/Compendium.Testing/) |
| `Compendium.Extensions.ExternalAdapters` | Unified registration for external adapters | [](https://www.nuget.org/packages/Compendium.Extensions.ExternalAdapters/) |
| `Compendium.Adapters.AspNetCore` | ASP.NET Core integration (middleware, auth, problem details) | [](https://www.nuget.org/packages/Compendium.Adapters.AspNetCore/) |
| `Compendium.Adapters.PostgreSQL` | PostgreSQL event store & repositories | [](https://www.nuget.org/packages/Compendium.Adapters.PostgreSQL/) |
| `Compendium.Adapters.Redis` | Redis cache adapter | [](https://www.nuget.org/packages/Compendium.Adapters.Redis/) |
| `Compendium.Adapters.Zitadel` | Zitadel OIDC identity adapter | [](https://www.nuget.org/packages/Compendium.Adapters.Zitadel/) |
| `Compendium.Adapters.Listmonk` | Listmonk email adapter | [](https://www.nuget.org/packages/Compendium.Adapters.Listmonk/) |
| `Compendium.Adapters.LemonSqueezy` | LemonSqueezy billing adapter | [](https://www.nuget.org/packages/Compendium.Adapters.LemonSqueezy/) |
| `Compendium.Adapters.OpenRouter` | OpenRouter AI provider adapter | [](https://www.nuget.org/packages/Compendium.Adapters.OpenRouter/) |
## Documentation
The full documentation site is being built at [sassy-solutions.github.io/compendium](https://sassy-solutions.github.io/compendium/) (DocFX-powered). In the meantime:
- [ROADMAP.md](ROADMAP.md) — themes, what's next, and what's out of scope
- [CONTRIBUTING.md](CONTRIBUTING.md) — build, test, conventions
- [docs/adr/](docs/adr/) — architecture decision records
- Source under `src/` and the Nexus consumer code for end-to-end examples
## Who's using Compendium?
- **[Nexus](https://sassy.solutions)** — 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](CONTRIBUTING.md) for guidelines on code style, commit conventions, and the development loop.
## License
MIT © 2026 Sassy Solutions. See [LICENSE](LICENSE) for details.