alex289/CleanArchitecture
58.6
Adequate · 21 September 2026
4.5k
lines of production code
C#
primary language
4
measurements over time
What this system is
This system is a multi-tenant user and tenant management service built on .NET 10 with Clean Architecture. It exposes REST and gRPC APIs for creating, reading, updating, and deleting users and tenants, featuring role-based access control, soft deletes, and distributed caching. The backend supports event-driven messaging via MassTransit and RabbitMQ, with comprehensive test coverage for both unit and integration scenarios.
How it got here
2023 — Initial Clean Architecture scaffolding and core domain implementation
47 changes.
The project was initialized with a .NET 10 Clean Architecture boilerplate, establishing the foundational solution structure, Docker orchestration, and Aspire integration. Core domain entities for tenants and users were implemented with command/query patterns, event sourcing, and soft-delete support, while gRPC and REST APIs were built to expose these capabilities. Comprehensive unit and integration tests were added alongside infrastructure for authentication, caching, and background services to ensure the system's robustness.
2024 — Aspire integration and observability
4 changes.
The project adopted .NET Aspire to streamline local development orchestration and introduced centralized OpenTelemetry and health check configurations for improved observability. Concurrently, the integration test infrastructure was migrated to NUnit with automated container management, and new tests were added to verify Redis caching behavior.
Features
Add infrastructure services and database context extensions
The application now registers core infrastructure services, including an event store context, a domain notification store, and specific repositories for users and tenants. This change also introduces a utility to automatically apply pending database migrations at runtime, ensuring the database schema is up-to-date before use.
CleanArchitecture.Infrastructure/Extensions · high confidence
Add paginated, sortable, and searchable tenant listing
The application now exposes a new query endpoint for retrieving tenants that supports pagination, sorting, and text search. Users can filter results by a search term, specify sort order, and choose whether to include soft-deleted tenants (tracked via a DeletedAt timestamp). The response is returned as a paged result containing tenant view models, improving performance and usability when managing large tenant lists.
CleanArchitecture.Application/Queries/Tenants/GetAll · high confidence
Add paginated, sortable, and searchable user listing
The GetAllUsersQuery and its handler have been introduced to retrieve users with pagination, sorting, and search capabilities. Users can now specify a page and page size via PageQuery, filter results by a search term matching email, first name, or last name, and apply sorting using SortQuery. The query also supports an IncludeDeleted flag to optionally include soft-deleted users, bypassing default query filters when needed. This provides a flexible way to list users with performance optimizations like no-tracking and deferred execution.
CleanArchitecture.Application/Queries/Users/GetAll · high confidence
Add query handler for retrieving users by ID
Users can now retrieve a specific user's details by ID via a new query handler. This implementation fetches the user from the repository and returns a view model, or raises a domain notification if the user is not found.
CleanArchitecture.Application/Queries/Users/GetUserById · high confidence
Add sorting support for Users and Tenants
Users can now sort query results for Users and Tenants. This change introduces a sorting infrastructure in the Application layer, including \QueryableExtensions\ to handle multi-level ordering, specific \SortProvider\ implementations for \UserViewModel\ (sorting by email, name, role, status, etc.) and \TenantViewModel\ (sorting by id, name), and the corresponding dependency injection registrations to wire these providers into the service collection.
CleanArchitecture.Application/Extensions, CleanArchitecture.Application/SortProviders · high confidence
Add tenant retrieval by ID query
Introduces a new query and handler for retrieving a tenant by its unique identifier. This change enables users to fetch specific tenant details via the application layer, returning a view model if found or raising a notification if the tenant does not exist.
CleanArchitecture.Application/Queries/Tenants/GetTenantById · high confidence
Added centralized OpenTelemetry and health check defaults via ServiceDefaults
The new CleanArchitecture.ServiceDefaults library provides a unified entry point for configuring observability and resilience. When the ASPIRE\_ENABLED flag is set, services automatically register OpenTelemetry instrumentation for ASP.NET Core, HTTP clients, runtime metrics, and Entity Framework Core (including SQL statement tagging). It also adds HTTP request/response body enrichment for traces and configures standard health check endpoints (/health and /alive) in development environments.
CleanArchitecture.ServiceDefaults · high confidence
Added database configuration and seed data for Tenant and User entities
The application now includes Entity Framework Core configuration classes for the Tenant and User entities, defining property constraints such as required fields and maximum lengths. Additionally, initial seed data is introduced to automatically create a default 'Admin Tenant' and an administrative user account upon database initialization.
CleanArchitecture.Infrastructure/Configurations · high confidence
Added gRPC service definitions for Users and Tenants
New Protocol Buffers definitions have been added to the CleanArchitecture.Proto package to expose gRPC endpoints for retrieving users and tenants by their IDs. The TenantsApi service now includes a GetByIds RPC that accepts a list of tenant IDs and returns corresponding Tenant messages (including an optional deletedAt timestamp). Similarly, the UsersApi service provides a GetByIds RPC for fetching GrpcUser details (id, firstName, lastName, email, and optional deletedAt). These proto files establish the contract for these specific retrieval operations.
CleanArchitecture.Proto · high confidence
Added tenant view models for API data transfer
New view models have been introduced in the Application layer to handle tenant data serialization and deserialization. CreateTenantViewModel and UpdateTenantViewModel provide structured records for creating and updating tenant names, while TenantViewModel exposes tenant details including associated users, featuring a static factory method to map from the domain entity.
CleanArchitecture.Application/ViewModels/Tenants · high confidence
Added user authentication view models
Introduced new data transfer objects for user authentication flows: LoginUserViewModel, which carries email and password credentials, and ChangePasswordViewModel, which handles the current and new password values. These records provide the structured input models required for connecting authentication commands to their respective endpoints.
CleanArchitecture.Application/ViewModels/Users · high confidence
Background service to automatically deactivate inactive users
A new background service has been added to the API that periodically identifies and deactivates user accounts. The service runs daily, querying for up to 250 active users who have not logged in for the past 30 days, and updates their status to inactive. This automation helps maintain data hygiene by archiving or disabling accounts that have been dormant for a month.
CleanArchitecture.Api/BackgroundServices · high confidence
Event sourcing and in-memory bus infrastructure added
The infrastructure layer now supports event sourcing by introducing EF Core configurations for storing domain events and notifications, alongside a new in-memory message bus that persists events to a store and dispatches them via MediatR and a fanout handler. A generic UnitOfWork implementation has also been added to manage database context commits and disposal.
CleanArchitecture.Infrastructure · high confidence
Initial database infrastructure with event sourcing support
The application now includes a new database layer within the Infrastructure project, introducing three distinct Entity Framework Core DbContexts: ApplicationDbContext for managing core domain entities like Users and Tenants, EventStoreDbContext for persisting domain events, and DomainNotificationStoreDbContext for handling domain notifications. The ApplicationDbContext implements a global soft-delete mechanism that automatically filters out records where the DeletedAt timestamp is set, and enforces restrictive referential delete behavior across all relationships to prevent accidental data loss.
CleanArchitecture.Infrastructure/Database · high confidence
Initial project scaffolding with .NET 10, Docker, and Aspire support
The repository is initialized with a complete Clean Architecture boilerplate targeting .NET 10, including the core solution structure (Api, Application, Domain, Infrastructure, gRPC, and Shared layers). This release adds first-class support for containerized development and deployment via a multi-stage Dockerfile, a docker-compose configuration for local dependencies (SQL Server, Redis, RabbitMQ), and integration with .NET Aspire for service orchestration and telemetry. The project also includes a comprehensive README with setup instructions, a CHANGELOG, and an MIT license.
(repo-wide) · high confidence
Initial repository implementations for data access
Added the foundational repository layer in the Infrastructure project, introducing a generic BaseRepository that provides standard CRUD operations (add, update, remove, get by ID, and query with optional no-tracking) along with soft-delete support. Specific implementations include TenantRepository and UserRepository, with the latter adding a specialized method to retrieve users by email address, enabling the application to persist and query domain entities against the database.
CleanArchitecture.Infrastructure/Repositories · high confidence
Introduce application services for tenant and user management with caching and pagination
New application-layer services (TenantService and UserService) have been added to handle business logic for tenants and users. These services expose CRUD operations, login, and password change capabilities, supporting pagination, sorting, and search terms for list endpoints. TenantService specifically integrates distributed caching (with a 3-day sliding/30-day absolute expiration) for single-tenant lookups, while both services delegate command and query execution to a mediator handler.
CleanArchitecture.Application/Services · high confidence
Introduce event sourcing infrastructure for persisting domain events
The application now includes an event sourcing layer within the Infrastructure project to handle the persistence of domain events. This change introduces a \DomainEventStore\ that serializes and saves domain events and notifications into dedicated database contexts, distinguishing between standard domain events and domain notifications. It also adds an \EventStoreContext\ to capture user identity and correlation IDs from the HTTP context, ensuring that audit trails and event logs are properly attributed to the initiating user and request.
CleanArchitecture.Infrastructure/EventSourcing · high confidence
Introduce gRPC client for users and tenants with soft-delete support
The CleanArchitecture.gRPC module now provides a structured gRPC client to communicate with external Users and Tenants services. This includes DI registration via ServiceCollectionExtensions, context implementations (UsersContext, TenantsContext) that map proto responses to view models, and interfaces (IUsersContext, ITenantsContext) for dependency injection. A key behavioral detail is that both contexts now parse a 'DeletedAt' timestamp from the proto responses, converting empty or missing values to null, which supports soft-delete semantics in the shared view models.
CleanArchitecture.gRPC · high confidence
Introduce user view models with status and pagination support
The application now exposes structured view models for user management, including CreateUserViewModel, UpdateUserViewModel, and UserViewModel. The UserViewModel has been extended to include a Status field, allowing clients to see the current state of a user account. Additionally, generic PageQuery and PagedResult types have been added to support paginated data retrieval, enabling users to request specific pages and page sizes for list operations.
CleanArchitecture.Application/ViewModels · high confidence
Introduces command-based user and tenant management with role-based access control
The CleanArchitecture.Domain layer now implements a command-driven architecture for managing users and tenants, replacing previous direct manipulation patterns. This change introduces a suite of commands (Create, Update, Delete, Login, ChangePassword) for both Users and Tenants, each backed by FluentValidation and handled by dedicated command handlers. These handlers enforce strict role-based access control, ensuring that only Admins can create, update, or delete tenants and users, while regular users can only modify their own profiles or change their passwords. The implementation also adds JWT token generation for login, soft-delete support via timestamps on entities, and integration with MassTransit for publishing domain events (e.g., TenantCreated, UserDeleted) to external consumers.
CleanArchitecture.Domain · high confidence
Introduction of .NET Aspire for local development orchestration
The CleanArchitecture.AppHost project now utilizes .NET Aspire to manage and orchestrate local development dependencies. This change introduces a centralized host that provisions Redis (with Redis Insight), RabbitMQ (with the management plugin), and SQL Server, while configuring the CleanArchitecture.Api service to depend on and wait for these resources. It also enables OpenTelemetry (OTLP) tracing and HTTP health checks, and provides specific launch settings and configuration files to support the Aspire dashboard and resource endpoints.
CleanArchitecture.AppHost · high confidence
New service configuration extensions for RabbitMQ and API setup
The API project now includes new extension methods in CleanArchitecture.Api/Extensions to centralize service configuration. ConfigurationExtensions adds a helper to parse RabbitMQ connection details, specifically supporting Aspire integration by extracting host, port, and credentials from a connection string when the ASPIRE\_ENABLED flag is true. ServiceCollectionExtension introduces AddSwagger to configure Swagger UI with JWT bearer security definitions and sortable field support, and AddAuth to register JWT authentication with token validation parameters bound to the Auth configuration section.
CleanArchitecture.Api/Extensions · high confidence
New sorting query parsing infrastructure
The application now includes a new sorting subsystem within the ViewModels layer, introducing a \SortQuery\ class that parses the \order\_by\ query string parameter. This change adds support for multiple sorting syntaxes, including functional style (e.g., \asc(Name)\), sentence style (e.g., \Name asc\), and single-word indicators (e.g., \+Name\ or \-Name\). The implementation is supported by new \SortParameter\ and \SortOrder\ types, along with an \ISortingExpressionProvider\ interface intended to map these parsed parameters to entity expressions.
CleanArchitecture.Application/ViewModels/Sorting · high confidence
Shared domain events and tenant/user view models introduced
The CleanArchitecture.Shared project now provides a foundational eventing structure and data transfer objects for core entities. It introduces a base DomainEvent class integrated with MassTransit and MediatR, along with specific events for Tenant lifecycle changes (Created, Updated, Deleted) and User lifecycle changes (Created, Updated, Deleted, PasswordChanged). Additionally, it defines immutable record types for TenantViewModel and UserViewModel, which include a nullable DeletedAt timestamp to support soft-delete semantics.
CleanArchitecture.Shared · high confidence
Swagger documentation now lists allowed sort fields for API parameters
The API reference now automatically displays the valid sorting options for query parameters. This is achieved through new Swagger attributes and filters that inspect the application's sorting providers and append the list of allowed sort fields to the parameter description in the generated documentation, helping developers understand which values are accepted without consulting external docs.
CleanArchitecture.Api/Swagger · high confidence
gRPC API implementations for retrieving tenants and users by IDs
New gRPC service implementations have been added for the Tenants and Users domains, exposing GetByIds endpoints that accept a list of string identifiers. These services query the underlying repositories using NoTracking and IgnoreQueryFilters to retrieve records, mapping domain entities to gRPC response types (Tenant and GrpcUser) and including the DeletedAt timestamp in the response payload.
CleanArchitecture.Application/gRPC · high confidence
Behavioural changes
Database schema updates: soft-delete migration, tenant support, and domain notifications
The application's database schema has evolved through several migrations. The most recent change replaces the boolean 'Deleted' flag on Users and Tenants with a nullable 'DeletedAt' timestamp to track when records were soft-deleted. Previous migrations introduced multi-tenancy by adding a 'TenantId' foreign key to Users and creating a Tenants table, added user authentication fields (Password, Role), renamed user name columns (GivenName/Surname to FirstName/LastName), and added user status tracking (Status, LastLoggedinDate). Additionally, a new database context was introduced to store domain notifications in a 'StoredDomainNotifications' table.
CleanArchitecture.Infrastructure/Migrations · high confidence
Introduce tenant and user management APIs with authentication
The default Weather Forecast sample controller has been removed and replaced with new Tenant and User management endpoints. The TenantController exposes standard CRUD operations (list, get, create, update, delete) with support for pagination, search, and sorting. The UserController provides user lifecycle management (create, read, update, delete) along with a 'me' endpoint for the current user and a login endpoint that returns an authentication token. All new controllers inherit from a base ApiController that standardizes error handling and response formatting via domain notifications.
CleanArchitecture.Api/Controllers · high confidence
Major API overhaul: gRPC, MassTransit, and health checks
The CleanArchitecture.Api entry has been significantly expanded to support a more robust architecture. It now exposes gRPC services (UsersApi, TenantsApi) with reflection enabled in development, and integrates MassTransit with RabbitMQ for event-driven messaging (FanoutEventConsumer, TenantUpdatedEventConsumer). Health checks are now comprehensive, monitoring SQL Server, Redis, and RabbitMQ, with specific configurations for production versus development. Additionally, a new DetailedError model and a generic ResponseMessage\<T\> type have been introduced to standardize API error responses, and authentication/authorization middleware is now explicitly configured.
CleanArchitecture.Api · high confidence
Test coverage
Added HTTP helper extensions for integration tests; Added gRPC integration test fixtures for tenant and user queries; Added gRPC integration tests for tenant and user retrieval; Added integration test fixtures for authentication, tenants, and users; Added integration tests for Redis caching behavior; Added integration tests for Tenant and User controllers; Added integration tests for authentication and health checks; Added test authentication infrastructure for integration tests; Added test fixtures for Tenant and User gRPC API implementations; Added test fixtures for tenant query handlers; Added test infrastructure for command handlers and validation; Added unit test fixtures for user query handlers; Added unit tests for GetTenantsByIds gRPC endpoint; Added unit tests for infrastructure components; Added unit tests for tenant and user command handlers; Added unit tests for tenant query handlers; Added unit tests for the GetUsersByIds gRPC endpoint; Added unit tests for user query handlers; Integration test infrastructure now uses NUnit and manages SQL Server, Redis, and RabbitMQ containers; Integration test infrastructure now uses Testcontainers for Redis and RabbitMQ.
Dependencies
Upgrade to .NET 10 and Aspire 13 with comprehensive dependency updates
The project has been upgraded to target .NET 10.0 across all components, including the API, Application, Domain, Infrastructure, gRPC, and AppHost projects. The AppHost now utilizes the Aspire AppHost SDK 13.2, integrating Aspire Hosting packages for RabbitMQ, Redis, and SQL Server (version 13.5.3). Key library updates include Microsoft.EntityFrameworkCore to 10.0.11, Swashbuckle.AspNetCore to 10.2.3, and MassTransit to 9.2.1. The test infrastructure has been standardized with xUnit 2.9.3, NSubstitute 6.2.0, and Shouldly 4.3.0, while integration tests now use NUnit 4.6.1 and Testcontainers 4.14.0. Additionally, the API project now includes health checks for RabbitMQ, Redis, and SQL Server, and enables gRPC reflection.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 61 → 59 (-2.4)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 90 → 90 (-0.1)
- Architecture 92 → 92 (+0.0)
- Maturity 64 → 64 (-0.5)
- Readiness 54 → 53 (-0.8)
- Security 55 → 49 (-6.0)
- Domain Modelling 98 (new)
- Event-Driven 100 → 100 (+0.0)
Resolved (53)
- Bounded contexts not declared
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- …and 33 more
New (199)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Duplicated block (11 lines × 2) (CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs)
- Duplicated block (18 lines × 2) (CleanArchitecture.Domain/Commands/Tenants/DeleteTenant/DeleteTenantCommandHandler.cs)
- Duplicated block (23 lines × 2) (CleanArchitecture.Domain/Commands/Tenants/CreateTenant/CreateTenantCommandValidation.cs)
- Duplicated block (24–25 lines × 2) (CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommandHandler.cs)
- High IaC: WD-COMPOSE-0002 (docker-compose.yml)
- High IaC: WD-COMPOSE-0002 (docker-compose.yml)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- …and 179 more
Changes since last survey
- 4 commits — 4 feature/other, 0 fixes
By area
- (repo) — 2 commits
- .github/workflows — 1 commit
- CleanArchitecture.Api/CleanArchitecture.Api.csproj — 1 commit
Notable commits
- change: chore: Bump github/codeql-action from 4.37.3 to 4.37.9 in the dependencies group (#129)
- change: chore: Bump github/codeql-action in the dependencies group
- change: chore: Bump the dependencies group with 36 updates
- change: chore: Bump the dependencies group with 36 updates (#130)
API surface
- Unchanged — 13 HTTP endpoints
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
alex289/CleanArchitecture was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit f58e9177088b07ab2cf3fbcea81082f2d085f923 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.