docs: getting-started guide and 3 runnable samples#20
Conversation
In-memory walkthrough demonstrating AggregateRoot, IDomainEvent, ICommandDispatcher/IQueryDispatcher wiring, and a synchronous projection update — zero external infra so newcomers can dotnet run it immediately.
02-MultiTenant-WithPostgres demonstrates row-level tenant isolation through Compendium.Multitenancy + the PostgreSQL event store adapter, with a docker-compose for a throw-away Postgres 16 container. 03-AI-WithOpenRouter shows the provider-agnostic IAIProvider against OpenRouter, with an offline stub fallback so the sample still runs in CI and on flights. samples/README.md indexes all three; Samples.sln makes `dotnet build samples/` work for the CI step added in a follow-up commit. Compendium.sln gets the projects under the `samples` solution folder.
Replaces the placeholder docs/getting-started.md with a 10-min walkthrough: prerequisites, NuGet install, define an Order aggregate, wire DI for ICommandDispatcher / IQueryDispatcher, dispatch a command, read a projection, plus links into concepts/, adapters/, and the runnable samples. The snippets match samples/01-QuickStart-OrderAggregate verbatim so readers can switch between page and code without translation.
Adds a Build samples step after the unit-test job so we catch sample breakage before merge. No dotnet run in CI — sample 02 needs Postgres and sample 03 may need an OpenRouter key.
| catch | ||
| { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Pull request overview
Adds a real “Getting Started” walkthrough and introduces three runnable sample projects, plus CI plumbing to ensure samples compile.
Changes:
- Replaces the placeholder
docs/getting-started.mdwith a step-by-step walkthrough (aggregate → CQRS → DI → projection). - Adds three runnable samples under
samples/(in-memory quickstart, multi-tenant Postgres, OpenRouter AI with offline fallback) plus asamples/Samples.sln. - Updates solution/CI wiring to include and build the samples.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
samples/Samples.sln |
Adds a dedicated solution for building all samples via dotnet build samples/. |
samples/README.md |
Documents the sample index and how to build samples. |
samples/Directory.Build.props |
Overrides repo build defaults for samples (not packable, no doc generation). |
samples/03-AI-WithOpenRouter/README.md |
Explains how to run the OpenRouter sample (live vs offline). |
samples/03-AI-WithOpenRouter/Program.cs |
Implements the OpenRouter demo with env-var API key + offline IAIProvider fallback. |
samples/03-AI-WithOpenRouter/AI.WithOpenRouter.csproj |
Adds the AI sample project and its references. |
samples/02-MultiTenant-WithPostgres/docker-compose.yml |
Provides a local Postgres container for the multi-tenant sample. |
samples/02-MultiTenant-WithPostgres/README.md |
Documents the multi-tenant Postgres sample usage and expected output. |
samples/02-MultiTenant-WithPostgres/Program.cs |
Implements the multi-tenant + Postgres sample with tenant-scoped reads/writes. |
samples/02-MultiTenant-WithPostgres/MultiTenant.WithPostgres.csproj |
Adds the multi-tenant sample project and its references. |
samples/01-QuickStart-OrderAggregate/README.md |
Documents the in-memory QuickStart sample. |
samples/01-QuickStart-OrderAggregate/QuickStart.OrderAggregate.csproj |
Adds the QuickStart sample project and its references. |
samples/01-QuickStart-OrderAggregate/Program.cs |
Implements the full in-memory CQRS + projection QuickStart in one file. |
docs/getting-started.md |
Adds the new 10-minute “Getting Started” guide with code snippets. |
Compendium.sln |
Adds sample projects under a samples solution folder. |
.github/workflows/ci.yml |
Adds a CI step to build the samples. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| --collect:"XPlat Code Coverage" | ||
|
|
||
| - name: Build samples | ||
| run: dotnet build samples/ -c Release |
There was a problem hiding this comment.
This step likely rebuilds projects that were already built in the earlier dotnet build Compendium.sln step (the samples are now included in Compendium.sln). If the intent is only to verify dotnet build samples/ works, consider adding --no-restore here (restore already ran) and/or removing samples from Compendium.sln to avoid double-building in CI.
| run: dotnet build samples/ -c Release | |
| run: dotnet build samples/ -c Release --no-restore |
| This page walks you through building a tiny event-sourced service with Compendium: prerequisites, install, define an aggregate, wire DI, dispatch a command, and read a projection. Plan ~10 minutes; longer if it's your first event-sourced .NET app. | ||
|
|
||
| This page will walk you through: | ||
| If you'd rather read working code, jump straight to [`samples/01-QuickStart-OrderAggregate`](https://github.com/sassy-solutions/compendium/tree/main/samples/01-QuickStart-OrderAggregate). Everything below is taken from that sample. |
There was a problem hiding this comment.
The guide says “Everything below is taken from that sample”, but multiple snippets diverge from samples/01-QuickStart-OrderAggregate/Program.cs (e.g., different validation messages and a different PlaceOrderHandler shape). Either update the snippets to match the sample verbatim, or soften the claim (e.g., “adapted from the sample”) so readers aren’t confused when comparing code.
| If you'd rather read working code, jump straight to [`samples/01-QuickStart-OrderAggregate`](https://github.com/sassy-solutions/compendium/tree/main/samples/01-QuickStart-OrderAggregate). Everything below is taken from that sample. | |
| If you'd rather read working code, jump straight to [`samples/01-QuickStart-OrderAggregate`](https://github.com/sassy-solutions/compendium/tree/main/samples/01-QuickStart-OrderAggregate). The examples below are adapted from that sample. |
| public sealed class PlaceOrderHandler(OrderSummaryProjection projection) | ||
| : ICommandHandler<PlaceOrderCommand, Guid> | ||
| { | ||
| public Task<Result<Guid>> HandleAsync(PlaceOrderCommand cmd, CancellationToken ct = default) | ||
| { | ||
| var result = Order.Place(cmd.OrderId, cmd.CustomerId, cmd.TotalAmount); | ||
| if (result.IsFailure) return Task.FromResult(Result.Failure<Guid>(result.Error)); | ||
|
|
||
| projection.Apply(result.Value!.GetUncommittedEvents()); | ||
| return Task.FromResult(Result.Success(result.Value!.Id)); | ||
| } | ||
| } |
There was a problem hiding this comment.
This command/query section introduces a PlaceOrderHandler implementation that doesn’t match the QuickStart sample (the sample also appends events to an in-memory event log). If the docs are meant to mirror the runnable sample, align the handler/projection flow with the sample so readers can copy/paste between them reliably.
| dotnet build samples/ -c Release | ||
| ``` | ||
|
|
||
| CI builds every sample on every PR; running them is left to humans because samples 02 and 03 need real services. |
There was a problem hiding this comment.
CI builds every sample... because samples 02 and 03 need real services is inaccurate now that sample 03 has an offline fallback and can run without external services. Suggest updating this sentence to clarify that only sample 02 requires Docker/PostgreSQL (and sample 03 only needs a real service/API key for live mode).
| CI builds every sample on every PR; running them is left to humans because samples 02 and 03 need real services. | |
| CI builds every sample on every PR; running them is left to humans because sample 02 requires Docker/PostgreSQL, and sample 03 only needs a real service and API key when exercising live mode. |
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" /> |
There was a problem hiding this comment.
Program.cs calls services.AddLogging(), but this project only references Microsoft.Extensions.Logging.Abstractions. The AddLogging extension lives in Microsoft.Extensions.Logging, so this sample may not compile (or may rely on an accidental transitive reference). Add an explicit PackageReference to Microsoft.Extensions.Logging (or remove the AddLogging() call if it’s not needed).
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" /> | |
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" /> | |
| <PackageReference Include="Microsoft.Extensions.Logging" /> |
| Console.Error.WriteLine($""" | ||
| ✗ Could not connect to PostgreSQL at {ConnectionString}. | ||
|
|
||
| Start the bundled container: |
There was a problem hiding this comment.
The connection failure message prints the full PostgreSQL connection string, including the password. Even in a sample, this can encourage unsafe logging patterns and may leak credentials in terminal logs. Consider printing a redacted connection string (or just host/port/db/user) and keep the password out of output.
## Summary PR #23 incorrectly bumped CHANGELOG to `[1.0.0-preview.2] - 2026-04-26` with the quality-sweep entries — but tag `v1.0.0-preview.2` was already cut on **2026-04-25** from a different commit set (PRs #1-7) and **already published to nuget.org** (`Compendium.Core 1.0.0-preview.2` is live). Reusing that version was a mistake. This PR reconciles the CHANGELOG with the published reality and rolls today's work into a new **preview.3**: ### `[1.0.0-preview.2] - 2026-04-25` — rewritten retroactively Now matches the auto-generated GitHub release notes for `v1.0.0-preview.2`: - **Added** — `Compendium.Adapters.Shared` (PII masking utilities, introduced in #3). - **Changed** — Dependabot bumps #4-7, OSS governance scaffolding. - **Security** — workflow `permissions:` block (#1), tenant log sanitization (#2), email removal from adapter logs / GDPR (#3). ### `[1.0.0-preview.3] - 2026-04-26` — new Everything since `v1.0.0-preview.2`: - **Added** — DocFX site (#17), 5 ADRs (#14), public ROADMAP (#15), getting-started guide (#20), 4 concept pages (#21), 8 adapter how-to guides (#22). - **Changed** — CodeQL Default Setup → `extended` query suite. - **Security** — `softprops/action-gh-release` pinned to commit SHA (#16, alert #28 closed). ## Test plan - [ ] CI green on this PR. - [ ] After merge, tag `v1.0.0-preview.3` triggers Release workflow successfully. - [ ] `Compendium.* @ 1.0.0-preview.3` published on nuget.org. - [ ] GitHub Release `v1.0.0-preview.3` created with auto-generated notes. VK: POM-186 (Code Quality sweep parent). Co-authored-by: sacha <sacha@scojhconsult.com>
Summary
POM-182 — turns the placeholder
docs/getting-started.mdinto a 10-minute walkthrough and lands three runnable sample projects undersamples/with aBuild samplesCI step.docs/getting-started.md— prerequisites → NuGet install → define anAggregateRoot<TId>with domain events → wireICommandDispatcher/IQueryDispatcherin DI → dispatch a command → read a projection → next-step links intoconcepts/,adapters/, andsamples/. Snippets match sample 01 verbatim.samples/01-QuickStart-OrderAggregate— pure in-memory Order aggregate, command/query handlers, in-memory projection. Zero infra;dotnet runworks.samples/02-MultiTenant-WithPostgres—Compendium.Multitenancy+Compendium.Adapters.PostgreSQLshowing two tenants sharingevent_storewith row-level isolation, plus adocker-compose.yml(postgres:16-alpineon port 5433). Prints a clear error if Postgres is unreachable.samples/03-AI-WithOpenRouter—Compendium.Adapters.OpenRouterdoing a single chat completion. ReadsOPENROUTER_API_KEY; falls back to an offline stubIAIProviderso the sample also runs in CI and on flights.samples/README.md— index table (Sample / What it shows / How to run / Required setup).Build samplesstep afterTest (unit only), runningdotnet build samples/ -c Release. Nodotnet runin CI.Compendium.slnunder asamplesfolder; a separatesamples/Samples.slnmakesdotnet build samples/work;samples/Directory.Build.propsopts samples out of NuGet packing.Test plan
dotnet build Compendium.sln -c Release— clean (only pre-existing upstream XML-doc warnings)dotnet build samples/ -c Release— cleancd samples/01-QuickStart-OrderAggregate && dotnet run -c Release— prints OrderPlaced + projectioncd samples/03-AI-WithOpenRouter && OPENROUTER_API_KEY= dotnet run -c Release— runs in offline-demo modecd samples/02-MultiTenant-WithPostgres && docker compose up -d && dotnet run -c Release— verify locally with Docker installedbuild-test, the newBuild samplesstep, and CodeQLdocs-deploy.ymlre-runs without DocFX warnings on the newgetting-started.mdCloses POM-182.