Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

922 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Wallow

Wallow

A .NET modular monolith base platform for building multi-tenant SaaS products.

Fork it. Add your domain modules. Deploy.

Pre-release: Wallow has not been deployed outside local development yet, and breaking changes to main are expected.

CI .NET PostgreSQL Tests Coverage License Docker


Why Wallow?

  • Multi-tenancy from day one -- tenant isolation, per-tenant config, and data partitioning built into the architecture so you ship product features, not plumbing
  • Fork-first architecture -- merge drivers preserve your branding, config, and customizations when pulling upstream improvements
  • Batteries-included infrastructure -- observability, background jobs, file storage, email, caching, and CI/CD preconfigured and tested
  • Comprehensive test coverage -- the .NET suites (unit, integration, architecture) plus per-app Playwright E2E and Vitest browser-mode suites across the pnpm workspace

What is Wallow?

Wallow provides the cross-cutting infrastructure every SaaS product needs out of the box -- identity, notifications, announcements, file storage, API keys, and multi-tenant data isolation. You write the business logic.

The intended workflow is to fork this repo and build your product on top. Shared infrastructure improvements can be pulled from upstream into forks without conflicts.

New here? Start with the Fork Guide or the Developer Guide.

Quick Start

Prerequisites

1. Install workspace dependencies

pnpm install

2. Start infrastructure

pnpm backend:infra                        # docker compose up -d; backend:infra:down to stop

Starts PostgreSQL, Valkey, GarageHQ (S3), Mailpit, and Grafana.

3. Run the apps

The frontends are React (TanStack Start) apps; the .NET Aspire host orchestrates the API, both React apps, migrations, and the seeder together:

pnpm backend                              # Aspire AppHost: API + Auth + Web + Migration + Seeder

Or run the pieces individually:

dotnet run --project api/src/Wallow.Api                       # API   → http://localhost:5001
pnpm --filter @bc-solutions-coder/wallow-web dev              # Web   → http://localhost:3000
pnpm --filter @bc-solutions-coder/wallow-auth dev             # Auth  → http://localhost:3002

4. Run tests

./scripts/run-tests.sh                    # backend fast suites (Category=Integration excluded)
./scripts/run-tests.sh all                # the same, plus the integration suites (needs Docker)
./scripts/run-tests.sh identity           # single backend module
pnpm check                                # the frontend quality gate (format, lint, build, typecheck, test)

See Testing for coverage, E2E, and CI details.

Architecture

A modular monolith where each module is an autonomous bounded context following Clean Architecture. Modules communicate through Wolverine in-memory events via Shared.Contracts -- never direct references. Each module owns its own PostgreSQL schema.

api/
└── src/
    ├── Wallow.Api/                  # REST API host: modules, Wolverine, OpenIddict resource server
    ├── Wallow.AppHost/              # .NET Aspire host orchestrating the API, React apps, and infra
    ├── Wallow.MigrationService/     # Applies EF migrations for all module DbContexts
    ├── Wallow.SeederService/        # Seeds roles, scopes, admin, and OIDC clients from seed.json
    ├── Wallow.ServiceDefaults/      # Aspire defaults: telemetry, health checks, resilience
    ├── Modules/
    │   ├── Identity/                # Auth, users, organizations, RBAC
    │   ├── Storage/                 # File storage (S3-compatible)
    │   ├── Notifications/           # In-app and push notifications
    │   ├── Announcements/           # System-wide announcements
    │   ├── Inquiries/               # Inquiry and question submission
    │   ├── ApiKeys/                 # API key management
    │   └── Branding/                # Tenant branding configuration
    └── Shared/
        ├── Wallow.Shared.Contracts/                 # Cross-module integration events
        ├── Wallow.Shared.Kernel/                    # DDD primitives, multi-tenancy, JWT claim helpers
        ├── Wallow.Shared.Api/                       # Shared API utilities (Result → IActionResult, health check)
        ├── Wallow.Shared.Infrastructure/            # Settings framework and module coordination
        ├── Wallow.Shared.Infrastructure.Core/       # Persistence, caching, and messaging primitives
        ├── Wallow.Shared.Infrastructure.BackgroundJobs/  # Hangfire-backed IJobScheduler
        └── Wallow.Shared.Infrastructure.Plugins/    # Plugin loading and extension points

apps/                               # React (TanStack Start) frontends (pnpm workspace)
├── wallow-auth/                     # Auth UI (login, register, MFA)  → http://localhost:3002
├── wallow-web/                      # Dashboard and public pages       → http://localhost:3000
└── minimal-app/                     # Smallest wiring of the shared packages → http://localhost:3010

packages/                           # Shared TypeScript packages (SDK, UI, forms, auth, styles, …)

Each module follows four layers: Domain (no dependencies) → ApplicationInfrastructureAPI.

Deep dive: Architecture Assessment · Module Creation

Key Features

Feature Description
Clean Architecture Strict dependency rules per module with domain isolation
Domain-Driven Design Entities, value objects, domain events, bounded contexts
CQRS Command/query separation with Wolverine as mediator
Multi-Tenancy Schema-per-tenant data isolation, configurable resolution (header, subdomain, JWT)
Event-Driven Wolverine in-memory events between modules
Identity & RBAC OpenIddict + ASP.NET Core Identity
Real-Time Push notifications via SignalR
Observability Serilog structured logging, OpenTelemetry tracing, Grafana dashboards
Audit Trail Automatic entity change auditing via Audit.NET
Background Jobs IJobScheduler abstraction backed by Hangfire

Tech Stack

Purpose Technology
Framework .NET 10
Database PostgreSQL 18
ORM EF Core + Dapper (available for raw SQL reads)
CQRS & Messaging Wolverine (in-memory)
Caching Valkey (Redis-compatible)
Identity OpenIddict + ASP.NET Core Identity
Real-time SignalR
Validation FluentValidation
Logging & Tracing Serilog, OpenTelemetry
Testing xUnit, Testcontainers, AwesomeAssertions

Testing

The backend has 15 xUnit test assemblies under api/tests/ (unit, integration, and architecture), alongside the shared Wallow.Tests.Common helper library and the BenchmarkDotNet project, neither of which carries tests. Most pnpm workspace members add a Vitest suite — DOM specs run in a real browser project, non-DOM specs in a node project — plus per-app Playwright E2E suites.

./scripts/run-tests.sh                    # backend fast suites, with the coverage runsettings
./scripts/run-tests.sh all                # the same, plus every Category=Integration test (Docker)
pnpm check                                # frontend quality gate, including pnpm test
./scripts/e2e.sh                          # containerised backend + all three Playwright suites

A bare backend run filters out Category=Integration and says so in its own output; all (or integration for that tier alone) is what exercises the Wolverine handler-codegen guards and the Testcontainers-backed suites.

Coverage figures are produced by the run, not tracked here — ./scripts/run-tests.sh writes them with api/tests/coverage.runsettings applied.

Details: Testing Guide — backend suites, frontend Vitest, coverage, the Docker test stack, and CI · E2E Tests

Configuration

Wallow is designed to be customized without changing source code. Backend configuration flows through standard .NET mechanisms; branding is frontend-only and lives with the styles package:

Area Config Source What it controls
Branding packages/styles/branding.json App name, icon, tagline, theme colors
Database appsettings.json PostgreSQL and Valkey connection strings
Email appsettings.json SMTP host, port, TLS, sender defaults
Storage appsettings.json S3 endpoint, bucket, ClamAV virus scanning
Observability appsettings.json OpenTelemetry OTLP endpoints, service name
CORS appsettings.json Allowed origins for API requests
Environment Environment variables Override any setting with Section__Key syntax

Configuration loads in order: appsettings.jsonappsettings.{Environment}.json → environment variables → user secrets (dev only).

Full reference with examples for Docker, Kubernetes, and all module options: Configuration Guide

Local Services

Service URL
API http://localhost:5001
API Docs (Scalar) http://localhost:5001/scalar/v1
Web (TanStack) http://localhost:3000
Auth (TanStack) http://localhost:3002
Minimal app http://localhost:3010
Docs http://localhost:5004
Mailpit http://localhost:8025
GarageHQ (S3) http://localhost:3900
Grafana http://localhost:3001

Credentials and config: Configuration Guide. The application rows are duplicated in root CLAUDE.md's Local Development table — change both together.

Documentation

Guide Description
Developer Guide Day-to-day development workflow
Fork Guide Creating a new product from Wallow
Configuration Environment variables, branding, settings
Architecture Design decisions and patterns
Module Creation Adding new modules
Deployment CI/CD, Docker, and production setup
Versioning Conventional Commits and release-please
Observability Logging, tracing, and dashboards
Frontend Setup The pnpm workspace, Vite, and TanStack Start
Component Library The shared @bc-solutions-coder/ui catalog
Forms The @bc-solutions-coder/forms authoring layer
Frontend State TanStack Query, auth, and the nav store
Logging Structured logging across the browser and the app server
BFF Pattern Same-origin OIDC through the app server
TypeScript SDK @bc-solutions-coder/sdk reference

License

Apache 2.0

About

A .NET 10 modular monolith starter platform with multi-tenancy, Clean Architecture, DDD, CQRS, and Wolverine messaging

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages