BrewUpErp is an end‑to‑end sample ERP built to demonstrate
- Domain‑Driven Design (DDD)
- Modular / bounded‑context architecture
- Functional‑style domain modelling
- Clean, testable application layers
The solution is intentionally realistic but still small enough to study. It consists of:
- BrewApi – backend HTTP API
- BrewSpa – Blazor web front‑end
- BrewApp – .NET MAUI mobile application
Note: this repository is a work in progress. Expect breaking changes and incomplete features, especially in less‑used flows.
High‑level folder layout:
src/BrewApi– backend API and domain implementationBrewUp.Rest– ASP.NET Core Web API hostBrewUp.Shared– shared abstractions, value objects, helpersMasterData/*– Master Data bounded context (domain, facade, read model, infrastructure, shared kernel)Sales/*– Sales bounded context (domain, facade, read model, infrastructure, shared kernel, tests)BrewUp.Infrastructure– cross‑cutting infrastructure (MongoDB, RabbitMQ, logging, etc.)BrewUp.*.Tests– backend/unit/architecture tests
BrewSpa– Blazor front‑endBrewSpa– main Blazor app (layouts, pages, wwwroot)BrewSpa.Shared– shared client models and helpersBrewSpa.Shared.Components,Dashboards,MasterData,Sales– modularized UI feature areas
BrewApp– .NET MAUI mobile solutionsrc/*– MAUI shell, shared UI/core libraries, feature modulestests/*– mobile/UI tests
BrewErp– Bruno API contracts & examples (e.g.GetCustomers.bru)docker–docker-compose.ymland helper script for local infrastructureDocs– sample API payloads and documentation fragments
The ERP is decomposed into modules that map to bounded contexts:
- MasterData – core catalog and reference data (e.g., customers, products)
- Sales – sales orders and related workflows
- (Additional contexts like Purchase/Warehouse are being modelled incrementally.)
Each context follows a similar layout:
*.Domain– Aggregates, value objects, domain events, domain services*.SharedKernel– types shared only inside the bounded context*.Infrastructure– persistence and integration (MongoDB, messaging, etc.)*.ReadModel– denormalized read models and projections*.Facade– application services / use‑case orchestration
This structure keeps the domain model independent from infrastructure and UI, and encourages explicit module boundaries.
- Runtime: .NET (currently targeting
net10.0for the API) - API: ASP.NET Core Web API
- OpenAPI/Swagger via Swashbuckle and Scalar
- Observability with OpenTelemetry and Azure Monitor exporter
- Logging with Serilog (console + file)
- Architecture:
- DDD with explicit domain and application layers
- Modular monolith style, grouped by bounded context
- CQRS and message‑driven patterns inspired by Muflone
- Persistence & Messaging:
- MongoDB (document storage)
- RabbitMQ (message bus)
- Web UI: Blazor (server or WebAssembly, depending on configuration)
- Mobile: .NET MAUI (Android / iOS / Windows)
Check individual
*.csprojfiles anddocker/docker-compose.ymlfor exact framework versions and external dependencies.
- .NET SDK compatible with the target frameworks
- For the backend:
.NET 10(asnet10.0is targeted)
- For the backend:
- Docker Desktop (for local MongoDB, RabbitMQ, and other backing services)
- A recent IDE: Visual Studio, Rider, or VS Code with C# support
Optional (but recommended):
gitfor source control- A modern browser for Blazor debugging tools
The docker folder contains a docker-compose.yml and helper script.
From the repository root:
cd docker
./run-docker-compose.bat # on Windows PowerShell / CMDThis typically starts the required supporting services (MongoDB,
RabbitMQ, etc.). Inspect docker-compose.yml for details and port
configuration.
The main API host is in src/BrewApi/BrewUp.Rest.
From the repository root:
cd src/BrewApi
dotnet run --project BrewUp.Rest/BrewUp.Rest.csprojBy default the API will expose:
- HTTP endpoints for each bounded context (e.g., MasterData, Sales)
- OpenAPI/Swagger UI (and/or Scalar UI) for interactive exploration
Configuration is managed via appsettings.json and environment‑specific
files such as appsettings.Development.json inside BrewUp.Rest.
The Blazor web app lives under BrewSpa/BrewSpa.
From the repository root:
cd BrewSpa/BrewSpa
dotnet runThen navigate to the URL printed in the console (commonly
https://localhost:xxxx).
The SPA consumes the BrewApi endpoints and is structured into feature‑specific modules (Dashboards, MasterData, Sales, etc.), plus shared components and models.
The .NET MAUI application is under BrewApp.
Typical workflow:
- Open
BrewApp/BrewUpErp.Mobile.slnxin Visual Studio or Rider. - Select the desired target (Android, iOS, Windows).
- Build and run from the IDE.
The mobile app uses a shell navigation structure and references
feature modules (MasterData, Sales, Warehouse, etc.) and shared
libraries (BrewApp.Shared.Core, BrewApp.Shared.UI).
The solution includes several test projects under src/BrewApi and
BrewApp/tests.
Examples:
src/BrewApi/BrewUp.MasterData.Testssrc/BrewApi/BrewUp.Rest.Testssrc/BrewApi/Sales/BrewUp.Sales.Tests
Run all backend tests from the repository root with:
cd src/BrewApi
dotnet testAdditional mobile/UI tests can be run from the appropriate tests
projects under BrewApp using your IDE or dotnet test.
- Domain layer
- Encapsulates business rules, invariants, and ubiquitous language.
- Uses aggregates, value objects, and domain events.
- Pure C# code without infrastructure dependencies.
- Application / Facade layer
- Implements use cases and orchestrates domain operations.
- Coordinates between domain, read models, and infrastructure.
- Infrastructure layer
- Persistence implementations, messaging, and external services.
- Implementations of repositories, event stores, message publishers.
- Each bounded context lives in its own folder tree and assemblies.
- Cross‑context communication goes through explicit contracts and messages rather than shared tables or implicit coupling.
- Shared code is pushed either into
BrewUp.Sharedfor truly cross‑cutting concerns, or*.SharedKernelfor types shared inside a single context.
While written in C#, many domain and application components are built with a functional mindset:
- Emphasis on immutable value objects
- Clear input/output contracts for use cases
- Reduced side effects, with IO pushed to the infrastructure layer
This repository is under active development. Some planned or ongoing areas include:
- Completing end‑to‑end flows for all modules (not only Sales/MasterData)
- Expanding test coverage (unit, integration, and contract tests)
- Hardening observability (distributed tracing, metrics dashboards)
- Improving documentation for each bounded context and module
Contributions in the form of issue reports, ideas, and pull requests are welcome, but please treat this as a learning/reference project rather than production‑ready software.
See the LICENSE file at the root of the repository for the full
license text.