omid-ahmadpour/CleanArchitecture-Template
51.0
Adequate · 21 September 2026
3k
lines of production code
C#
primary language
4
measurements over time
What this system is
This system is a .NET 10-based Clean Architecture template that provides a foundational structure for building secure, scalable web APIs. It implements a CQRS pattern with a custom dispatching layer, supporting user authentication via JWT and refresh tokens, as well as basic product management with read/write database separation and Redis caching. The framework includes standardized API response handling, centralized exception filtering, and comprehensive validation to streamline the development of domain-specific services.
How it got here
2020 — CleanArchitecture v3.6.1 foundation
10 changes.
This period focused on upgrading the template to .NET 10 and establishing the core CleanArchitecture structure, including the introduction of a dedicated API framework and a custom dispatching layer. Significant work involved implementing CQRS patterns with separate read/write database contexts, defining domain entities for products and users, and setting up infrastructure for JWT authentication and refresh token management.
2021–2026 — API layer implementation and .NET 10 migration
25 changes.
The project migrated to .NET 10 and established a minimal hosting API layer with JWT authentication, Swagger documentation, and centralized exception handling. Core domain features for product management and user authentication were implemented, including CRUD endpoints, command/query handlers, and input validation. The architecture adopted a custom dispatching framework with pipeline behaviors and split read/write database contexts to support these services.
Features
AddProduct command handler implementation
The persistence layer now includes a dedicated command handler for adding new products. This handler validates that the product name is not null and checks for duplicates before persisting the new product entity to the database, ensuring data integrity during creation.
src/Infrastructure/Persistance/CommandHandlers/Products · high confidence
Added custom exception classes for common error scenarios
The application now includes four new custom exception classes in the \CleanTemplate.Common.Exceptions\ namespace: \ExistingRecordException\, \InvalidNullInputException\, \NotFoundException\, and \ValidationException\. These exceptions provide specific error handling capabilities, with \ValidationException\ integrating with FluentValidation to expose detailed property-level error messages, while the others offer structured messaging for entity existence, input validity, and record not found scenarios.
src/Common/Exceptions · high confidence
Implemented product query handlers with caching and pagination support
The persistence layer now includes specific query handlers for retrieving product data. The GetProductById handler fetches a single product by ID, while the GetProducts handler supports paginated retrieval of product lists. Additionally, a new ReadProductFromRedis handler has been added to fetch products using a static cache manager with a 2-minute expiry, improving read performance for frequently accessed product details.
src/Infrastructure/Persistance/QueryHandlers · high confidence
Initial application dependency injection setup
A new DependencyInjection class has been added to the Application layer, providing an extension method to register application services. Currently, this method initializes the service collection but does not yet register any specific services or dependencies.
src/Core/Application · high confidence
Introduce common infrastructure for API status codes and exception handling
Added a new \CleanTemplate.Common\ library that provides foundational types for the application. This includes an \ApiResultStatusCode\ enum to standardize API response codes (e.g., Success, BadRequest, NotFound) with localized display names, and a \CleanArchAppException\ class that carries HTTP status codes, API status codes, and additional data for structured error handling. Additionally, marker interfaces (\IScopedDependency\, \ITransientDependency\, \ISingletonDependency\) are introduced to support dependency injection lifetime management, alongside a \DependencyInjection\ extension method for registering common services.
src/Common · high confidence
Introduction of centralized API exception handling filter
The API layer now includes an ApiExceptionFilter that automatically intercepts unhandled exceptions during request processing. This filter maps specific application exceptions—such as ValidationException, NotFoundException, and ExistingRecordException—to standardized HTTP responses (400, 404, or 500), ensuring consistent error formatting for clients without requiring manual try-catch blocks in individual controllers.
src/Web/Api/Filters · high confidence
Introduction of core domain entities and custom Identity models
This change introduces the foundational domain entities for the application, including a generic base entity structure (IEntity, BaseEntity) and specific models for Products and Users. It defines a custom User class extending IdentityUser\<int\> with additional profile fields (FullName, Age, Gender, IsActive) and a custom Role class extending IdentityRole\<int\> with a Description field. Additionally, a RefreshToken entity is added to support token-based authentication flows, linking users to their refresh tokens with creation, update, and expiry timestamps.
src/Core/Domain/Entities · high confidence
JWT authentication and token management infrastructure
The persistence layer now includes a new JWT service that handles user authentication by generating signed and encrypted access tokens along with refresh tokens upon successful login. This service validates access tokens to retrieve user identities and manages token expiration settings via configuration, providing the core mechanism for securing API endpoints.
src/Infrastructure/Persistance/Jwt · high confidence
New API framework result types and Swagger configuration
This change introduces new classes in the ApiFramework.Tools layer to standardize API responses and documentation. ApiResult and PagedApiResult are new IActionResult implementations that wrap data, status codes, and optional error messages, with ApiResult specifically configured to omit the 'Errors' field from JSON output when it is null or empty. Additionally, ConfigureSwaggerOptions is added to automatically generate Swagger documentation for all API versions discovered by the ApiVersionDescriptionProvider.
src/Web/ApiFramework/Tools · high confidence
New action filter for validating API request model state
A new ValidateModelStateAttribute action filter has been added to the API framework. When applied to an API endpoint, it automatically checks the incoming request's model state; if validation fails, it immediately returns a JSON response containing the specific error messages, preventing the controller action from executing.
src/Web/ApiFramework/Attributes · high confidence
New product application layer commands and queries
The application layer for products now includes new command and query definitions to support adding products, retrieving a single product by ID, fetching a paged list of products, and reading product data from Redis. These changes introduce the request/response structures (AddProductCommand, GetProductByIdQuery, GetProductsQuery, ReadProductFromRedisQuery) and their corresponding models, establishing the interface for product-related operations within the CleanTemplate architecture.
src/Core/Application/Products · high confidence
New user request models for authentication and registration
The API now includes dedicated request models to handle user authentication and account creation. A new LoginRequest model supports username, password, and refresh token inputs, while a separate RefreshTokenRequest model is available for token renewal operations. Additionally, a SingUpRequest model has been added to capture user registration details, including name, email, password, age, and gender.
src/Web/Api/Controllers/v1/Users/Requests · high confidence
New utility extensions for identity, data modeling, paging, and security
This update introduces a suite of new helper classes in the Common Utilities library to streamline common development tasks. IdentityExtensions provides convenient methods for extracting user IDs and names from ClaimsIdentity. ModelBuilderExtensions adds conventions for Entity Framework Core, including automatic pluralization of table names, setting restrictive delete behaviors for foreign keys, and registering entity configurations via reflection. PagingHelper offers an async method for paginating IQueryable results. SecurityHelper provides a utility for generating SHA-256 hashes, and StringExtensions adds helper methods for type conversion, numeric formatting, and null-checking.
src/Common/Utilities · high confidence
New v1 User API endpoints for authentication and token management
The new UserController exposes three POST endpoints for user authentication: sign-up, login, and token refresh. These endpoints accept request bodies and utilize Mapster for model mapping and a centralized Dispatcher for command handling, with Swagger documentation added for API clarity.
src/Web/Api/Controllers/v1/Users · high confidence
Product API endpoints for CRUD and caching operations
The ProductController now exposes four HTTP endpoints for managing products: adding a new product via POST, retrieving a single product by ID, fetching a paginated list of all products, and reading a product directly from Redis cache. These endpoints utilize the Mapster library for object mapping and the CleanTemplate.Dispatching mechanism to send commands and queries to the application layer, with Swagger annotations added to document the API operations.
src/Web/Api/Controllers/v1/Products · high confidence
User authentication and token management handlers implemented
The persistence layer now includes command handlers for user registration, login, and token refresh. The CreateUserCommandHandler registers new users via ASP.NET Core Identity. The LoginCommandHandler authenticates users, generates JWT access and refresh tokens, and persists the refresh token. The RefreshTokenCommandHandler validates existing tokens, issues new JWT pairs, and updates the stored refresh token, enabling seamless session renewal.
src/Infrastructure/Persistance/CommandHandlers/Users · high confidence
User authentication commands and response models added
The application layer now includes specific command and response structures for user registration, login, and token refresh. New files define CreateUserCommand for account creation, LoginCommand and LoginResponse for handling authentication and returning access/refresh tokens, and RefreshTokenCommand/RefreshTokenResponse for token renewal. These components support the underlying API endpoints for user identity management.
src/Core/Application/Users · high confidence
Behavioural changes
API layer bootstrapping with minimal hosting, JWT auth, and health checks
The \src/Web/Api\ project has been restructured to use the .NET 10 minimal hosting pattern, replacing the traditional \Startup.cs\ with a new \Program.cs\ that configures Autofac, Serilog, and the application services. This entry point wires up JWT authentication, Swagger UI with API versioning, and health checks for SQL Server and Redis. The \DependencyInjection.cs\ file centralizes service registration, including FluentValidation, PolyCache, and pipeline behaviors, while \MigrationService.cs\ ensures automatic database migrations on startup. Configuration is now managed via environment-specific \appsettings\ files, and a \Dockerfile\ has been added to support containerized deployment.
src/Web/Api · high confidence
Added EF Core entity configurations for Product, User, and Role
New Fluent API configuration classes have been introduced in the persistence layer to define database mapping rules for core domain entities. ProductConfiguration sets the table name and primary key for the Product entity. RoleConfiguration enforces that the Role name is required and limited to 50 characters. UserConfiguration enforces that the User name is required and limited to 100 characters. These configurations ensure consistent schema generation for these entities via Entity Framework Core.
src/Infrastructure/Persistance/Configuration · high confidence
Automatic service registration via Autofac dependency markers
The application now uses Autofac to automatically register services based on their inheritance from specific dependency interfaces (IScopedDependency, ITransientDependency, ISingletonDependency), reducing the need for manual registration code. This change introduces a new Autofac configuration extension that scans assemblies for types implementing these markers and registers them with the appropriate lifetime scope, streamlining the dependency injection setup.
src/Web/ApiFramework/Configuration · high confidence
CleanArchitecture-Template v3.6.1 release with .NET 10 upgrade
This release updates the CleanArchitecture-Template to version 3.6.1, upgrading the target runtime to .NET 10 with modernized configuration. The solution structure now includes a dedicated CleanTemplate.ApiFramework project for API results and Swagger filters, alongside a custom CleanTemplate.Dispatching layer replacing previous MediatR dependencies. The template supports Docker deployment, integrates Redis and SQL Server for persistence and caching, and includes comprehensive unit and integration tests using xUnit and Moq.
(repo-wide) · high confidence
Database persistence layer refactored with Identity support and read/write separation
The database context has been upgraded from a standard DbContext to IdentityDbContext, enabling built-in user and role management capabilities. The architecture now separates concerns by introducing distinct read (CleanArchReadOnlyDbContext) and write (CleanArchWriteDbContext) contexts, both inheriting from the new AppDbContext. Additionally, table names are automatically pluralized via a convention, and a parameterless constructor is available on the write context to support unit testing scenarios.
src/Infrastructure/Persistance/Db · high confidence
Database schema updated to support refresh token management
The persistence layer migrations have been updated to reflect the new refresh token architecture. The database schema now includes a dedicated 'RefreshTokens' table containing token details, creation/update timestamps, expiry time, and a foreign key linking to the user, replacing the previous approach of storing refresh tokens directly as columns on the 'AspNetUsers' table. This change ensures that token lifecycle and expiration are managed in a separate, indexed structure for better security and performance.
src/Infrastructure/Persistance/Migrations · high confidence
Enhanced Swagger UI with automatic API documentation and JWT authentication support
The Swagger UI now provides richer, auto-generated documentation for API endpoints by applying operation filters that create descriptive summaries and parameter descriptions based on controller action names (e.g., 'Retrieves a {resource} by unique id'). It also automatically injects 401 Unauthorized and 403 Forbidden responses for protected endpoints, removes redundant version parameters from the UI, and normalizes API paths to include the current version. Additionally, the UI is configured to use a JWT Bearer header, allowing users to authenticate directly from the Swagger interface.
src/Web/ApiFramework/Swagger · high confidence
Input validation added for user authentication and registration endpoints
The API now enforces strict input validation on user-facing requests. Login, registration (Sign Up), and refresh token endpoints will reject requests if required fields (such as username, password, email, or tokens) are missing or empty, ensuring data integrity before processing.
src/Web/Api/Controllers/v1/Users/Validators · high confidence
Input validation for product creation and paginated retrieval
Added request validators for the Products API to enforce data integrity on new endpoints. The AddProductRequestValidator ensures that product names are provided and prices are positive numbers, while the GetProductsRequestValidator validates that pagination parameters (page and page size) are positive integers. These changes prevent invalid data from reaching the business logic layer for both creating products and retrieving paginated lists.
src/Web/Api/Controllers/v1/Products/Validators · high confidence
Introduce generic and specialized EF Core repositories with separate read/write contexts
The persistence layer now uses a generic repository pattern implemented via Entity Framework Core, splitting data access into read-only and write operations backed by distinct DbContext instances (CleanArchReadOnlyDbContext and CleanArchWriteDbContext). This change introduces EfReadOnlyRepository for read-only queries, a base Repository class for standard CRUD operations, and specialized repositories (UserRepository, RefreshTokenRepository) that implement specific domain logic such as user authentication, password hashing, and token validation.
src/Infrastructure/Persistance/Repositories · high confidence
Introduces custom request dispatching with pipeline behavior support
The application now uses a new internal dispatching library (CleanTemplate.Dispatching) instead of MediatR. This change provides a custom IDispatcher implementation that automatically registers request handlers via dependency injection and supports an extensible pipeline of IRequestPipelineBehavior interceptors for cross-cutting concerns.
src/Dispatching · high confidence
Introduces domain repository interfaces for user and refresh token management
The core domain layer now exposes specific repository contracts for user and authentication operations. IRefreshTokenRepository defines methods to add, update, and validate refresh tokens, while IUserRepository provides specialized methods for retrieving users by credentials, updating security stamps, and tracking last login dates. These interfaces extend the generic IRepository and IReanOnlyRepository base contracts, establishing the domain-side abstraction for data access without depending on infrastructure implementations.
src/Core/Domain/IRepositories · high confidence
Introduction of v1 base controller with centralized dependency injection
A new BaseControllerV1 has been added to the v1 API controllers, providing a common base for versioned endpoints. This controller enforces authorization and model state validation, and introduces helper properties to access the service provider, a specific IDispatcher for command/query handling, and a logger, simplifying the implementation of individual API controllers.
src/Web/Api/Controllers/v1 · high confidence
New configuration models for application, caching, and authentication settings
Added new configuration classes in the Common/General module to support distinct read and write database connection strings, Redis distributed caching, and JWT/Identity authentication settings. These models (AppOptions, DistributedCacheConfig, SiteSettings, JwtSettings, IdentitySettings) provide the structured configuration schema required for the new separate read/write repository pattern and refresh token endpoint.
src/Common/General · high confidence
Request pipeline behaviors migrated to CleanTemplate.Dispatching
The request handling pipeline in src/Common/Behaviours has been updated to use the CleanTemplate.Dispatching framework instead of the previous MediatR implementation. This change introduces three new pipeline behaviors: ValidationBehavior for automatic request validation via FluentValidation, PerformanceBehaviour for logging requests that exceed 500ms, and UnhandledExceptionBehaviour for centralized error logging. These behaviors now implement the IRequestPipelineBehavior interface from the new dispatching library, ensuring consistent request processing, validation, and error handling across the application.
src/Common/Behaviours · high confidence
Separate read and write database contexts
The persistence layer now registers distinct DbContext instances for reading and writing operations. The dependency injection setup creates a read-only context (CleanArchReadOnlyDbContext) and a write context (CleanArchWriteDbContext) using separate connection strings, while also registering the standard AppDbContext for write operations. This architectural change supports the CQRS pattern by allowing the application to use different database connections or configurations for queries versus commands.
src/Infrastructure/Persistance · high confidence
Test coverage
Added end-to-end and unit tests for the API and command handlers
Added end-to-end tests for the Product API controller (GET by ID, GET all, and POST) and unit tests for the AddProduct, CreateUser, Login, and RefreshToken command handlers to verify null-input validation. Also added tests for the CleanTemplate.Dispatching dispatcher to confirm request routing, cancellation token propagation, pipeline behavior execution order, and error handling for missing or duplicate handlers, along with supporting test helpers for mocking ASP.NET Core Identity components.
test · high confidence
Dependencies
Upgrade to .NET 10 and update core dependencies
The project has been upgraded to target .NET 10.0, updating the target framework across all project files (Common, Application, Domain, Dispatching, Persistence, Api, ApiFramework, and test projects). Key NuGet packages have been updated to versions compatible with .NET 10, including Microsoft.EntityFrameworkCore (10.0.9), Microsoft.AspNetCore.Authentication.JwtBearer (10.0.9), Autofac.Extensions.DependencyInjection (10.0.0), Serilog.AspNetCore (10.0.0), and Swashbuckle.AspNetCore (10.2.1). The Elastic.Serilog.Sinks package is now at version 9.0.0, and health check libraries (AspNetCore.HealthChecks.Redis/SqlServer/UI.Client) are at version 9.0.0.
(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 62 → 51 (-10.7)
- Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 75 → 61 (-13.8)
- Architecture 83 → 83 (+0.0)
- Maturity 74 → 75 (+0.6)
- Readiness 64 → 54 (-9.4)
- Security 53 → 39 (-13.3)
Resolved (16)
- Bounded contexts not declared
- Build did not complete in the analyzer
- Coverage not measured
- 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)
- Inconsistent namespace spelling: 'Persistance' (missing 'e') vs the rest of the codebase which uses 'CleanTemplate' or 'Persistence'. This suggests a typo in the namespace name itself.
- No exposed public API
- Off-boarding risk: anonymized user #1
- Test reliability not measured — no test run produced results
- Typo in interface name: 'ReanOnly' instead of 'ReadOnly'. This creates a confusingly similar but distinct name from the standard 'IRepository' interface.
- Typo in name: 'SingUp' instead of 'SignUp'. This is inconsistent with standard 'SignUp' terminology and likely a typo in the codebase.
- Vulnerable: System.Security.Cryptography.Xml
- redundant comment (src/Infrastructure/Persistance/CommandHandlers/Users/CreateUserCommandHandler.cs)
New (77)
- CRAP 870: ApplySummariesOperationFilter.Apply (src/Web/ApiFramework/Swagger/ApplySummariesOperationFilter.cs)
- CommentedOutCode (src/Web/Api/DependencyInjection.cs)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Duplicated block (5 lines × 2) (src/Infrastructure/Persistance/CommandHandlers/Users/LoginCommandHandler.cs)
- Duplicated block (6 lines × 2) (src/Web/ApiFramework/Tools/ApiResult.cs)
- High secret: WD-SECRET-0002 (src/Web/Api/appsettings.Development.json)
- High secret: WD-SECRET-0002 (src/Web/Api/appsettings.Production.json)
- High secret: WD-SECRET-0002 (src/Web/Api/appsettings.Staging.json)
- 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)
- Inconsistent namespace for migration classes: 'Persistance' (typo) vs 'Persistence'. The class 'AppDbContextModelSnapshot' is in 'Persistance.Migrations' while 'AppDbContext' is in 'Persistence.Db'.
- Inconsistent naming for the migration service interface and implementation. One is prefixed with 'I' (standard convention) and the other is not, or they are distinct types with confusingly similar names where one might be expected to be the interface for the other.
- Inconsistent naming style for properties: 'token_type' and 'Refresh_token' use snake_case, while the rest of the codebase predominantly uses PascalCase (e.g., 'UserId', 'ExpiryTime').
- Leaked secret: signing-key (src/Web/Api/appsettings.Production.json)
- Leaked secret: signing-key (src/Web/Api/appsettings.Staging.json)
- Low coverage: src/Common/Behaviours/PerformanceBehaviour.cs (src/Common/Behaviours/PerformanceBehaviour.cs)
- …and 57 more
Changes since last survey
- 2 commits — 1 feature/other, 1 fixes
By area
- (repo) — 1 commit
- src/Infrastructure — 1 commit
Notable commits
- fix: Fix NuGet package vulnerability
- change: Merge branch 'main' of https://github.com/omid-ahmadpour/CleanArchitecture-Template
API surface
- Unchanged — 7 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
omid-ahmadpour/CleanArchitecture-Template 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 9281c8ee8ddfae5d978fc89aea27e14ee12b6fad — 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-28e75b8e3254.