Skip to content
CAI
Software that uses CAICheck a score

jeangatto/ASP.NET-Core-API-DDD-SOLID

55.2

Adequate · 21 September 2026

2.8k

lines of production code

C#

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a .NET 10-based public API that manages user authentication and geographic data for Brazil. It provides endpoints for logging in, refreshing tokens, and retrieving hierarchical location data (regions, states, and cities) via a structured application layer. The architecture leverages CQRS, dependency injection, and caching to handle user credentials and geographic lookups, supported by a SQL Server database with in-memory SQLite for testing.

How it got here

2021 — Initial domain and API implementation

33 changes.

This period focused on establishing the core domain model and public API for the SGP project, introducing entities for user authentication and Brazilian geographic hierarchy. The work involved implementing the full stack for these features, including repository patterns, application services, and API controllers, alongside comprehensive unit and integration tests.

2022–2024 — infrastructure and domain layer implementation

17 changes.

This period focused on implementing the core domain entities, repository patterns, and database mappings within the infrastructure layer. It also established shared abstractions, validation utilities, and centralized service registration to support the application's data access and business logic.

Features

Added GetByIdRequest and its validator for retrieving entities by ID

A new GetByIdRequest class and its corresponding GetByIdRequestValidator have been introduced to handle fetching entities by their unique identifier. The request class accepts both Guid and string inputs, automatically parsing the string to a Guid, and utilizes a LazyValidator for validation. The validator enforces that the Id is not null or empty, ensuring that requests contain a valid identifier before processing.

src/SGP.Application/Requests · high confidence

Added database mapping configurations for core domain entities

New Entity Framework Core mapping configurations have been added for the Cidade, Estado, Regiao, Token, and Usuario entities. These changes define how each entity is persisted to the database, including property constraints, unique indexes, and relationships (such as the one-to-many between Usuario and Token, and the ownership of Email as a value object). This establishes the database schema for these domain models.

src/SGP.Infrastructure/Data/Mappings · high confidence

Added domain entities for authentication and geographic hierarchy

New domain entities have been introduced to support user authentication and regional data management. The system now includes a Token entity to manage access and refresh tokens, including validation for expiration and revocation. A Usuario (User) entity has been added to handle user credentials, login attempts, and account locking logic. Additionally, new entities for geographic hierarchy—Regiao (Region), Estado (State), and Cidade (City)—have been created to support location-based data structures.

src/SGP.Domain/Entities · high confidence

Added domain-to-response mapping for city, state, and region entities

A new AutoMapper profile, DomainToResponseMapper, has been introduced in the Application layer to map domain entities (Cidade, Estado, Regiao) to their corresponding response DTOs (CidadeResponse, EstadoResponse, RegiaoResponse). This enables the application layer to serialize domain objects into structured response formats, supporting the CQRS pattern by providing a dedicated mapping configuration for these geographic entities.

src/SGP.Application/Mapper · high confidence

Added login and refresh token request models with validation

New request models for authentication have been introduced: LogInRequest and RefreshTokenRequest, each paired with a corresponding FluentValidation validator. LogInRequest validates email and password fields, while RefreshTokenRequest validates the token string, enabling structured input handling for these authentication flows.

src/SGP.Application/Requests/AuthenticationRequests · high confidence

Added project configuration and tooling files

Added foundational project configuration files to the repository root: a .editorconfig for consistent code formatting and .NET diagnostic rules, a .dockerignore to exclude unnecessary files from Docker builds, a Directory.Build.props to centralize build properties and analyzers, a global.json to pin the .NET SDK version, and a SGP.slnx solution file to organize the project structure. These changes standardize the development environment, enforce code quality rules, and simplify local and containerized development workflows.

(repo-wide) · high confidence

Added repository interfaces for domain entities

New repository interfaces have been introduced for Cidade, Estado, Regiao, and Usuario, each defining specific query methods for retrieving data. These interfaces extend shared abstractions (IRepository, IAsyncRepository) and establish the data access contracts for the domain layer.

src/SGP.Domain/Repositories · high confidence

Added request and validation classes for city lookup by IBGE code and state code

New request classes (ObterPorIbgeRequest, ObterTodosPorUfRequest) and their corresponding FluentValidation validators (ObterPorIbgeRequestValidator, ObterTodosPorUfRequestValidator) have been introduced in the application layer. These classes enable retrieving city data by IBGE code and by state code, with validation rules ensuring the IBGE code is a positive integer and the state code is a non-empty string of length 2.

src/SGP.Application/Requests/CidadeRequests · high confidence

Added request handler for retrieving states by region

Introduced a new request class, ObterTodosPorRegiaoRequest, and its corresponding FluentValidation validator, ObterTodosPorRegiaoRequestValidator, within the SGP.Application layer. This addition enables the application to process requests for retrieving all states associated with a specific region, enforcing a maximum length of 15 characters for the region parameter.

src/SGP.Application/Requests/EstadoRequests · high confidence

Added response models for regional data and authentication tokens

New response classes have been introduced in the Application layer to support regional data and authentication. Specifically, CidadeResponse, EstadoResponse, and RegiaoResponse now expose structured data for cities, states, and regions respectively, each implementing the IResponse interface. Additionally, TokenResponse has been added to encapsulate authentication details, including access and refresh tokens, creation and expiration timestamps, and the token's lifetime in seconds.

src/SGP.Application/Responses · high confidence

Adds Swagger configuration for API versioning

A new ConfigureSwaggerOptions class has been added to the public API's Options directory. This class implements IConfigureOptions\<SwaggerGenOptions\> to automatically register OpenAPI documentation for each API version defined by the ApiVersionDescriptionProvider. It sets the title, description, and version for each endpoint, and appends a deprecation notice for discontinued API versions.

src/SGP.PublicApi/Options · high confidence

Adds cached repository implementations for Cidade, Estado, and Regiao

New cached repository classes (CidadeCachedRepository, EstadoCachedRepository, RegiaoCachedRepository) are introduced in the SGP.Infrastructure layer. Each class implements its respective domain interface (ICidadeRepository, IEstadoRepository, IRegiaoRepository) and extends CachedRepositoryBase, applying caching via ICacheService to optimize data retrieval for city, state, and region entities.

src/SGP.Infrastructure/Data/Repositories/Cached · high confidence

Centralized app settings validation and lazy validator caching

The shared library now provides a centralized way to configure and validate application settings via the new \ConfigureServices.ConfigureAppSettings\ extension, which registers strongly-typed options with data annotation validation. Additionally, a new \LazyValidator\ utility has been introduced to cache and lazily instantiate FluentValidation validators, improving performance by avoiding repeated reflection and instantiation overhead during validation.

src/SGP.Shared · medium confidence

Centralized email validation pattern

A new static class, RegexPatterns, has been introduced to centralize regular expression patterns, starting with an email validation pattern. This change provides a single, consistent source for email format validation across the application.

src/SGP.Shared/Constants · high confidence

Initial public API launch with .NET 10 and Docker support

The public API is now available, built on .NET 10 and fully containerized via a new Dockerfile. The application startup is configured with standard ASP.NET Core middleware, including health checks, response compression, and JWT authentication. Configuration is managed through environment-specific settings files (Development, Docker, Testing, and default), and the API includes built-in profiling and Swagger UI for development and testing.

src/SGP.PublicApi · high confidence

Introduce base request/response interfaces and validation support

Added new shared message types to the SGP.Shared.Messages namespace. This includes the IRequest and IResponse marker interfaces, which serve as base contracts for API requests and responses. Additionally, a new abstract class BaseRequestWithValidation was introduced, providing a standard structure for requests that require validation, including a ValidationResult property and an IsValid flag.

src/SGP.Shared/Messages · high confidence

Introduced SGP database context and data seeding

The application now includes a new SGP database context (SgpContext) that defines entity sets for cities, states, regions, tokens, and users, while also configuring change tracking behavior and database collation. Additionally, a new data seeding mechanism (SgpContextSeed) has been added to populate the database with initial data from JSON files for regions, states, and cities.

src/SGP.Infrastructure/Data/Context · medium confidence

Introduced UnitOfWork implementation for database transaction management

Added a new UnitOfWork class in the Data layer that wraps EF Core's SaveChangesAsync to provide a unified transactional commit mechanism. The implementation includes concurrency error handling and proper disposal of the database context, exposing the IUnitOfWork interface for use across the application.

src/SGP.Infrastructure/Data · high confidence

Introduced application services for authentication, cities, states, and regions

Added new application service implementations for handling authentication logic (including login, token generation, and refresh), as well as services for retrieving data about cities, states, and regions. These services utilize AutoMapper for mapping domain entities to response models and leverage the Ardalis.Result library to standardize API responses with validation and error handling.

src/SGP.Application/Services · high confidence

Introduced base repository classes for caching and EF Core operations

Added new base classes to the common repository layer: CachedRepositoryBase for managing cache service and inner repository disposal, EfRepository implementing standard EF Core CRUD operations (Add, Update, Remove with single and range variants, plus GetByIdAsync), and RepositoryBase providing a generic EF Core repository with IDisposable support. These classes encapsulate common data access patterns and resource management for repository implementations.

src/SGP.Infrastructure/Data/Repositories/Common · high confidence

Introduced shared abstractions for core domain and infrastructure services

The \src/SGP.Shared/Abstractions\ directory now contains a new set of interfaces and base classes that define the application's core contracts. This includes \BaseEntity\ for typed primary keys, marker interfaces like \IAggregateRoot\ and \IAppService\, and service contracts for caching (\ICacheService\), date/time (\IDateTimeService\), hashing (\IHashService\), and token claims (\ITokenClaimsService\). Additionally, repository patterns (\IAsyncRepository\, \IRepository\, \IUnitOfWork\) and configuration options (\IAppOptions\) are now formally defined in this shared abstraction layer.

src/SGP.Shared/Abstractions · high confidence

Introduces standardized API response models

The public API now uses new \ApiResponse\ and \ApiResponse\<T\>\ models to standardize HTTP responses, providing static factory methods for common status codes (200, 400, 401, 403, 404, 500) and error handling. Additionally, a \SwaggerDefaultValuesFilter\ was added to automatically populate Swagger documentation with parameter descriptions and default values.

src/SGP.PublicApi/Models · high confidence

Introduces structured configuration options for authentication, caching, and database connections

The application now uses dedicated, strongly-typed configuration classes (AuthOptions, CacheOptions, ConnectionStrings, InMemoryOptions, and JwtOptions) to manage settings for authentication, distributed caching, and database connections. Each class implements IAppOptions and defines a specific configuration section path, allowing for more robust and validated access to these critical settings.

src/SGP.Shared/AppSettings · high confidence

Introduction of Email value object

A new Email value object has been added to the domain layer, encapsulating an email address with a private parameterless constructor for ORM compatibility and a normalized Address property that trims and lowercases the input.

src/SGP.Domain/ValueObjects · high confidence

New HTTP error result types for 403 and 500 status codes

The public API now includes dedicated result classes for handling specific HTTP error scenarios. A ForbiddenObjectResult has been added to represent 403 Forbidden responses, and an InternalServerErrorObjectResult has been added to represent 500 Internal Server Error responses. These classes simplify returning standard error responses from API endpoints by automatically setting the correct status code.

src/SGP.PublicApi/ObjectResults · high confidence

New application service interfaces for authentication and geographic data

The application layer now exposes new service interfaces for authentication and geographic data retrieval. IAuthenticationService defines methods for logging in and refreshing tokens. Separate interfaces (ICidadeService, IEstadoService, IRegiaoService) are introduced to handle city, state, and region data retrieval, all utilizing the Ardalis.Result library for consistent response handling.

src/SGP.Application/Interfaces · high confidence

New data access layer for geographic entities and user management

Added repository implementations for Cidade (City), Estado (State), and Regiao (Region) entities, enabling database queries for geographic data. Additionally, implemented the Usuario (User) repository with methods for retrieving users by ID, email, and update token, supporting the system's authentication and user management features.

src/SGP.Infrastructure/Data/Repositories · high confidence

New extension methods for EF Core model configuration

The SGP.Infrastructure project introduces two new static extension classes for Entity Framework Core. EntityTypeBuilderExtensions provides a helper to configure the base entity's primary key, while ModelBuilderExtensions adds a method to globally disable cascade delete behavior for foreign keys, changing it from Cascade to Restrict to prevent accidental data loss.

src/SGP.Infrastructure/Extensions · high confidence

New public API endpoints for authentication and geographic data

The public API now exposes new controllers for authentication and geographic data. The AuthController provides endpoints for user login and token refresh. New controllers for Cidades (Cities), Estados (States), and Regioes (Regions) expose endpoints to retrieve lists of cities by state code or IBGE code, states by region name, and all regions, all versioned at 1.0.

src/SGP.PublicApi/Controllers · high confidence

New service implementations for hashing, caching, and JWT claims

The application now includes new service implementations in the infrastructure layer: BCryptHashService for password hashing, DateTimeService for time abstraction, MemoryCacheService and DistributedCacheService for caching strategies, and JwtClaimService for generating access and refresh tokens. These services implement shared abstractions and integrate with ASP.NET Core's built-in caching and JWT security features.

src/SGP.Infrastructure/Services · high confidence

New shared extension methods for configuration, JSON, validation, and service provider access

The SGP.Shared library introduces a suite of extension methods to standardize common operations across the application. ConfigurationExtensions adds a generic method to bind configuration sections to strongly-typed options. JsonExtensions provides static helpers for serializing and deserializing JSON using a pre-configured Newtonsoft.Json settings object. RuleBuilderExtensions adds a FluentValidation helper to validate email addresses. ServiceProviderExtensions offers a convenience method to retrieve typed options from the service provider. TExtensions provides a utility to check if a value is the default. Additionally, a new AccessToken record is added to represent token data.

src/SGP.Shared/Extensions · high confidence

Behavioural changes

Add centralized error handling middleware

A new ErrorHandlingMiddleware has been introduced to the public API, providing a consistent way to catch unhandled exceptions across all requests. In development environments, the middleware returns the full exception details as plain text, while in other environments, it returns a standardized JSON error response with a generic message, ensuring that users receive a predictable error format regardless of the environment.

src/SGP.PublicApi/Middlewares · high confidence

Centralized service registration for AutoMapper and application services

The application now registers AutoMapper as a singleton and uses Scrutor to automatically scan and register all classes implementing IAppService as scoped services. This centralizes the dependency injection setup, ensuring that all application services are discovered and registered automatically based on their interfaces.

src/SGP.Application · medium confidence

Centralizes API configuration into dedicated extension methods

The public API's startup logic is now organized into specific extension methods for caching (supporting both in-memory and Redis distributed cache), database context (with SQL Server, retry logic, and health checks), JWT Bearer authentication, Swagger/OpenAPI generation, and HTTP result mapping. This refactoring groups related setup code into dedicated files (CacheExtensions, DbContextExtensions, JwtBearerExtensions, ResultExtensions, and SwaggerExtensions), making the API's initialization more modular and easier to maintain.

src/SGP.PublicApi/Extensions · high confidence

Introduce infrastructure service registration and repository caching

Added ConfigureServices.cs to the SGP.Infrastructure project, establishing the application's dependency injection configuration. This includes registering core services such as DateTimeService, BCryptHashService, JwtClaimService, and UnitOfWork. Additionally, it implements repository registration via assembly scanning using the Scrutor library and applies a caching decorator pattern to Cidade, Estado, and Regiao repositories, supporting both in-memory and distributed cache implementations.

src/SGP.Infrastructure · high confidence

New validation attribute for positive integer values

A new validation attribute, RequiredGreaterThanZero, has been added to the SGP.Shared.ValidationAttributes namespace. This attribute enforces that a property, field, or parameter is not null, can be parsed as an integer, and is strictly greater than zero.

src/SGP.Shared/ValidationAttributes · high confidence

Updated database migration to remove clustered index on Cidades.EstadoId

The database schema for the Cidades (Cities) table has been updated via a new migration (EF\_Update). Specifically, the clustered index on the EstadoId column was removed and replaced with a non-clustered index. This change affects how the public API's Entity Framework Core migrations are applied to the SQL Server database, altering the storage and access patterns for city records.

src/SGP.PublicApi/Migrations · high confidence

Test coverage

Added in-memory SQLite test fixture for integration tests; Added integration tests for authentication and city lookup endpoints; Added test constants for Brazil's regional, state, and city counts; Added test helper extensions for unit testing; Added unit tests for LazyValidator; Added unit tests for PublicApi result extensions; Added unit tests for Token and Usuario domain entities; Added unit tests for application services; Added unit tests for data infrastructure components; Added unit tests for email validation and JSON serialization; Added unit tests for infrastructure services; Added unit tests for the Email value object.

Dependencies

Centralized NuGet package version management and .NET 10 upgrade

The project now uses a central \Directory.Packages.props\ file to manage all NuGet package versions, enabling consistent dependency updates across the solution. Additionally, all projects have been upgraded to target .NET 10.0, and various third-party libraries (such as FluentValidation, xUnit, and Microsoft.Extensions packages) have been updated to their latest compatible versions.

(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 58 → 55 (-2.5)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 65 → 63 (-2.3)
  • Architecture 78 → 78 (+0.1)
  • Maturity 59 → 59 (+0.0)
  • Readiness 55 → 50 (-4.7)
  • Security 66 → 73 (+6.1)
  • Domain Modelling 57 → 55 (-1.7)

Resolved (25)

  • Build status unknown
  • Change coupling clique: CidadesController.cs, EstadosController.cs, RegioesController.cs (src/SGP.PublicApi/Controllers/CidadesController.cs)
  • Change coupling: AuthOptions.cs ↔ JwtOptions.cs (src/SGP.Shared/AppSettings/AuthOptions.cs)
  • 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)
  • No exposed public API
  • Secret: generic-api-key (src/SGP.PublicApi/appsettings.Development.json)
  • …and 5 more

New (49)

  • Change coupling: CidadeService.cs ↔ EstadoService.cs (src/SGP.Application/Services/CidadeService.cs)
  • CoverageExclusion (src/SGP.Application/ConfigureServices.cs)
  • CoverageExclusion (src/SGP.Infrastructure/ConfigureServices.cs)
  • CoverageExclusion (src/SGP.PublicApi/Extensions/CacheExtensions.cs)
  • CoverageExclusion (src/SGP.PublicApi/Extensions/DbContextExtensions.cs)
  • CoverageExclusion (src/SGP.PublicApi/Extensions/JwtBearerExtensions.cs)
  • CoverageExclusion (src/SGP.PublicApi/Extensions/SwaggerExtensions.cs)
  • CoverageExclusion (src/SGP.Shared/ConfigureServices.cs)
  • Documentation: no contributor guidance (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no project overview (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (13 lines × 2) (src/SGP.Application/Services/AuthenticationService.cs)
  • Helper methods for creating test fixtures or dependencies use inconsistent names and languages. Some use Portuguese verbs like 'Criar' (Create) or 'Popular' (Populate), while others use English verbs like 'Create'. Specifically, 'CriarRepositorio' vs 'CreateValidator' vs 'CreateDateTime' for similar setup actions.
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High secret: WD-SECRET-0002 (src/SGP.PublicApi/appsettings.Development.json)
  • High secret: WD-SECRET-0002 (src/SGP.PublicApi/appsettings.Docker.json)
  • High secret: WD-SECRET-0002 (src/SGP.PublicApi/appsettings.Testing.json)
  • High: security finding (details withheld)
  • …and 29 more

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

jeangatto/ASP.NET-Core-API-DDD-SOLID 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 23c4222c0ef6402521e5fcc3df6e87199bccef5e — 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.